[Pkg-cmake-commits] [cmake] 01/10: Imported Upstream version 3.4.0

Felix Geyer fgeyer at moszumanska.debian.org
Tue Nov 17 17:29:42 UTC 2015


This is an automated email from the git hooks/post-receive script.

fgeyer pushed a commit to branch experimental
in repository cmake.

commit 6e41954b4acd4b63ce6af12ae36d411076047930
Author: Felix Geyer <fgeyer at debian.org>
Date:   Tue Nov 17 17:22:37 2015 +0100

    Imported Upstream version 3.4.0
---
 Auxiliary/cmake-indent.vim                         |    2 +-
 Auxiliary/cmake-mode.el                            |  191 +-
 Auxiliary/cmake-syntax.vim                         |    2 +-
 CMakeCPack.cmake                                   |   67 +-
 CMakeCPackOptions.cmake.in                         |  126 +-
 CMakeLists.txt                                     |   37 +-
 CONTRIBUTING.rst                                   |    4 +-
 CTestCustom.cmake.in                               |   21 +-
 Help/command/FIND_XXX.txt                          |   68 +-
 Help/command/FIND_XXX_MAC.txt                      |   24 -
 Help/command/FIND_XXX_ROOT.txt                     |   16 +-
 Help/command/add_executable.rst                    |    2 +-
 Help/command/add_library.rst                       |    8 +
 Help/command/add_subdirectory.rst                  |   14 +-
 Help/command/add_test.rst                          |    7 +
 Help/command/aux_source_directory.rst              |    2 +-
 Help/command/build_name.rst                        |    5 +-
 Help/command/cmake_host_system_information.rst     |    6 +-
 Help/command/cmake_minimum_required.rst            |    2 +-
 Help/command/create_test_sourcelist.rst            |   18 +-
 Help/command/ctest_memcheck.rst                    |    1 +
 Help/command/ctest_read_custom_files.rst           |    3 +
 Help/command/ctest_run_script.rst                  |    6 +-
 Help/command/ctest_start.rst                       |    2 +-
 Help/command/ctest_test.rst                        |   13 +-
 Help/command/define_property.rst                   |   28 +-
 Help/command/else.rst                              |    2 +-
 Help/command/elseif.rst                            |    2 +-
 Help/command/enable_language.rst                   |    2 +-
 Help/command/enable_testing.rst                    |    8 +-
 Help/command/endforeach.rst                        |    4 +-
 Help/command/endfunction.rst                       |    2 +-
 Help/command/endif.rst                             |    2 +-
 Help/command/endmacro.rst                          |    2 +-
 Help/command/endwhile.rst                          |    2 +-
 Help/command/exec_program.rst                      |    8 +-
 Help/command/execute_process.rst                   |   14 +-
 Help/command/export.rst                            |   18 +-
 Help/command/export_library_dependencies.rst       |   12 +-
 Help/command/file.rst                              |    3 +-
 Help/command/find_file.rst                         |   29 +-
 Help/command/find_library.rst                      |   51 +-
 Help/command/find_package.rst                      |    7 +-
 Help/command/find_path.rst                         |   35 +-
 Help/command/find_program.rst                      |   22 +-
 Help/command/fltk_wrap_ui.rst                      |    2 +-
 Help/command/foreach.rst                           |    6 +-
 Help/command/get_cmake_property.rst                |    8 +-
 Help/command/get_directory_property.rst            |    6 +-
 Help/command/get_filename_component.rst            |   47 +-
 Help/command/get_source_file_property.rst          |   10 +-
 Help/command/get_target_property.rst               |    6 +-
 Help/command/get_test_property.rst                 |    8 +-
 Help/command/if.rst                                |    4 +
 Help/command/include.rst                           |   18 +-
 Help/command/include_external_msproject.rst        |    6 +-
 Help/command/include_regular_expression.rst        |    4 +-
 Help/command/install.rst                           |    8 +
 Help/command/install_files.rst                     |   18 +-
 Help/command/install_programs.rst                  |   23 +-
 Help/command/install_targets.rst                   |   12 +-
 Help/command/link_directories.rst                  |    8 +-
 Help/command/list.rst                              |   48 +-
 Help/command/load_cache.rst                        |    4 +-
 Help/command/load_command.rst                      |    6 +-
 Help/command/make_directory.rst                    |    2 +-
 Help/command/mark_as_advanced.rst                  |    8 +-
 Help/command/math.rst                              |    2 +-
 Help/command/message.rst                           |    2 +-
 Help/command/option.rst                            |    6 +-
 Help/command/qt_wrap_cpp.rst                       |    2 +-
 Help/command/qt_wrap_ui.rst                        |    6 +-
 Help/command/remove.rst                            |    8 +-
 Help/command/remove_definitions.rst                |    6 +-
 Help/command/return.rst                            |   14 +-
 Help/command/separate_arguments.rst                |    8 +-
 Help/command/set_property.rst                      |    3 +
 Help/command/set_target_properties.rst             |   92 +-
 Help/command/string.rst                            |  314 +-
 Help/command/subdirs.rst                           |   12 +-
 Help/command/try_compile.rst                       |   14 +
 Help/command/unset.rst                             |   10 +-
 Help/command/utility_source.rst                    |    4 +-
 Help/command/variable_requires.rst                 |    8 +-
 Help/command/while.rst                             |    8 +-
 Help/command/write_file.rst                        |   14 +-
 Help/manual/LINKS.txt                              |   10 +-
 Help/manual/cmake-buildsystem.7.rst                |   23 +-
 Help/manual/cmake-commands.7.rst                   |    2 +-
 Help/manual/cmake-developer.7.rst                  |    6 +-
 Help/manual/cmake-generator-expressions.7.rst      |    4 +
 Help/manual/cmake-policies.7.rst                   |    2 +
 Help/manual/cmake-properties.7.rst                 |   25 +
 Help/manual/cmake-toolchains.7.rst                 |   39 +-
 Help/manual/cmake-variables.7.rst                  |   44 +
 Help/manual/cmake.1.rst                            |   12 +-
 Help/manual/ctest.1.rst                            |   20 +
 Help/policy/CMP0064.rst                            |   17 +
 Help/policy/CMP0065.rst                            |   27 +
 Help/prop_dir/INCLUDE_REGULAR_EXPRESSION.rst       |    5 +-
 Help/prop_gbl/RULE_LAUNCH_COMPILE.rst              |   10 +-
 Help/prop_gbl/RULE_LAUNCH_CUSTOM.rst               |   10 +-
 Help/prop_gbl/RULE_LAUNCH_LINK.rst                 |   10 +-
 Help/prop_gbl/TARGET_MESSAGES.rst                  |   20 +
 Help/prop_sf/OBJECT_DEPENDS.rst                    |   13 +-
 Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst   |    8 +
 Help/prop_tgt/ANDROID_ARCH.rst                     |   17 +
 Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst       |    9 +
 Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst         |    7 +
 Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst          |   14 +
 Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst          |    8 +
 Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst  |   14 +
 Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst   |   16 +
 Help/prop_tgt/ANDROID_PROCESS_MAX.rst              |    8 +
 Help/prop_tgt/ANDROID_PROGUARD.rst                 |    9 +
 Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst     |    9 +
 Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst        |    8 +
 Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst            |    6 +
 Help/prop_tgt/ANDROID_STL_TYPE.rst                 |   15 +
 Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst  |    3 +
 Help/prop_tgt/BINARY_DIR.rst                       |    6 +
 Help/prop_tgt/CONFIG_OUTPUT_NAME.rst               |    5 +-
 Help/prop_tgt/ENABLE_EXPORTS.rst                   |    5 +-
 Help/prop_tgt/FRAMEWORK.rst                        |    4 +-
 Help/prop_tgt/FRAMEWORK_VERSION.rst                |    5 +
 Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst           |   13 +
 Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst  |    3 +
 Help/prop_tgt/LINK_SEARCH_END_STATIC.rst           |    8 +-
 Help/prop_tgt/LINK_SEARCH_START_STATIC.rst         |    7 +-
 Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst         |   40 +-
 Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst      |   26 +-
 Help/prop_tgt/NO_SONAME.rst                        |    6 +-
 Help/prop_tgt/OUTPUT_NAME.rst                      |   13 +
 Help/prop_tgt/OUTPUT_NAME_CONFIG.rst               |    3 +-
 Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst  |    3 +
 Help/prop_tgt/SOURCE_DIR.rst                       |    6 +
 Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst    |   10 +
 Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst        |   10 +
 Help/prop_tgt/VS_IOT_STARTUP_TASK.rst              |    6 +
 Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst     |   10 +
 .../VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst     |   10 +
 Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst       |   18 +
 Help/prop_tgt/XXX_OUTPUT_DIRECTORY.txt             |    7 +-
 Help/release/3.4.rst                               |  273 ++
 Help/release/index.rst                             |    1 +
 Help/variable/APPLE.rst                            |    4 +-
 Help/variable/BORLAND.rst                          |    4 +-
 Help/variable/BUILD_SHARED_LIBS.rst                |    6 +-
 Help/variable/CMAKE_ABSOLUTE_DESTINATION_FILES.rst |    4 +-
 .../CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst       |    5 +
 Help/variable/CMAKE_ANDROID_ARCH.rst               |    5 +
 Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst |    5 +
 Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst   |    5 +
 Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst    |    5 +
 Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst    |    5 +
 .../CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst      |    5 +
 .../CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst       |    5 +
 Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst        |    5 +
 Help/variable/CMAKE_ANDROID_PROGUARD.rst           |    5 +
 .../CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst         |    5 +
 Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst  |    5 +
 Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst      |    5 +
 Help/variable/CMAKE_ANDROID_STL_TYPE.rst           |    5 +
 Help/variable/CMAKE_ARGC.rst                       |    5 +-
 Help/variable/CMAKE_ARGV0.rst                      |    8 +-
 Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst       |   12 +-
 Help/variable/CMAKE_AUTORCC.rst                    |    4 +-
 Help/variable/CMAKE_AUTOUIC.rst                    |    4 +-
 Help/variable/CMAKE_BINARY_DIR.rst                 |    2 +-
 Help/variable/CMAKE_BUILD_TYPE.rst                 |   25 +-
 Help/variable/CMAKE_BUILD_WITH_INSTALL_RPATH.rst   |   10 +-
 Help/variable/CMAKE_CACHEFILE_DIR.rst              |    6 +-
 Help/variable/CMAKE_CACHE_MAJOR_VERSION.rst        |    2 +-
 Help/variable/CMAKE_CACHE_MINOR_VERSION.rst        |    2 +-
 Help/variable/CMAKE_CACHE_PATCH_VERSION.rst        |    2 +-
 Help/variable/CMAKE_CFG_INTDIR.rst                 |   21 +-
 Help/variable/CMAKE_CL_64.rst                      |    4 +-
 Help/variable/CMAKE_COLOR_MAKEFILE.rst             |    4 +-
 Help/variable/CMAKE_COMMAND.rst                    |    8 +-
 Help/variable/CMAKE_COMPILER_IS_GNULANG.rst        |    6 +-
 Help/variable/CMAKE_CONFIGURATION_TYPES.rst        |    6 +-
 Help/variable/CMAKE_CONFIG_POSTFIX.rst             |    6 +-
 Help/variable/CMAKE_CTEST_COMMAND.rst              |    8 +-
 Help/variable/CMAKE_CURRENT_BINARY_DIR.rst         |    2 +-
 Help/variable/CMAKE_CURRENT_LIST_DIR.rst           |    6 +-
 Help/variable/CMAKE_CURRENT_LIST_FILE.rst          |    2 +-
 Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst       |    4 +-
 Help/variable/CMAKE_CXX_EXTENSIONS.rst             |    2 +-
 Help/variable/CMAKE_CXX_STANDARD.rst               |    2 +-
 Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst      |    2 +-
 Help/variable/CMAKE_C_COMPILE_FEATURES.rst         |    4 +-
 Help/variable/CMAKE_C_EXTENSIONS.rst               |    2 +-
 Help/variable/CMAKE_C_STANDARD.rst                 |    2 +-
 Help/variable/CMAKE_C_STANDARD_REQUIRED.rst        |    2 +-
 Help/variable/CMAKE_DEBUG_POSTFIX.rst              |    4 +-
 Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst    |    6 +-
 .../CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst     |    9 +-
 Help/variable/CMAKE_DL_LIBS.rst                    |    6 +-
 Help/variable/CMAKE_EDIT_COMMAND.rst               |    6 +-
 Help/variable/CMAKE_ENABLE_EXPORTS.rst             |   22 +
 Help/variable/CMAKE_ERROR_DEPRECATED.rst           |    4 +-
 ...CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst |    5 +-
 Help/variable/CMAKE_EXECUTABLE_SUFFIX.rst          |    4 +-
 Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst    |    2 +-
 Help/variable/CMAKE_EXTRA_GENERATOR.rst            |    9 +-
 .../CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES.rst        |    2 +-
 Help/variable/CMAKE_FIND_APPBUNDLE.rst             |   22 +
 Help/variable/CMAKE_FIND_FRAMEWORK.rst             |   22 +
 Help/variable/CMAKE_FIND_LIBRARY_PREFIXES.rst      |    6 +-
 Help/variable/CMAKE_FIND_LIBRARY_SUFFIXES.rst      |    6 +-
 Help/variable/CMAKE_FIND_NO_INSTALL_PREFIX.rst     |    6 +-
 .../variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst |   18 +-
 Help/variable/CMAKE_FIND_ROOT_PATH.rst             |    4 +-
 Help/variable/CMAKE_Fortran_FORMAT.rst             |    6 +-
 Help/variable/CMAKE_Fortran_MODDIR_DEFAULT.rst     |    6 +-
 Help/variable/CMAKE_Fortran_MODDIR_FLAG.rst        |    2 +-
 Help/variable/CMAKE_Fortran_MODOUT_FLAG.rst        |    2 +-
 Help/variable/CMAKE_Fortran_MODULE_DIRECTORY.rst   |    2 +-
 Help/variable/CMAKE_GENERATOR.rst                  |    4 +-
 Help/variable/CMAKE_GENERATOR_PLATFORM.rst         |    4 +-
 Help/variable/CMAKE_GENERATOR_TOOLSET.rst          |    4 +-
 Help/variable/CMAKE_GNUtoMS.rst                    |    6 +-
 Help/variable/CMAKE_HOST_APPLE.rst                 |    4 +-
 Help/variable/CMAKE_HOST_SYSTEM_NAME.rst           |    2 +-
 Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst      |    4 +-
 Help/variable/CMAKE_HOST_SYSTEM_VERSION.rst        |    2 +-
 Help/variable/CMAKE_HOST_UNIX.rst                  |    4 +-
 Help/variable/CMAKE_HOST_WIN32.rst                 |    4 +-
 Help/variable/CMAKE_IMPORT_LIBRARY_PREFIX.rst      |    2 +-
 Help/variable/CMAKE_IMPORT_LIBRARY_SUFFIX.rst      |    2 +-
 Help/variable/CMAKE_INCLUDE_CURRENT_DIR.rst        |    8 +-
 .../CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.rst     |   10 +-
 Help/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE.rst |    7 +-
 .../CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE.rst   |    4 +-
 .../CMAKE_INSTALL_DEFAULT_COMPONENT_NAME.rst       |    8 +-
 Help/variable/CMAKE_INSTALL_NAME_DIR.rst           |    6 +-
 Help/variable/CMAKE_INSTALL_PREFIX.rst             |   25 +-
 Help/variable/CMAKE_INSTALL_RPATH.rst              |    2 +-
 .../variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst |    6 +-
 Help/variable/CMAKE_LANG_ARCHIVE_APPEND.rst        |    7 +-
 Help/variable/CMAKE_LANG_ARCHIVE_CREATE.rst        |    7 +-
 Help/variable/CMAKE_LANG_ARCHIVE_FINISH.rst        |    7 +-
 Help/variable/CMAKE_LANG_COMPILER.rst              |    4 +-
 .../CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst     |    6 +-
 Help/variable/CMAKE_LANG_COMPILER_ID.rst           |    1 +
 Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst     |    6 +
 Help/variable/CMAKE_LANG_COMPILER_LOADED.rst       |    4 +-
 Help/variable/CMAKE_LANG_COMPILE_OBJECT.rst        |    2 +-
 Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY.rst |    2 +-
 Help/variable/CMAKE_LANG_CREATE_SHARED_MODULE.rst  |    2 +-
 Help/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY.rst |    2 +-
 Help/variable/CMAKE_LANG_FLAGS.rst                 |    2 +-
 Help/variable/CMAKE_LANG_FLAGS_DEBUG.rst           |    4 +-
 Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL.rst      |    6 +-
 Help/variable/CMAKE_LANG_FLAGS_RELEASE.rst         |    4 +-
 Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO.rst  |    6 +-
 .../variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst |    4 +-
 .../CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst     |    6 +-
 .../CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst        |    4 +-
 .../CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst |    6 +-
 .../CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst    |    2 +-
 .../CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst       |    8 +-
 ...KE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES.rst |    2 +-
 .../CMAKE_LANG_IMPLICIT_LINK_LIBRARIES.rst         |    2 +-
 Help/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE.rst  |    8 +-
 Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst     |    4 +-
 .../CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst    |    2 +-
 Help/variable/CMAKE_LANG_OUTPUT_EXTENSION.rst      |    4 +-
 Help/variable/CMAKE_LANG_SIMULATE_ID.rst           |    4 +-
 Help/variable/CMAKE_LANG_SIMULATE_VERSION.rst      |    4 +-
 Help/variable/CMAKE_LANG_SIZEOF_DATA_PTR.rst       |    4 +-
 Help/variable/CMAKE_LIBRARY_ARCHITECTURE.rst       |    4 +-
 Help/variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX.rst |    4 +-
 Help/variable/CMAKE_LIBRARY_PATH_FLAG.rst          |    2 +-
 Help/variable/CMAKE_LINK_DEF_FILE_FLAG.rst         |    4 +-
 Help/variable/CMAKE_LINK_DEPENDS_NO_SHARED.rst     |    2 +-
 Help/variable/CMAKE_LINK_INTERFACE_LIBRARIES.rst   |    4 +-
 Help/variable/CMAKE_LINK_LIBRARY_FLAG.rst          |    2 +-
 Help/variable/CMAKE_LINK_LIBRARY_SUFFIX.rst        |    2 +-
 Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst     |   19 +
 Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst   |   20 +
 Help/variable/CMAKE_MACOSX_BUNDLE.rst              |    6 +-
 Help/variable/CMAKE_MAKE_PROGRAM.rst               |   10 +-
 Help/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG.rst |    8 +-
 Help/variable/CMAKE_MFC_FLAG.rst                   |    6 +-
 Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst   |    6 +-
 Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst |    2 +-
 Help/variable/CMAKE_NOT_USING_CONFIG_FLAGS.rst     |    4 +-
 Help/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED.rst    |    4 +-
 Help/variable/CMAKE_PARENT_LIST_FILE.rst           |    8 +-
 Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst     |   19 +-
 Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst     |    6 +-
 Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst  |    9 +-
 Help/variable/CMAKE_PROJECT_NAME.rst               |    2 +-
 Help/variable/CMAKE_ROOT.rst                       |    4 +-
 Help/variable/CMAKE_SCRIPT_MODE_FILE.rst           |    9 +-
 Help/variable/CMAKE_SHARED_LIBRARY_PREFIX.rst      |    4 +-
 Help/variable/CMAKE_SHARED_LIBRARY_SUFFIX.rst      |    4 +-
 Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst |    2 +-
 Help/variable/CMAKE_SHARED_MODULE_PREFIX.rst       |    2 +-
 Help/variable/CMAKE_SHARED_MODULE_SUFFIX.rst       |    2 +-
 Help/variable/CMAKE_SIZEOF_VOID_P.rst              |    6 +-
 .../variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.rst |   12 +-
 Help/variable/CMAKE_SKIP_INSTALL_RPATH.rst         |    2 +-
 Help/variable/CMAKE_SKIP_INSTALL_RULES.rst         |    5 +-
 Help/variable/CMAKE_SKIP_RPATH.rst                 |    4 +-
 Help/variable/CMAKE_SOURCE_DIR.rst                 |    2 +-
 Help/variable/CMAKE_STAGING_PREFIX.rst             |   11 +-
 Help/variable/CMAKE_STATIC_LIBRARY_PREFIX.rst      |    4 +-
 Help/variable/CMAKE_STATIC_LIBRARY_SUFFIX.rst      |    4 +-
 Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG.rst |    2 +-
 Help/variable/CMAKE_SYSTEM.rst                     |    2 +-
 Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst      |    7 +
 Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst      |    8 +
 Help/variable/CMAKE_SYSTEM_NAME.rst                |   20 +-
 Help/variable/CMAKE_SYSTEM_PROCESSOR.rst           |    2 +-
 Help/variable/CMAKE_SYSTEM_VERSION.rst             |   28 +-
 Help/variable/CMAKE_TOOLCHAIN_FILE.rst             |    6 +-
 Help/variable/CMAKE_TRY_COMPILE_CONFIGURATION.rst  |    7 +-
 Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE.rst   |   20 +-
 .../CMAKE_USER_MAKE_RULES_OVERRIDE_LANG.rst        |    7 +-
 Help/variable/CMAKE_USE_RELATIVE_PATHS.rst         |    9 +-
 Help/variable/CMAKE_VERBOSE_MAKEFILE.rst           |    2 +-
 .../CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst  |    8 +-
 .../CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst     |    4 +-
 Help/variable/CMAKE_VS_PLATFORM_TOOLSET.rst        |    2 +-
 .../CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst   |   11 +
 Help/variable/CMAKE_WARN_DEPRECATED.rst            |    4 +-
 .../CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst |    7 +-
 Help/variable/CMAKE_WIN32_EXECUTABLE.rst           |    6 +-
 Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst |    6 +
 .../CMAKE_XCODE_ATTRIBUTE_an-attribute.rst         |    4 +-
 Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst     |    6 +-
 Help/variable/CPACK_ABSOLUTE_DESTINATION_FILES.rst |    6 +-
 .../CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY.rst |    6 +-
 ...CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst |    9 +-
 Help/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY.rst |   11 +-
 Help/variable/CPACK_INSTALL_SCRIPT.rst             |    2 +-
 Help/variable/CPACK_PACKAGING_INSTALL_PREFIX.rst   |   12 +-
 Help/variable/CPACK_SET_DESTDIR.rst                |   31 +-
 .../CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst |    7 +-
 Help/variable/CTEST_CHANGE_ID.rst                  |    9 +
 Help/variable/CTEST_COVERAGE_COMMAND.rst           |   20 +-
 Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst    |    7 +
 Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst     |    7 +
 Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst         |    7 +
 Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst  |    7 +
 Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst   |    7 +
 ...TEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst |    8 +
 .../CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst      |    8 +
 .../CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst    |    8 +
 ...TEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst |    8 +
 Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst     |    7 +
 Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst       |    6 +
 Help/variable/CTEST_CUSTOM_POST_TEST.rst           |    6 +
 Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst        |    7 +
 Help/variable/CTEST_CUSTOM_PRE_TEST.rst            |    6 +
 Help/variable/CTEST_CUSTOM_TEST_IGNORE.rst         |    7 +
 Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst   |    7 +
 Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst       |    7 +
 Help/variable/CTEST_CUSTOM_XXX.txt                 |    2 +
 Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst        |    7 +
 Help/variable/CTEST_MEMORYCHECK_TYPE.rst           |    5 +-
 Help/variable/CTEST_TEST_LOAD.rst                  |    7 +
 Help/variable/CYGWIN.rst                           |    4 +-
 Help/variable/ENV.rst                              |    4 +-
 Help/variable/EXECUTABLE_OUTPUT_PATH.rst           |    4 +-
 Help/variable/LIBRARY_OUTPUT_PATH.rst              |    8 +-
 Help/variable/MINGW.rst                            |    4 +-
 Help/variable/MSVC.rst                             |    4 +-
 Help/variable/MSVC10.rst                           |    4 +-
 Help/variable/MSVC11.rst                           |    4 +-
 Help/variable/MSVC12.rst                           |    4 +-
 Help/variable/MSVC14.rst                           |    4 +-
 Help/variable/MSVC60.rst                           |    4 +-
 Help/variable/MSVC70.rst                           |    4 +-
 Help/variable/MSVC71.rst                           |    4 +-
 Help/variable/MSVC80.rst                           |    4 +-
 Help/variable/MSVC90.rst                           |    4 +-
 Help/variable/MSVC_IDE.rst                         |    4 +-
 Help/variable/UNIX.rst                             |    6 +-
 Help/variable/WIN32.rst                            |    4 +-
 Help/variable/XCODE_VERSION.rst                    |    4 +-
 .../BasicConfigVersion-AnyNewerVersion.cmake.in    |    8 +-
 Modules/BasicConfigVersion-ExactVersion.cmake.in   |   10 +-
 .../BasicConfigVersion-SameMajorVersion.cmake.in   |   10 +-
 Modules/CMakeASMInformation.cmake                  |    2 +-
 Modules/CMakeASM_MASMInformation.cmake             |    2 +-
 Modules/CMakeCCompiler.cmake.in                    |   10 +-
 Modules/CMakeCCompilerId.c.in                      |   11 +
 Modules/CMakeCInformation.cmake                    |    8 +-
 Modules/CMakeCXXCompiler.cmake.in                  |   10 +-
 Modules/CMakeCXXCompilerId.cpp.in                  |   10 +
 Modules/CMakeCXXInformation.cmake                  |    8 +-
 Modules/CMakeClDeps.cmake                          |   34 -
 Modules/CMakeDetermineCCompiler.cmake              |   12 +-
 Modules/CMakeDetermineCXXCompiler.cmake            |   12 +-
 Modules/CMakeDetermineCompilerId.cmake             |  134 +-
 Modules/CMakeDetermineFortranCompiler.cmake        |   16 +
 Modules/CMakeDetermineSwiftCompiler.cmake          |   53 +
 Modules/CMakeDetermineSystem.cmake                 |    4 +-
 Modules/CMakeExpandImportedTargets.cmake           |   16 +-
 ...atorDetermineCompilerMacrosAndIncludeDirs.cmake |    4 +
 Modules/CMakeFortranCompiler.cmake.in              |    1 +
 Modules/CMakeFortranCompilerId.F.in                |    4 +-
 Modules/CMakeFortranInformation.cmake              |    8 +-
 Modules/CMakeGenericSystem.cmake                   |    5 +-
 Modules/CMakeParseImplicitLinkInfo.cmake           |    2 +-
 Modules/CMakeRCInformation.cmake                   |    2 +-
 Modules/CMakeSwiftCompiler.cmake.in                |    5 +
 Modules/CMakeSwiftInformation.cmake                |   41 +
 Modules/CMakeTestSwiftCompiler.cmake               |   65 +
 Modules/CPack.cmake                                |  133 +-
 Modules/CPackComponent.cmake                       |    4 +-
 Modules/CPackDeb.cmake                             |  131 +-
 Modules/CPackNSIS.cmake                            |    2 +-
 Modules/CPackRPM.cmake                             |   77 +-
 Modules/CPackWIX.cmake                             |    4 +-
 Modules/CTestCoverageCollectGCOV.cmake             |    2 +-
 Modules/CheckForPthreads.c                         |    2 +-
 Modules/CheckFunctionExists.c                      |    3 +
 Modules/CheckFunctionExists.cmake                  |   14 +-
 Modules/CheckLibraryExists.cmake                   |   13 +-
 Modules/CheckSymbolExists.cmake                    |   10 +-
 Modules/Compiler/AppleClang-C.cmake                |    7 +-
 Modules/Compiler/AppleClang-CXX.cmake              |   13 +-
 Modules/Compiler/CCur-Fortran.cmake                |    1 +
 Modules/Compiler/Clang-C.cmake                     |   11 +-
 Modules/Compiler/Clang-CXX.cmake                   |    9 +-
 Modules/Compiler/Cray-DetermineCompiler.cmake      |    2 +-
 Modules/Compiler/GNU-C.cmake                       |   16 +-
 Modules/Compiler/GNU-CXX.cmake                     |    7 +-
 Modules/Compiler/GNU-DetermineCompiler.cmake       |    4 +-
 Modules/Compiler/GNU.cmake                         |    4 +-
 Modules/Compiler/HP-C.cmake                        |    4 +-
 Modules/Compiler/HP-CXX.cmake                      |    4 +-
 Modules/Compiler/HP-Fortran.cmake                  |    4 +-
 Modules/Compiler/IAR-ASM.cmake                     |    2 +-
 Modules/Compiler/IAR-C.cmake                       |    6 +-
 Modules/Compiler/IAR-CXX.cmake                     |    6 +-
 Modules/Compiler/IAR.cmake                         |    4 +-
 Modules/Compiler/Intel-C.cmake                     |    4 +-
 Modules/Compiler/Intel-CXX.cmake                   |    4 +-
 Modules/Compiler/Intel-Fortran.cmake               |    4 +-
 Modules/Compiler/PGI.cmake                         |    4 +-
 Modules/Compiler/QCC-CXX.cmake                     |    2 +-
 Modules/Compiler/SunPro-C.cmake                    |    4 +-
 Modules/Compiler/SunPro-CXX.cmake                  |   13 +-
 Modules/Compiler/SunPro-Fortran.cmake              |    4 +-
 Modules/Compiler/TI-ASM.cmake                      |    2 +-
 Modules/Compiler/TI-C.cmake                        |    6 +-
 Modules/Compiler/TI-CXX.cmake                      |    6 +-
 Modules/Compiler/XL-ASM.cmake                      |    3 +-
 Modules/Compiler/XL-C.cmake                        |    3 +-
 Modules/Compiler/XL-CXX.cmake                      |    2 +-
 Modules/Compiler/XL.cmake                          |    4 +-
 Modules/CompilerId/VS-10.vcxproj.in                |    1 +
 Modules/CompilerId/main.swift.in                   |    1 +
 Modules/DartConfiguration.tcl.in                   |    5 +
 Modules/ExternalProject.cmake                      |  120 +-
 Modules/FindBISON.cmake                            |  155 +-
 Modules/FindBZip2.cmake                            |    6 +-
 Modules/FindBoost.cmake                            |    6 +-
 Modules/FindCUDA.cmake                             |   37 +-
 Modules/FindHDF5.cmake                             |   34 +-
 Modules/FindIce.cmake                              |  134 +-
 Modules/FindJNI.cmake                              |   14 +-
 Modules/FindJava.cmake                             |   94 +-
 Modules/FindKDE4.cmake                             |    2 +-
 Modules/FindMPI.cmake                              |    8 +-
 Modules/FindMatlab.cmake                           |    1 +
 Modules/FindOpenSSL.cmake                          |  167 +-
 Modules/FindPackageHandleStandardArgs.cmake        |    2 +-
 Modules/FindPkgConfig.cmake                        |   42 +-
 Modules/FindPostgreSQL.cmake                       |    2 +-
 Modules/FindProtobuf.cmake                         |   84 +-
 Modules/FindPythonInterp.cmake                     |    2 +-
 Modules/FindPythonLibs.cmake                       |  121 +-
 Modules/FindTIFF.cmake                             |   14 +-
 Modules/FindThreads.cmake                          |   27 +-
 Modules/FindXercesC.cmake                          |   16 +-
 Modules/FindZLIB.cmake                             |   45 +-
 Modules/FindwxWidgets.cmake                        |   43 +-
 Modules/GNUInstallDirs.cmake                       |  130 +-
 Modules/GenerateExportHeader.cmake                 |    2 +-
 Modules/GetPrerequisites.cmake                     |   38 +
 Modules/Internal/FeatureTesting.cmake              |    2 +-
 Modules/Platform/ARTOS-GNU-C.cmake                 |    9 +
 Modules/Platform/ARTOS.cmake                       |   17 +
 Modules/Platform/BlueGeneQ-base.cmake              |    4 +-
 Modules/Platform/CYGWIN-windres.cmake              |    2 +-
 Modules/Platform/Darwin-Initialize.cmake           |    4 +
 Modules/Platform/Darwin-NAG-Fortran.cmake          |    2 +-
 Modules/Platform/Darwin.cmake                      |    2 +-
 Modules/Platform/Euros.cmake                       |   19 +
 Modules/Platform/GHS-MULTI-Initialize.cmake        |   36 +-
 Modules/Platform/Generic-SDCC-C.cmake              |    2 +-
 Modules/Platform/HP-UX-HP-C.cmake                  |    6 +-
 Modules/Platform/HP-UX-HP-CXX.cmake                |    4 +-
 Modules/Platform/HP-UX-HP-Fortran.cmake            |    4 +-
 Modules/Platform/HP-UX.cmake                       |   25 +-
 Modules/Platform/IRIX64.cmake                      |    8 +-
 Modules/Platform/Linux-CCur-Fortran.cmake          |    1 +
 Modules/Platform/Linux-GNU-Fortran.cmake           |    1 +
 Modules/Platform/SunOS.cmake                       |    8 -
 Modules/Platform/Windows-Embarcadero.cmake         |   10 +-
 Modules/Platform/Windows-GNU.cmake                 |    2 +-
 Modules/Platform/Windows-MSVC.cmake                |   17 +-
 Modules/Platform/Windows-wcl386.cmake              |    8 +-
 Modules/Platform/Windows-windres.cmake             |    2 +-
 Modules/ProcessorCount.cmake                       |   29 +-
 Modules/UseJava.cmake                              |  245 +-
 Modules/UseSWIG.cmake                              |   10 +-
 Modules/UseVTK40.cmake                             |   29 -
 Modules/UseVTKBuildSettings40.cmake                |   38 -
 Modules/UseVTKConfig40.cmake                       |  409 --
 Modules/readme.txt                                 |    2 +-
 README.rst                                         |   14 +-
 Source/CMakeLists.txt                              |   54 +-
 Source/CMakeVersion.cmake                          |    4 +-
 Source/CPack/IFW/cmCPackIFWGenerator.cxx           |    2 +-
 Source/CPack/OSXScriptLauncher.cxx                 |   11 +-
 Source/CPack/WiX/cmCPackWIXGenerator.cxx           |    4 +-
 Source/CPack/WiX/cmWIXAccessControlList.cxx        |    2 +-
 Source/CPack/WiX/cmWIXPatch.cxx                    |    2 +-
 Source/CPack/WiX/cmWIXSourceWriter.cxx             |    2 +-
 Source/CPack/cmCPackArchiveGenerator.cxx           |    4 +-
 Source/CPack/cmCPackDebGenerator.cxx               |  320 +-
 Source/CPack/cmCPackGenerator.cxx                  |   16 +-
 Source/CPack/cmCPackNSISGenerator.cxx              |    6 +-
 Source/CPack/cmCPackSTGZGenerator.cxx              |    3 +-
 Source/CPack/cpack.cxx                             |   10 +-
 Source/CTest/cmCTestBuildHandler.cxx               |   10 +-
 Source/CTest/cmCTestCoverageHandler.cxx            |   37 +-
 Source/CTest/cmCTestCoverageHandler.h              |    2 +-
 Source/CTest/cmCTestCurl.cxx                       |    6 +
 Source/CTest/cmCTestGIT.cxx                        |    1 -
 Source/CTest/cmCTestGenericHandler.cxx             |    2 +
 Source/CTest/cmCTestGenericHandler.h               |    3 +
 Source/CTest/cmCTestHandlerCommand.cxx             |    6 +
 Source/CTest/cmCTestLaunch.cxx                     |    5 +-
 Source/CTest/cmCTestMultiProcessHandler.cxx        |  158 +-
 Source/CTest/cmCTestMultiProcessHandler.h          |    4 +
 Source/CTest/cmCTestP4.cxx                         |    1 -
 Source/CTest/cmCTestRunTest.cxx                    |    3 +-
 Source/CTest/cmCTestScriptHandler.cxx              |   46 +-
 Source/CTest/cmCTestSubmitHandler.cxx              |    8 +
 Source/CTest/cmCTestTestCommand.cxx                |   33 +
 Source/CTest/cmCTestTestCommand.h                  |    1 +
 Source/CTest/cmCTestTestHandler.cxx                |   34 +-
 Source/CTest/cmCTestTestHandler.h                  |    5 +
 Source/CTest/cmCTestUpdateHandler.cxx              |    4 +-
 Source/CTest/cmParseJacocoCoverage.cxx             |  139 +-
 Source/CTest/cmProcess.cxx                         |   19 +-
 Source/CTest/cmProcess.h                           |    7 +-
 Source/Checks/cm_c11_thread_local.c                |    2 +
 Source/Checks/cm_c11_thread_local.cmake            |   33 +
 Source/CursesDialog/CMakeLists.txt                 |    3 +-
 Source/CursesDialog/cmCursesLongMessageForm.cxx    |    8 +-
 Source/CursesDialog/cmCursesMainForm.cxx           |   17 +-
 Source/CursesDialog/cmCursesStringWidget.cxx       |   25 +-
 Source/CursesDialog/cmCursesWidget.cxx             |    2 +-
 Source/QtDialog/CMakeLists.txt                     |   83 +-
 Source/QtDialog/Info.plist.in                      |    2 +
 Source/QtIFW/CMake.Dialogs.QtGUI.qs                |   21 +
 Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in  |   21 +
 Source/QtIFW/CMake.qs.in                           |   22 +
 Source/QtIFW/installscript.qs.in                   |    8 +-
 Source/bindexplib.cxx                              |  439 ++
 Source/cmAlgorithms.h                              |   84 +-
 Source/cmArchiveWrite.cxx                          |   85 +-
 Source/cmArchiveWrite.h                            |   96 +-
 Source/cmBuildNameCommand.h                        |    1 -
 Source/cmCMakeHostSystemInformationCommand.cxx     |    4 +-
 Source/cmCMakePolicyCommand.cxx                    |   16 +
 Source/cmCPackPropertiesGenerator.cxx              |   16 +-
 Source/cmCPackPropertiesGenerator.h                |    6 +-
 Source/cmCPluginAPI.cxx                            |   22 +-
 Source/cmCTest.cxx                                 |  109 +-
 Source/cmCTest.h                                   |    6 +
 Source/cmCacheManager.cxx                          |   11 +-
 Source/cmCallVisualStudioMacro.cxx                 |    2 +-
 Source/cmCommand.h                                 |    9 -
 Source/cmCommandArgumentParserHelper.cxx           |    7 +-
 Source/cmCommandArgumentParserHelper.h             |    8 +-
 Source/cmCommonTargetGenerator.cxx                 |  431 ++
 Source/cmCommonTargetGenerator.h                   |   96 +
 Source/cmComputeComponentGraph.h                   |    4 +-
 Source/cmComputeLinkDepends.cxx                    |   37 +-
 Source/cmComputeLinkDepends.h                      |   26 +-
 Source/cmComputeLinkInformation.cxx                |   94 +-
 Source/cmComputeLinkInformation.h                  |   43 +-
 Source/cmComputeTargetDepends.cxx                  |   84 +-
 Source/cmComputeTargetDepends.h                    |   16 +-
 Source/cmConditionEvaluator.cxx                    |   82 +-
 Source/cmConditionEvaluator.h                      |   10 +-
 Source/cmCoreTryCompile.cxx                        |   34 +-
 Source/cmCryptoHash.cxx                            |    2 +-
 Source/cmCurl.cxx                                  |    2 +-
 Source/cmCustomCommand.cxx                         |   55 +-
 Source/cmCustomCommand.h                           |   10 +-
 Source/cmCustomCommandGenerator.cxx                |   28 +-
 Source/cmCustomCommandGenerator.h                  |    4 +-
 Source/cmDefinitions.cxx                           |   14 +-
 Source/cmDefinitions.h                             |   17 +-
 Source/cmDependsFortran.cxx                        |  525 +--
 Source/cmDependsFortran.h                          |   19 +-
 Source/cmDependsFortranLexer.cxx                   | 2414 -----------
 Source/cmDependsFortranLexer.h                     |  348 --
 Source/cmDependsFortranLexer.in.l                  |  190 -
 Source/cmDependsFortranParser.cxx                  | 2088 ----------
 Source/cmDependsFortranParser.h                    |   96 -
 Source/cmDependsFortranParser.y                    |  282 --
 Source/cmDependsFortranParserTokens.h              |  122 -
 Source/cmDocumentation.h                           |    1 -
 Source/cmExecProgramCommand.cxx                    |    6 +-
 Source/cmExecProgramCommand.h                      |    6 -
 Source/cmExportBuildFileGenerator.cxx              |   47 +-
 Source/cmExportBuildFileGenerator.h                |    7 +-
 Source/cmExportCommand.cxx                         |    6 +
 Source/cmExportFileGenerator.cxx                   |   64 +-
 Source/cmExportFileGenerator.h                     |   12 +-
 Source/cmExportInstallFileGenerator.cxx            |   22 +-
 Source/cmExportInstallFileGenerator.h              |    3 +-
 Source/cmExportLibraryDependenciesCommand.cxx      |    8 +-
 Source/cmExportLibraryDependenciesCommand.h        |    1 -
 Source/cmExportTryCompileFileGenerator.cxx         |   14 +-
 Source/cmExportTryCompileFileGenerator.h           |    8 +-
 Source/cmExtraCodeBlocksGenerator.cxx              |   30 +-
 Source/cmExtraCodeBlocksGenerator.h                |    5 +-
 Source/cmExtraCodeLiteGenerator.cxx                |   18 -
 Source/cmExtraEclipseCDT4Generator.cxx             |    3 +-
 Source/cmFileCommand.cxx                           |   31 +-
 Source/cmFindBase.cxx                              |    4 +-
 Source/cmFindLibraryCommand.cxx                    |   12 +-
 Source/cmFindPackageCommand.cxx                    |    2 +-
 Source/cmFindProgramCommand.cxx                    |  166 +-
 Source/cmFindProgramCommand.h                      |   10 +-
 Source/cmFortranLexer.cxx                          | 2413 +++++++++++
 Source/cmFortranLexer.h                            |  348 ++
 Source/cmFortranLexer.in.l                         |  190 +
 Source/cmFortranParser.cxx                         | 1895 +++++++++
 Source/cmFortranParser.h                           |  175 +
 Source/cmFortranParser.y                           |  279 ++
 Source/cmFortranParserImpl.cxx                     |  408 ++
 Source/cmFortranParserTokens.h                     |  129 +
 Source/cmFunctionCommand.cxx                       |   34 +-
 Source/cmGeneratedFileStream.h                     |    4 +-
 Source/cmGeneratorExpression.cxx                   |    6 +-
 Source/cmGeneratorExpression.h                     |    5 +-
 Source/cmGeneratorExpressionDAGChecker.cxx         |    2 +-
 Source/cmGeneratorExpressionEvaluationFile.cxx     |   42 +-
 Source/cmGeneratorExpressionEvaluationFile.h       |   15 +-
 Source/cmGeneratorExpressionNode.cxx               |  110 +-
 Source/cmGeneratorTarget.cxx                       | 4240 ++++++++++++++++++--
 Source/cmGeneratorTarget.h                         |  311 +-
 Source/cmGetCMakePropertyCommand.cxx               |   19 +-
 Source/cmGetDirectoryPropertyCommand.cxx           |   43 +-
 Source/cmGetDirectoryPropertyCommand.h             |    5 +-
 Source/cmGetFilenameComponentCommand.cxx           |   24 +-
 Source/cmGetPropertyCommand.cxx                    |   31 +-
 Source/cmGetSourceFilePropertyCommand.cxx          |    6 +-
 Source/cmGetTargetPropertyCommand.cxx              |    6 +-
 Source/cmGetTestPropertyCommand.cxx                |    6 +-
 Source/cmGhsMultiTargetGenerator.cxx               |   57 +-
 Source/cmGhsMultiTargetGenerator.h                 |    3 +-
 Source/cmGlobalBorlandMakefileGenerator.cxx        |    4 +-
 Source/cmGlobalBorlandMakefileGenerator.h          |    3 +-
 Source/cmGlobalCommonGenerator.cxx                 |   21 +
 Source/cmGlobalCommonGenerator.h                   |   27 +
 Source/cmGlobalGenerator.cxx                       |  592 +--
 Source/cmGlobalGenerator.h                         |  119 +-
 Source/cmGlobalGhsMultiGenerator.cxx               |    5 +-
 Source/cmGlobalGhsMultiGenerator.h                 |    3 +-
 Source/cmGlobalJOMMakefileGenerator.cxx            |   28 +-
 Source/cmGlobalJOMMakefileGenerator.h              |    3 +
 Source/cmGlobalKdevelopGenerator.cxx               |    8 +-
 Source/cmGlobalMSYSMakefileGenerator.cxx           |    6 +-
 Source/cmGlobalNMakeMakefileGenerator.cxx          |   28 +-
 Source/cmGlobalNMakeMakefileGenerator.h            |    3 +
 Source/cmGlobalNinjaGenerator.cxx                  |   95 +-
 Source/cmGlobalNinjaGenerator.h                    |   39 +-
 Source/cmGlobalUnixMakefileGenerator3.cxx          |  165 +-
 Source/cmGlobalUnixMakefileGenerator3.h            |   19 +-
 Source/cmGlobalVisualStudio10Generator.cxx         |   37 +-
 Source/cmGlobalVisualStudio10Generator.h           |   11 +-
 Source/cmGlobalVisualStudio11Generator.h           |    5 +-
 Source/cmGlobalVisualStudio12Generator.h           |    5 +-
 Source/cmGlobalVisualStudio14Generator.cxx         |  165 +
 Source/cmGlobalVisualStudio14Generator.h           |   16 +
 Source/cmGlobalVisualStudio6Generator.cxx          |   11 +-
 Source/cmGlobalVisualStudio6Generator.h            |    5 +-
 Source/cmGlobalVisualStudio71Generator.cxx         |    6 +-
 Source/cmGlobalVisualStudio7Generator.cxx          |   94 +-
 Source/cmGlobalVisualStudio7Generator.h            |    8 +-
 Source/cmGlobalVisualStudio8Generator.cxx          |   28 +-
 Source/cmGlobalVisualStudio8Generator.h            |    2 +-
 Source/cmGlobalVisualStudioGenerator.cxx           |  156 +-
 Source/cmGlobalVisualStudioGenerator.h             |   21 +-
 Source/cmGlobalXCodeGenerator.cxx                  |  127 +-
 Source/cmGlobalXCodeGenerator.h                    |    4 +-
 Source/cmGraphVizWriter.cxx                        |    7 +-
 Source/cmGraphVizWriter.h                          |   15 +-
 Source/cmIfCommand.cxx                             |   29 +-
 Source/cmIncludeCommand.cxx                        |    1 +
 Source/cmInstallCommand.cxx                        |    8 +-
 Source/cmInstallDirectoryGenerator.cxx             |   47 +-
 Source/cmInstallDirectoryGenerator.h               |   11 +
 Source/cmInstallExportGenerator.cxx                |   13 +-
 Source/cmInstallExportGenerator.h                  |    8 +-
 Source/cmInstallFilesCommand.cxx                   |    2 +-
 Source/cmInstallFilesCommand.h                     |    6 -
 Source/cmInstallFilesGenerator.cxx                 |   46 +-
 Source/cmInstallFilesGenerator.h                   |   17 +-
 Source/cmInstallGenerator.h                        |    2 +
 Source/cmInstallProgramsCommand.cxx                |    2 +-
 Source/cmInstallProgramsCommand.h                  |    6 -
 Source/cmInstallTargetGenerator.cxx                |   88 +-
 Source/cmInstallTargetGenerator.h                  |   20 +-
 Source/cmInstallTargetsCommand.h                   |    6 -
 Source/cmInstalledFile.cxx                         |    4 +-
 Source/cmLinkDirectoriesCommand.cxx                |    2 +-
 Source/cmLinkItem.h                                |  121 +
 Source/cmLinkLibrariesCommand.h                    |    6 -
 Source/cmLinkedTree.h                              |  195 +
 Source/cmListCommand.cxx                           |   12 +-
 Source/cmListFileCache.cxx                         |   60 +-
 Source/cmListFileCache.h                           |   53 +-
 Source/cmLoadCommandCommand.h                      |    1 -
 Source/cmLocalCommonGenerator.cxx                  |   39 +
 Source/cmLocalCommonGenerator.h                    |   37 +
 Source/cmLocalGenerator.cxx                        | 1021 +----
 Source/cmLocalGenerator.h                          |  155 +-
 Source/cmLocalGhsMultiGenerator.cxx                |    7 +-
 Source/cmLocalGhsMultiGenerator.h                  |    3 +-
 Source/cmLocalNinjaGenerator.cxx                   |   88 +-
 Source/cmLocalNinjaGenerator.h                     |   30 +-
 Source/cmLocalUnixMakefileGenerator3.cxx           |   93 +-
 Source/cmLocalUnixMakefileGenerator3.h             |   43 +-
 Source/cmLocalVisualStudio10Generator.cxx          |   11 +-
 Source/cmLocalVisualStudio10Generator.h            |    4 +-
 Source/cmLocalVisualStudio6Generator.cxx           |  159 +-
 Source/cmLocalVisualStudio6Generator.h             |    5 +-
 Source/cmLocalVisualStudio7Generator.cxx           |  158 +-
 Source/cmLocalVisualStudio7Generator.h             |    4 +-
 Source/cmLocalVisualStudioGenerator.cxx            |   10 +-
 Source/cmLocalVisualStudioGenerator.h              |    4 +-
 Source/cmLocalXCodeGenerator.cxx                   |    5 +-
 Source/cmLocalXCodeGenerator.h                     |    4 +-
 Source/cmMacroCommand.cxx                          |   30 +-
 Source/cmMakeDepend.cxx                            |    2 +-
 Source/cmMakeDirectoryCommand.h                    |    6 -
 Source/cmMakefile.cxx                              | 1391 +++----
 Source/cmMakefile.h                                |  278 +-
 Source/cmMakefileExecutableTargetGenerator.cxx     |   16 +-
 Source/cmMakefileLibraryTargetGenerator.cxx        |   83 +-
 Source/cmMakefileTargetGenerator.cxx               |  451 +--
 Source/cmMakefileTargetGenerator.h                 |   54 +-
 Source/cmMakefileUtilityTargetGenerator.cxx        |    2 +-
 Source/cmMessageCommand.cxx                        |    2 +-
 Source/cmNinjaNormalTargetGenerator.cxx            |   95 +-
 Source/cmNinjaTargetGenerator.cxx                  |  349 +-
 Source/cmNinjaTargetGenerator.h                    |   45 +-
 Source/cmNinjaUtilityTargetGenerator.cxx           |    6 +-
 Source/cmOSXBundleGenerator.cxx                    |   16 +-
 Source/cmOrderDirectories.cxx                      |    8 +-
 Source/cmOrderDirectories.h                        |   11 +-
 Source/cmOutputConverter.cxx                       | 1065 +++++
 Source/cmOutputConverter.h                         |  183 +
 Source/cmOutputRequiredFilesCommand.h              |    1 -
 Source/cmPolicies.cxx                              |   47 +-
 Source/cmPolicies.h                                |   21 +-
 Source/cmProcessTools.cxx                          |    2 +-
 Source/cmProcessTools.h                            |    6 +-
 Source/cmProjectCommand.cxx                        |    5 +-
 Source/cmProperty.cxx                              |    7 +-
 Source/cmProperty.h                                |    6 +-
 Source/cmPropertyDefinitionMap.cxx                 |    8 +-
 Source/cmPropertyDefinitionMap.h                   |    4 +-
 Source/cmPropertyMap.cxx                           |   29 +-
 Source/cmPropertyMap.h                             |   18 +-
 Source/cmQtAutoGeneratorInitializer.cxx            | 1074 +++++
 Source/cmQtAutoGeneratorInitializer.h              |   67 +
 Source/cmQtAutoGenerators.cxx                      | 1068 +----
 Source/cmQtAutoGenerators.h                        |   31 +-
 Source/cmRemoveCommand.h                           |    6 -
 Source/cmScriptGenerator.h                         |    3 -
 Source/cmSetCommand.cxx                            |    6 +-
 Source/cmSetPropertyCommand.cxx                    |   10 +-
 Source/cmSetTestsPropertiesCommand.cxx             |    6 +-
 Source/cmSourceFile.cxx                            |   19 +-
 Source/cmSourceFile.h                              |    4 +-
 Source/cmStandardIncludes.h                        |    8 -
 Source/cmState.cxx                                 | 1168 +++++-
 Source/cmState.h                                   |  206 +-
 Source/cmStringCommand.cxx                         |   42 +-
 Source/cmStringCommand.h                           |    1 +
 Source/cmSubdirCommand.h                           |    6 -
 Source/cmSubdirDependsCommand.h                    |    1 -
 Source/cmSystemTools.cxx                           |  196 +-
 Source/cmSystemTools.h                             |   14 +-
 Source/cmTarget.cxx                                | 4111 +++----------------
 Source/cmTarget.h                                  |  429 +-
 Source/cmTargetCompileOptionsCommand.cxx           |    3 +-
 Source/cmTargetDepend.h                            |   13 +-
 Source/cmTargetIncludeDirectoriesCommand.cxx       |   23 +-
 Source/cmTest.cxx                                  |   18 +-
 Source/cmTestGenerator.cxx                         |   35 +-
 Source/cmTestGenerator.h                           |    4 +
 Source/cmUseMangledMesaCommand.h                   |    1 -
 Source/cmUtilitySourceCommand.h                    |    1 -
 Source/cmVariableRequiresCommand.h                 |    1 -
 Source/cmVariableWatchCommand.cxx                  |   16 +-
 Source/cmVisualStudio10TargetGenerator.cxx         |  532 ++-
 Source/cmVisualStudio10TargetGenerator.h           |   10 +
 Source/cmVisualStudioGeneratorOptions.cxx          |   14 +-
 Source/cmWhileCommand.cxx                          |   15 +-
 Source/cmWriteFileCommand.h                        |    6 -
 Source/cmXCode21Object.cxx                         |    2 +-
 Source/cmXCodeObject.cxx                           |    6 +-
 Source/cmXMLSafe.cxx                               |    8 +-
 Source/cmXMLSafe.h                                 |    8 +-
 Source/cmake.cxx                                   |   98 +-
 Source/cmake.h                                     |   10 +-
 Source/cmake.version.manifest                      |   18 +
 Source/cmakemain.cxx                               |   10 +-
 Source/cmcmd.cxx                                   |  480 ++-
 Source/cmcmd.h                                     |   14 -
 Source/ctest.cxx                                   |    5 +
 Source/kwsys/CMakeEmptyInputFile.in                |    1 -
 Source/kwsys/CMakeLists.txt                        |  217 +-
 Source/kwsys/CONTRIBUTING.rst                      |    2 +-
 Source/kwsys/CTestCustom.cmake.in                  |   14 +
 Source/kwsys/CommandLineArguments.cxx              |  103 +-
 Source/kwsys/CommandLineArguments.hxx.in           |   56 +-
 Source/kwsys/Configure.hxx.in                      |  144 -
 Source/kwsys/Directory.cxx                         |   21 +-
 Source/kwsys/Directory.hxx.in                      |   16 +-
 Source/kwsys/DynamicLoader.cxx                     |   28 +-
 Source/kwsys/DynamicLoader.hxx.in                  |   18 +-
 Source/kwsys/Encoding.hxx.in                       |   22 +-
 Source/kwsys/EncodingC.c                           |   14 +-
 Source/kwsys/EncodingCXX.cxx                       |   16 +-
 Source/kwsys/FStream.hxx.in                        |    6 +-
 Source/kwsys/Glob.cxx                              |   93 +-
 Source/kwsys/Glob.hxx.in                           |   44 +-
 Source/kwsys/IOStream.cxx                          |   88 +-
 Source/kwsys/IOStream.hxx.in                       |   32 +-
 Source/kwsys/Process.h.in                          |  131 +-
 Source/kwsys/ProcessUNIX.c                         |  357 +-
 Source/kwsys/ProcessWin32.c                        |  613 ++-
 Source/kwsys/RegularExpression.hxx.in              |   60 +-
 Source/kwsys/String.hxx.in                         |   10 +-
 Source/kwsys/System.c                              |  585 +--
 Source/kwsys/System.h.in                           |   98 -
 Source/kwsys/SystemInformation.cxx                 |  442 +-
 Source/kwsys/SystemInformation.hxx.in              |   39 +-
 Source/kwsys/SystemTools.cxx                       | 1152 +++---
 Source/kwsys/SystemTools.hxx.in                    |  459 ++-
 Source/kwsys/hash_fun.hxx.in                       |   46 +-
 Source/kwsys/hash_map.hxx.in                       |  124 +-
 Source/kwsys/hash_set.hxx.in                       |  122 +-
 Source/kwsys/hashtable.hxx.in                      |  387 +-
 Source/kwsys/kwsysPlatformTestsCXX.cxx             |  287 +-
 Source/kwsys/kwsys_cstddef.hxx.in                  |   35 -
 Source/kwsys/kwsys_ios_fstream.h.in                |   46 -
 Source/kwsys/kwsys_ios_iosfwd.h.in                 |   49 -
 Source/kwsys/kwsys_ios_iostream.h.in               |   99 -
 Source/kwsys/kwsys_ios_sstream.h.in                |  199 -
 Source/kwsys/kwsys_stl.hxx.in                      |   49 -
 Source/kwsys/kwsys_stl_string.hxx.in               |  123 -
 Source/kwsys/testCommandLineArguments.cxx          |   70 +-
 Source/kwsys/testCommandLineArguments1.cxx         |   34 +-
 Source/kwsys/testDynamicLoader.cxx                 |   27 +-
 Source/kwsys/testEncoding.cxx                      |    3 +-
 Source/kwsys/testFStream.cxx                       |   21 +-
 Source/kwsys/testHashSTL.cxx                       |   10 +-
 Source/kwsys/testIOS.cxx                           |   73 +-
 Source/kwsys/testProcess.c                         |  293 +-
 Source/kwsys/testSystemInformation.cxx             |   23 +-
 Source/kwsys/testSystemTools.cxx                   |  522 ++-
 Templates/CPack.GenericDescription.txt             |    2 +-
 Templates/CPack.GenericLicense.txt                 |    2 +-
 Templates/Windows/SmallLogo44x44.png               |  Bin 0 -> 554 bytes
 Tests/BuildDepends/CMakeLists.txt                  |   21 +-
 Tests/BuildDepends/Project/CMakeLists.txt          |   12 +
 Tests/BuildDepends/Project/object_depends.cxx      |    1 +
 .../Project/object_depends_check.cmake             |    7 +
 Tests/CMakeLib/testVisualStudioSlnParser.cxx       |   60 +-
 Tests/CMakeLib/testXMLParser.cxx                   |    4 +-
 Tests/CMakeLists.txt                               |  128 +-
 Tests/CMakeOnly/Test.cmake.in                      |    6 +
 Tests/CMakeTests/GetPropertyTest.cmake.in          |   96 -
 Tests/CMakeTests/IfTest.cmake.in                   |   11 -
 Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in     |    7 +
 Tests/CMakeTests/List-Get-CMP0007-Warn.cmake       |    6 -
 Tests/CMakeTests/ListTest.cmake.in                 |   53 -
 Tests/CMakeTests/WhileTest.cmake.in                |   40 -
 Tests/CPackComponents/CMakeLists.txt               |    2 +-
 Tests/CPackComponentsDEB/CMakeLists.txt            |   37 +
 ...yResult-components-lintian-dpkgdeb-checks.cmake |    2 +-
 .../CPackComponentsDEB/RunCPackVerifyResult.cmake  |   12 +-
 Tests/CPackComponentsDEB/license.txt               |    2 +-
 Tests/CPackComponentsForAll/license.txt            |    2 +-
 Tests/CPackWiXGenerator/CMakeLists.txt             |    2 +-
 Tests/CTestCoverageCollectGCOV/test.cmake.in       |    6 +-
 Tests/CTestTest2/test.cmake.in                     |   13 +-
 Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt |    3 -
 .../CTestConfig.cmake                              |    7 -
 Tests/CTestTestConfigFileInBuildDir/test1.cmake.in |   19 -
 Tests/CTestTestConfigFileInBuildDir/test2.cmake.in |   19 -
 Tests/CTestUpdateCVS.cmake.in                      |   19 +
 Tests/CTestUpdateCommon.cmake                      |   32 +-
 Tests/CTestUpdateGIT.cmake.in                      |   35 +-
 Tests/CTestUpdateHG.cmake.in                       |   19 +
 Tests/CTestUpdateSVN.cmake.in                      |   19 +
 Tests/Contracts/Trilinos/CMakeLists.txt            |    2 +-
 Tests/ExportImport/Export/CMakeLists.txt           |   58 +-
 Tests/ExportImport/Export/Interface/CMakeLists.txt |    4 +
 Tests/ExportImport/Export/testExe4.c               |   24 +
 Tests/ExportImport/Export/testLib7.c               |    1 +
 Tests/ExportImport/Export/testLibNoSONAME.c        |    7 +
 Tests/ExportImport/Import/A/CMakeLists.txt         |   58 +
 .../ExportImport/Import/A/check_lib_nosoname.cmake |    7 +
 Tests/ExportImport/Import/A/check_lib_soname.cmake |    7 +
 Tests/ExportImport/Import/A/imp_testExe1.c         |    6 +-
 Tests/ExportImport/Import/Interface/CMakeLists.txt |   11 +
 Tests/ExternalProject/CMakeLists.txt               |   60 +
 Tests/ExternalProject/Example/CMakeLists.txt       |    2 +-
 Tests/ExternalProject/gitrepo-sub.tgz              |  Bin 0 -> 1911 bytes
 Tests/FindGTK2/CMakeLists.txt                      |    3 +
 Tests/FindOpenSSL/CMakeLists.txt                   |    9 +
 Tests/FindOpenSSL/rand/CMakeLists.txt              |   14 +
 Tests/FindOpenSSL/rand/main.cc                     |   22 +
 Tests/FindPackageModeMakefileTest/Makefile.in      |    5 +-
 Tests/FindThreads/C-only/CMakeLists.txt            |   10 +
 Tests/FindThreads/CMakeLists.txt                   |   11 +
 Tests/FindThreads/CXX-only/CMakeLists.txt          |   13 +
 Tests/FortranC/Flags.cmake.in                      |    6 +
 Tests/GeneratorExpression/CMakeLists.txt           |   26 +-
 Tests/GeneratorExpression/check-common.cmake       |    4 +-
 Tests/GeneratorExpression/check-part1.cmake        |    2 +-
 Tests/GeneratorExpression/check-part4.cmake        |   15 +
 .../SystemIncludeDirectories/CMakeLists.txt        |   10 +
 .../TargetIncludeDirectories/CMakeLists.txt        |    6 +-
 Tests/Java/CMakeLists.txt                          |    4 +
 Tests/JavaJavah/B.cpp                              |   10 +
 Tests/JavaJavah/B.java                             |   19 +
 Tests/JavaJavah/CMakeLists.txt                     |   20 +
 Tests/JavaJavah/HelloWorld2.java                   |   10 +
 Tests/MSManifest/CMakeLists.txt                    |    5 +
 Tests/MSManifest/Subdir/CMakeLists.txt             |    9 +
 Tests/MSManifest/Subdir/check.cmake                |    6 +
 Tests/MSManifest/Subdir/main.c                     |    1 +
 Tests/MSManifest/Subdir/test.manifest.in           |    4 +
 Tests/Module/GenerateExportHeader/CMakeLists.txt   |    4 +-
 Tests/OutOfBinary/CMakeLists.txt                   |    2 +
 Tests/OutOfBinary/outexe.c                         |    2 +
 Tests/OutOfSource/SubDir/CMakeLists.txt            |    2 +
 Tests/OutOfSource/SubDir/subdir.c                  |    1 +
 Tests/Plugin/CMakeLists.txt                        |    9 +-
 Tests/Plugin/PluginTest/CMakeLists.txt             |   17 +-
 Tests/Plugin/check_mod_soname.cmake                |   17 +-
 Tests/Plugin/src/example_exe.cxx                   |   20 +-
 Tests/QtAutogen/CMakeLists.txt                     |   36 +-
 Tests/QtAutogen/automoc_rerun/CMakeLists.txt       |   27 +
 Tests/QtAutogen/automoc_rerun/input.txt            |    1 +
 Tests/QtAutogen/automoc_rerun/res1.qrc             |    5 +
 Tests/QtAutogen/automoc_rerun/test1.cpp            |    5 +
 Tests/QtAutogen/automoc_rerun/test1.h.in1          |    8 +
 Tests/QtAutogen/automoc_rerun/test1.h.in2          |    7 +
 Tests/QtAutogen/targetObjectsTest.cpp              |    5 +
 Tests/RegexEscapeString.cmake                      |    4 -
 Tests/RunCMake/AutoExportDll/AutoExport.cmake      |    7 +
 .../AutoExportDll/AutoExportBuild-stderr.txt       |    1 +
 Tests/RunCMake/AutoExportDll/CMakeLists.txt        |    3 +
 Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake    |   26 +
 Tests/RunCMake/AutoExportDll/foo.c                 |   15 +
 Tests/RunCMake/AutoExportDll/hello.cxx             |   13 +
 Tests/RunCMake/AutoExportDll/hello.h               |   18 +
 Tests/RunCMake/AutoExportDll/say.cxx               |   37 +
 Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt    |    5 +
 Tests/RunCMake/AutoExportDll/sub/sub.cxx           |    4 +
 Tests/RunCMake/AutoExportDll/world.cxx             |    6 +
 Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake   |   19 +
 .../BuildDepends/C-Exe-Manifest.step1.cmake        |    6 +
 .../BuildDepends/C-Exe-Manifest.step2.cmake        |    6 +
 Tests/RunCMake/BuildDepends/C-Exe.cmake            |   12 +
 Tests/RunCMake/BuildDepends/C-Exe.step1.cmake      |    3 +
 Tests/RunCMake/BuildDepends/C-Exe.step2.cmake      |    3 +
 Tests/RunCMake/BuildDepends/CMakeLists.txt         |    3 +
 Tests/RunCMake/BuildDepends/RunCMakeTest.cmake     |   40 +
 Tests/RunCMake/BuildDepends/check.cmake            |   37 +
 Tests/RunCMake/BuildDepends/main.c                 |    1 +
 Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt     |    6 +-
 Tests/RunCMake/CMP0026/RunCMakeTest.cmake          |    1 +
 .../clear-cached-information-dir/CMakeLists.txt    |    2 +
 .../CMP0026/clear-cached-information.cmake         |   14 +
 Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt     |   12 +
 Tests/RunCMake/CMP0054/CMP0054-WARN.cmake          |    2 +
 .../CMP0054/CMP0054-keywords-WARN-stderr.txt       |   13 +
 Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake |    2 +
 Tests/RunCMake/CMP0064/CMP0064-NEW.cmake           |    5 +
 Tests/RunCMake/CMP0064/CMP0064-OLD.cmake           |    7 +
 Tests/RunCMake/CMP0064/CMP0064-WARN-stderr.txt     |   10 +
 Tests/RunCMake/CMP0064/CMP0064-WARN.cmake          |    7 +
 Tests/RunCMake/CMP0064/CMakeLists.txt              |    3 +
 Tests/RunCMake/CMP0064/RunCMakeTest.cmake          |    5 +
 .../RunCMake/CMP0065/BuildTargetInSubProject.cmake |   15 +
 Tests/RunCMake/CMP0065/CMakeLists.txt              |    3 +
 Tests/RunCMake/CMP0065/NEWBad.cmake                |    4 +
 Tests/RunCMake/CMP0065/NEWGood.cmake               |    4 +
 Tests/RunCMake/CMP0065/OLDBad1.cmake               |    4 +
 Tests/RunCMake/CMP0065/OLDBad2.cmake               |    4 +
 Tests/RunCMake/CMP0065/RunCMakeTest.cmake          |    8 +
 Tests/RunCMake/CMP0065/WARN-OFF.cmake              |    3 +
 Tests/RunCMake/CMP0065/WARN-ON-stderr.txt          |   10 +
 Tests/RunCMake/CMP0065/WARN-ON.cmake               |    3 +
 Tests/RunCMake/CMP0065/subproject/CMakeLists.txt   |   22 +
 Tests/RunCMake/CMP0065/subproject/main.c           |    7 +
 Tests/RunCMake/CMakeLists.txt                      |   67 +-
 Tests/RunCMake/CPack/CMakeLists.txt                |   12 +
 Tests/RunCMake/CPack/COMPONENTS_EMPTY_DIR.cmake    |    5 +
 Tests/RunCMake/CPack/CPackTestHelpers.cmake        |   41 +
 .../DEB/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake   |    5 +
 .../CPack/DEB/COMPONENTS_EMPTY_DIR-specifics.cmake |    2 +
 .../CPack/DEB/DEB_EXTRA-ExpectedFiles.cmake        |    9 +
 .../CPack/DEB/DEB_EXTRA-VerifyResult.cmake         |   17 +
 .../CPack/DEB/DEPENDENCIES-ExpectedFiles.cmake     |   14 +
 .../CPack/DEB/DEPENDENCIES-VerifyResult.cmake      |   34 +
 .../CPack/DEB/DEPENDENCIES-specifics.cmake         |   21 +
 .../CPack/DEB/EMPTY_DIR-ExpectedFiles.cmake        |    5 +
 Tests/RunCMake/CPack/DEB/EMPTY_DIR-specifics.cmake |    1 +
 Tests/RunCMake/CPack/DEB/Helpers.cmake             |   51 +
 .../RunCMake/CPack/DEB/MINIMAL-ExpectedFiles.cmake |    5 +
 Tests/RunCMake/CPack/DEB/MINIMAL-specifics.cmake   |    1 +
 Tests/RunCMake/CPack/DEB/Prerequirements.cmake     |    8 +
 Tests/RunCMake/CPack/DEB_EXTRA.cmake               |   38 +
 Tests/RunCMake/CPack/DEPENDENCIES.cmake            |   20 +
 Tests/RunCMake/CPack/EMPTY_DIR.cmake               |    4 +
 Tests/RunCMake/CPack/MINIMAL.cmake                 |    3 +
 .../PARTIALLY_RELOCATABLE_WARNING.cmake}           |    0
 Tests/RunCMake/CPack/README.txt                    |   99 +
 .../RPM/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake   |    5 +
 .../CPack/RPM/COMPONENTS_EMPTY_DIR-stderr.txt      |    1 +
 .../CPack/RPM/DEPENDENCIES-ExpectedFiles.cmake     |   13 +
 .../CPack/RPM/DEPENDENCIES-VerifyResult.cmake      |   45 +
 .../CPack/RPM/DEPENDENCIES-specifics.cmake         |   22 +
 .../CPack/RPM/EMPTY_DIR-ExpectedFiles.cmake        |    5 +
 Tests/RunCMake/CPack/RPM/EMPTY_DIR-stderr.txt      |    1 +
 Tests/RunCMake/CPack/RPM/Helpers.cmake             |   10 +
 .../RunCMake/CPack/RPM/MINIMAL-ExpectedFiles.cmake |    5 +
 Tests/RunCMake/CPack/RPM/MINIMAL-stderr.txt        |    1 +
 ...RTIALLY_RELOCATABLE_WARNING-ExpectedFiles.cmake |    5 +
 .../RPM/PARTIALLY_RELOCATABLE_WARNING-stderr.txt}  |    0
 Tests/RunCMake/CPack/RPM/Prerequirements.cmake     |   16 +
 Tests/RunCMake/CPack/RunCMakeTest.cmake            |   12 +
 .../TGZ/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake   |    3 +
 .../CPack/TGZ/COMPONENTS_EMPTY_DIR-specifics.cmake |    1 +
 .../CPack/TGZ/EMPTY_DIR-ExpectedFiles.cmake        |    3 +
 Tests/RunCMake/CPack/TGZ/Helpers.cmake             |   10 +
 .../RunCMake/CPack/TGZ/MINIMAL-ExpectedFiles.cmake |    5 +
 Tests/RunCMake/CPack/TGZ/Prerequirements.cmake     |    4 +
 Tests/RunCMake/CPack/VerifyResult.cmake            |   92 +
 Tests/RunCMake/CPackConfig/CMakeLists.txt          |    6 +
 Tests/RunCMake/CPackConfig/Default-check.cmake     |    7 +
 Tests/RunCMake/CPackConfig/Default.cmake           |    3 +
 Tests/RunCMake/CPackConfig/RunCMakeTest.cmake      |    6 +
 Tests/RunCMake/CPackConfig/Simple-check.cmake      |    3 +
 Tests/RunCMake/CPackConfig/Simple.cmake            |    1 +
 Tests/RunCMake/CPackConfig/Special-check.cmake     |    5 +
 Tests/RunCMake/CPackConfig/Special.cmake           |    3 +
 Tests/RunCMake/CPackConfig/Verbatim-check.cmake    |   10 +
 Tests/RunCMake/CPackConfig/Verbatim.cmake          |    5 +
 Tests/RunCMake/CPackConfig/check.cmake             |   10 +
 Tests/RunCMake/CPackRPM/CMakeLists.txt             |    7 -
 Tests/RunCMake/CPackRPM/RunCMakeTest.cmake         |   17 -
 .../CTestCommandLine/LabelCount-stdout.txt         |    7 +
 .../CTestCommandLine/MergeOutput-stdout.txt        |   13 +
 Tests/RunCMake/CTestCommandLine/MergeOutput.cmake  |    4 +
 Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake |  101 +
 .../CTestCommandLine/SerialFailed-result.txt       |    1 +
 .../CTestCommandLine/SerialFailed-stderr.txt       |    1 +
 .../CTestCommandLine/SerialFailed-stdout.txt       |   10 +
 .../CTestCommandLine/TestOutputSize-check.cmake    |   17 +
 .../CTestCommandLine/TestOutputSize-result.txt     |    1 +
 .../CTestCommandLine/TestOutputSize-stderr.txt     |    1 +
 .../CTestCommandLine/test-load-fail-stderr.txt     |    1 +
 .../CTestCommandLine/test-load-fail-stdout.txt     |    2 +
 .../CTestCommandLine/test-load-invalid-stderr.txt  |    1 +
 .../CTestCommandLine/test-load-invalid-stdout.txt  |    7 +
 .../CTestCommandLine/test-load-pass-stderr.txt     |    1 +
 .../CTestCommandLine/test-load-pass-stdout.txt     |    7 +
 Tests/RunCMake/CommandLine/BuildDir.cmake          |    1 +
 Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt |    5 +
 Tests/RunCMake/CommandLine/RunCMakeTest.cmake      |   21 +
 Tests/RunCMake/CommandLine/Wdev-stderr.txt         |    6 +
 Tests/RunCMake/CommandLine/Wdev.cmake              |    5 +
 Tests/RunCMake/CommandLine/Wno-dev.cmake           |    5 +
 .../RunCMake/CommandLine/build-bad-dir-result.txt  |    1 +
 .../RunCMake/CommandLine/build-bad-dir-stderr.txt  |    2 +
 Tests/RunCMake/CommandLine/build-no-dir-result.txt |    1 +
 Tests/RunCMake/CommandLine/build-no-dir-stderr.txt |    1 +
 Tests/RunCMake/CommandLine/trace-expand-stderr.txt |    2 +
 Tests/RunCMake/CommandLine/trace-expand.cmake      |    0
 Tests/RunCMake/CompileDefinitions/CMakeLists.txt   |    3 +
 .../RunCMake/CompileDefinitions/RunCMakeTest.cmake |    3 +
 .../CompileDefinitions/SetEmpty-result.txt         |    1 +
 .../CompileDefinitions/SetEmpty-stderr.txt         |    3 +
 Tests/RunCMake/CompileDefinitions/SetEmpty.cmake   |   12 +
 Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake  |    2 +-
 Tests/RunCMake/CompilerLauncher/C-Build-stdout.txt |    1 +
 .../CompilerLauncher/C-launch-Build-stdout.txt     |    1 +
 Tests/RunCMake/CompilerLauncher/C-launch.cmake     |    3 +
 Tests/RunCMake/CompilerLauncher/C.cmake            |    4 +
 Tests/RunCMake/CompilerLauncher/CMakeLists.txt     |    3 +
 .../RunCMake/CompilerLauncher/CXX-Build-stdout.txt |    1 +
 .../CompilerLauncher/CXX-launch-Build-stdout.txt   |    1 +
 Tests/RunCMake/CompilerLauncher/CXX-launch.cmake   |    3 +
 Tests/RunCMake/CompilerLauncher/CXX.cmake          |    4 +
 Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake |   23 +
 Tests/RunCMake/CompilerLauncher/main.c             |    3 +
 Tests/RunCMake/CompilerLauncher/main.cxx           |    1 +
 .../CompilerNotFound/BadCompilerC-stderr-JOM.txt   |   17 +
 .../CompilerNotFound/BadCompilerC-stderr-NMake.txt |   17 +
 .../CompilerNotFound/BadCompilerCXX-stderr-JOM.txt |   17 +
 .../BadCompilerCXX-stderr-NMake.txt                |   17 +
 .../BadCompilerCandCXX-stderr-JOM.txt              |   35 +
 .../BadCompilerCandCXX-stderr-NMake.txt            |   35 +
 Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake |   14 +
 Tests/RunCMake/ExternalProject/RunCMakeTest.cmake  |    1 +
 .../ExternalProject/UsesTerminal-check.cmake       |   97 +
 Tests/RunCMake/ExternalProject/UsesTerminal.cmake  |   45 +
 .../FindPkgConfig_GET_VARIABLE-stdout.txt          |    1 +
 .../FindPkgConfig/FindPkgConfig_GET_VARIABLE.cmake |    9 +
 Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake    |    6 +
 Tests/RunCMake/GNUInstallDirs/CMakeLists.txt       |    3 +
 Tests/RunCMake/GNUInstallDirs/Common.cmake         |   28 +
 Tests/RunCMake/GNUInstallDirs/Opt-stderr.txt       |   28 +
 Tests/RunCMake/GNUInstallDirs/Opt.cmake            |    2 +
 Tests/RunCMake/GNUInstallDirs/Root-stderr.txt      |   28 +
 Tests/RunCMake/GNUInstallDirs/Root.cmake           |    2 +
 Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake   |    6 +
 Tests/RunCMake/GNUInstallDirs/Usr-stderr.txt       |   28 +
 Tests/RunCMake/GNUInstallDirs/Usr.cmake            |    2 +
 Tests/RunCMake/GNUInstallDirs/UsrLocal-stderr.txt  |   28 +
 Tests/RunCMake/GNUInstallDirs/UsrLocal.cmake       |    2 +
 .../GeneratorExpression/BadSHELL_PATH-result.txt   |    1 +
 .../GeneratorExpression/BadSHELL_PATH-stderr.txt   |   17 +
 .../GeneratorExpression/BadSHELL_PATH.cmake        |    4 +
 .../ImportedTarget-TARGET_PDB_FILE-result.txt      |    1 +
 .../ImportedTarget-TARGET_PDB_FILE-stderr.txt      |    8 +
 .../ImportedTarget-TARGET_PDB_FILE.cmake           |    2 +
 .../OUTPUT_NAME-recursion-result.txt               |    1 +
 .../OUTPUT_NAME-recursion-stderr.txt               |    4 +
 .../OUTPUT_NAME-recursion.cmake                    |    3 +
 .../GeneratorExpression/RunCMakeTest.cmake         |    4 +
 .../TARGET_FILE-recursion-result.txt               |    1 +
 .../TARGET_FILE-recursion-stderr.txt               |    4 +
 .../TARGET_FILE-recursion.cmake                    |    4 +
 Tests/RunCMake/Languages/DetermineFail-result.txt  |    1 +
 Tests/RunCMake/Languages/DetermineFail-stderr.txt  |    5 +
 Tests/RunCMake/Languages/DetermineFail.cmake       |    2 +
 .../Modules/CMakeDetermineFailCompiler.cmake       |    1 +
 Tests/RunCMake/Languages/RunCMakeTest.cmake        |    2 +
 Tests/RunCMake/LinkStatic/CMakeLists.txt           |    3 +
 Tests/RunCMake/LinkStatic/LINK_SEARCH_STATIC.cmake |   73 +
 Tests/RunCMake/LinkStatic/LinkStatic.c             |    5 +
 Tests/RunCMake/LinkStatic/RunCMakeTest.cmake       |    3 +
 Tests/RunCMake/Make/CMakeLists.txt                 |    3 +
 Tests/RunCMake/Make/RunCMakeTest.cmake             |   17 +
 .../Make/TargetMessages-OFF-build-stdout.txt       |    5 +
 Tests/RunCMake/Make/TargetMessages-OFF.cmake       |    2 +
 .../Make/TargetMessages-ON-build-stdout.txt        |    8 +
 Tests/RunCMake/Make/TargetMessages-ON.cmake        |    2 +
 .../Make/TargetMessages-VAR-OFF-build-stdout.txt   |    5 +
 Tests/RunCMake/Make/TargetMessages-VAR-OFF.cmake   |    1 +
 .../Make/TargetMessages-VAR-ON-build-stdout.txt    |    8 +
 Tests/RunCMake/Make/TargetMessages-VAR-ON.cmake    |    1 +
 Tests/RunCMake/PolicyScope/CMakeLists.txt          |    3 +
 Tests/RunCMake/PolicyScope/RunCMakeTest.cmake      |    4 +
 .../dir-in-macro-generate-time-result.txt          |    1 +
 .../dir-in-macro-generate-time-stderr.txt          |    5 +
 .../PolicyScope/dir-in-macro-generate-time.cmake   |    2 +
 .../PolicyScope/dir-in-macro-include.cmake         |    6 +
 Tests/RunCMake/PolicyScope/dir1/CMakeLists.txt     |    5 +
 Tests/RunCMake/PolicyScope/dir1/foo.cpp            |    5 +
 .../parent-dir-generate-time-result.txt            |    1 +
 .../PolicyScope/parent-dir-generate-time.cmake     |    7 +
 Tests/RunCMake/RunCMake.cmake                      |   15 +-
 Tests/RunCMake/Swift/CMakeLists.txt                |    3 +
 Tests/RunCMake/Swift/NotSupported-result.txt       |    1 +
 Tests/RunCMake/Swift/NotSupported-stderr.txt       |    5 +
 Tests/RunCMake/Swift/NotSupported.cmake            |    1 +
 Tests/RunCMake/Swift/RunCMakeTest.cmake            |    9 +
 Tests/RunCMake/Swift/XcodeTooOld-result.txt        |    1 +
 Tests/RunCMake/Swift/XcodeTooOld-stderr.txt        |    5 +
 Tests/RunCMake/Swift/XcodeTooOld.cmake             |    1 +
 Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt     |    4 +-
 Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt     |    4 +-
 Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt     |    4 +-
 Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt     |    4 +-
 Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt   |    4 +-
 Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt   |    4 +-
 Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt   |    4 +-
 Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt   |    4 +-
 Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt   |    4 +-
 Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt   |    4 +-
 Tests/RunCMake/Syntax/ParenInENV-stderr.txt        |    4 +-
 Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt     |   12 +-
 Tests/RunCMake/Syntax/StringNoSpace-stderr.txt     |    8 +-
 .../RunCMake/TargetPolicies/PolicyList-stderr.txt  |    1 +
 Tests/RunCMake/XcodeProject/RunCMakeTest.cmake     |   52 +
 Tests/RunCMake/XcodeProject/XcodeBundles.cmake     |   45 +
 .../XcodeInstallIOS-install-stdout.txt             |    2 +
 Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake  |   12 +
 .../RunCMake/XcodeProject/XcodeTbdStub-stdout.txt  |    1 +
 Tests/RunCMake/XcodeProject/XcodeTbdStub.cmake     |    2 +
 Tests/RunCMake/XcodeProject/foo.cpp                |    1 +
 Tests/RunCMake/XcodeProject/main.m                 |    3 +
 Tests/RunCMake/XcodeProject/osx.cmake              |   18 +
 .../RunCMake/ctest_build/BuildChangeId-check.cmake |   12 +
 Tests/RunCMake/ctest_build/RunCMakeTest.cmake      |    9 +
 .../RunCMake/ctest_start/ConfigInBuild-stdout.txt  |    7 +
 .../RunCMake/ctest_start/ConfigInSource-stdout.txt |    7 +
 Tests/RunCMake/ctest_start/RunCMakeTest.cmake      |   13 +
 Tests/RunCMake/ctest_test/CMakeLists.txt.in        |    1 +
 .../ctest_test/CTestTestLoadFail-result.txt        |    1 +
 .../ctest_test/CTestTestLoadFail-stderr.txt        |    1 +
 .../ctest_test/CTestTestLoadFail-stdout.txt        |    2 +
 .../ctest_test/CTestTestLoadInvalid-stderr.txt     |    1 +
 .../ctest_test/CTestTestLoadInvalid-stdout.txt     |    7 +
 .../ctest_test/CTestTestLoadPass-stdout.txt        |    7 +
 Tests/RunCMake/ctest_test/RunCMakeTest.cmake       |   66 +
 Tests/RunCMake/ctest_test/TestChangeId-check.cmake |   12 +
 Tests/RunCMake/ctest_test/TestLoadFail-result.txt  |    1 +
 Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt  |    1 +
 Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt  |    2 +
 .../RunCMake/ctest_test/TestLoadInvalid-stderr.txt |    1 +
 .../RunCMake/ctest_test/TestLoadInvalid-stdout.txt |    7 +
 Tests/RunCMake/ctest_test/TestLoadOrder-stderr.txt |    1 +
 Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt |    7 +
 Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt  |    7 +
 .../RunCMake/ctest_test/TestOutputSize-check.cmake |   17 +
 Tests/RunCMake/ctest_test/test.cmake.in            |    2 +
 Tests/RunCMake/export/AppendExport-stderr.txt      |    2 +-
 Tests/RunCMake/export/AppendExport.cmake           |    1 +
 Tests/RunCMake/export/CMakeLists.txt               |    2 +-
 Tests/RunCMake/export/CustomTarget-result.txt      |    1 +
 Tests/RunCMake/export/CustomTarget-stderr.txt      |    4 +
 Tests/RunCMake/export/CustomTarget.cmake           |    2 +
 Tests/RunCMake/export/OldIface-stderr.txt          |    2 +-
 Tests/RunCMake/export/OldIface.cmake               |    1 +
 Tests/RunCMake/export/RunCMakeTest.cmake           |    1 +
 Tests/RunCMake/find_program/A/testA                |    1 +
 Tests/RunCMake/find_program/A/testAandB            |    1 +
 Tests/RunCMake/find_program/B/testAandB            |    1 +
 Tests/RunCMake/find_program/B/testB                |    1 +
 Tests/RunCMake/find_program/CMakeLists.txt         |    3 +
 Tests/RunCMake/find_program/DirsPerName-stdout.txt |    2 +
 Tests/RunCMake/find_program/DirsPerName.cmake      |   12 +
 Tests/RunCMake/find_program/EnvAndHints-stdout.txt |    1 +
 Tests/RunCMake/find_program/EnvAndHints.cmake      |    8 +
 Tests/RunCMake/find_program/NamesPerDir-stdout.txt |    2 +
 Tests/RunCMake/find_program/NamesPerDir.cmake      |   12 +
 Tests/RunCMake/find_program/RunCMakeTest.cmake     |   10 +
 Tests/RunCMake/find_program/Win/testCom.com        |    0
 Tests/RunCMake/find_program/Win/testCom.exe        |    0
 Tests/RunCMake/find_program/Win/testExe.exe        |    0
 Tests/RunCMake/find_program/WindowsCom-stdout.txt  |    1 +
 Tests/RunCMake/find_program/WindowsCom.cmake       |    6 +
 Tests/RunCMake/find_program/WindowsExe-stdout.txt  |    1 +
 Tests/RunCMake/find_program/WindowsExe.cmake       |    6 +
 .../RunCMake/get_filename_component/CMakeLists.txt |    2 +-
 .../get_filename_component/KnownComponents.cmake   |  110 +
 Tests/RunCMake/get_property/BadArgument-result.txt |    1 +
 Tests/RunCMake/get_property/BadArgument-stderr.txt |    4 +
 .../get_property/BadArgument.cmake}                |    0
 .../RunCMake/get_property/BadDirectory-result.txt  |    1 +
 .../RunCMake/get_property/BadDirectory-stderr.txt  |    6 +
 .../get_property/BadDirectory.cmake}               |    0
 Tests/RunCMake/get_property/BadScope-result.txt    |    1 +
 Tests/RunCMake/get_property/BadScope-stderr.txt    |    5 +
 .../get_property/BadScope.cmake}                   |    0
 Tests/RunCMake/get_property/BadTarget-result.txt   |    1 +
 Tests/RunCMake/get_property/BadTarget-stderr.txt   |    5 +
 .../get_property/BadTarget.cmake}                  |    0
 Tests/RunCMake/get_property/BadTest-result.txt     |    1 +
 Tests/RunCMake/get_property/BadTest-stderr.txt     |    4 +
 .../get_property/BadTest.cmake}                    |    0
 Tests/RunCMake/get_property/GlobalName-result.txt  |    1 +
 Tests/RunCMake/get_property/GlobalName-stderr.txt  |    4 +
 .../get_property/GlobalName.cmake}                 |    0
 .../get_property/MissingArgument-result.txt        |    1 +
 .../get_property/MissingArgument-stderr.txt        |    4 +
 .../get_property/MissingArgument.cmake}            |    0
 Tests/RunCMake/get_property/NoCache-result.txt     |    1 +
 Tests/RunCMake/get_property/NoCache-stderr.txt     |    4 +
 .../get_property/NoCache.cmake}                    |    0
 Tests/RunCMake/get_property/NoProperty-result.txt  |    1 +
 Tests/RunCMake/get_property/NoProperty-stderr.txt  |    4 +
 .../get_property/NoProperty.cmake}                 |    0
 Tests/RunCMake/get_property/NoSource-result.txt    |    1 +
 Tests/RunCMake/get_property/NoSource-stderr.txt    |    4 +
 .../get_property/NoSource.cmake}                   |    0
 Tests/RunCMake/get_property/NoTarget-result.txt    |    1 +
 Tests/RunCMake/get_property/NoTarget-stderr.txt    |    4 +
 .../get_property/NoTarget.cmake}                   |    0
 Tests/RunCMake/get_property/NoTest-result.txt      |    1 +
 Tests/RunCMake/get_property/NoTest-stderr.txt      |    4 +
 .../get_property/NoTest.cmake}                     |    0
 Tests/RunCMake/get_property/RunCMakeTest.cmake     |   14 +
 .../RunCMake/get_property/VariableName-result.txt  |    1 +
 .../RunCMake/get_property/VariableName-stderr.txt  |    4 +
 .../get_property/VariableName.cmake}               |    0
 .../get_property/target_properties-stderr.txt      |    6 +-
 .../RunCMake/get_property/target_properties.cmake  |    2 +
 Tests/RunCMake/if/InvalidArgument1-result.txt      |    1 +
 Tests/RunCMake/if/InvalidArgument1-stderr.txt      |    8 +
 .../if/InvalidArgument1.cmake}                     |    0
 Tests/RunCMake/if/RunCMakeTest.cmake               |    4 +
 .../if/TestNameThatDoesNotExist-stdout.txt         |    1 +
 Tests/RunCMake/if/TestNameThatDoesNotExist.cmake   |    6 +
 Tests/RunCMake/if/TestNameThatExists-stdout.txt    |    1 +
 Tests/RunCMake/if/TestNameThatExists.cmake         |    7 +
 .../include_directories/DirectoryBefore-stdout.txt |    1 +
 .../include_directories/DirectoryBefore.cmake      |    4 +
 .../include_directories/RunCMakeTest.cmake         |    1 +
 .../install/DIRECTORY-DESTINATION-bad-result.txt   |    1 +
 .../install/DIRECTORY-DESTINATION-bad-stderr.txt   |    6 +
 .../install/DIRECTORY-DESTINATION-bad.cmake        |    1 +
 .../install/FILES-DESTINATION-bad-result.txt       |    1 +
 .../install/FILES-DESTINATION-bad-stderr.txt       |    6 +
 Tests/RunCMake/install/FILES-DESTINATION-bad.cmake |    1 +
 Tests/RunCMake/install/RunCMakeTest.cmake          |    2 +
 Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt    |    8 +
 Tests/RunCMake/list/GET-CMP0007-WARN.cmake         |    7 +
 Tests/RunCMake/list/GET-InvalidIndex-result.txt    |    1 +
 Tests/RunCMake/list/GET-InvalidIndex-stderr.txt    |    4 +
 .../list/GET-InvalidIndex.cmake}                   |    0
 Tests/RunCMake/list/INSERT-InvalidIndex-result.txt |    1 +
 Tests/RunCMake/list/INSERT-InvalidIndex-stderr.txt |    4 +
 .../list/INSERT-InvalidIndex.cmake}                |    0
 Tests/RunCMake/list/InvalidSubcommand-result.txt   |    1 +
 Tests/RunCMake/list/InvalidSubcommand-stderr.txt   |    4 +
 .../list/InvalidSubcommand.cmake}                  |    0
 .../list/LENGTH-TooManyArguments-result.txt        |    1 +
 .../list/LENGTH-TooManyArguments-stderr.txt        |    4 +
 .../list/LENGTH-TooManyArguments.cmake}            |    0
 Tests/RunCMake/list/NoArguments-result.txt         |    1 +
 Tests/RunCMake/list/NoArguments-stderr.txt         |    4 +
 .../list/NoArguments.cmake}                        |    0
 .../list/REMOVE_AT-InvalidIndex-result.txt         |    1 +
 .../list/REMOVE_AT-InvalidIndex-stderr.txt         |    4 +
 .../list/REMOVE_AT-InvalidIndex.cmake}             |    0
 Tests/RunCMake/list/REMOVE_AT-NotList-result.txt   |    1 +
 Tests/RunCMake/list/REMOVE_AT-NotList-stderr.txt   |    4 +
 .../list/REMOVE_AT-NotList.cmake}                  |    0
 .../list/REMOVE_DUPLICATES-NotList-result.txt      |    1 +
 .../list/REMOVE_DUPLICATES-NotList-stderr.txt      |    4 +
 .../list/REMOVE_DUPLICATES-NotList.cmake}          |    0
 .../REMOVE_DUPLICATES-TooManyArguments-result.txt  |    1 +
 .../REMOVE_DUPLICATES-TooManyArguments-stderr.txt  |    4 +
 .../list/REMOVE_DUPLICATES-TooManyArguments.cmake} |    0
 Tests/RunCMake/list/REMOVE_ITEM-NotList-result.txt |    1 +
 Tests/RunCMake/list/REMOVE_ITEM-NotList-stderr.txt |    4 +
 .../list/REMOVE_ITEM-NotList.cmake}                |    0
 Tests/RunCMake/list/REVERSE-NotList-result.txt     |    1 +
 Tests/RunCMake/list/REVERSE-NotList-stderr.txt     |    4 +
 .../list/REVERSE-NotList.cmake}                    |    0
 .../list/REVERSE-TooManyArguments-result.txt       |    1 +
 .../list/REVERSE-TooManyArguments-stderr.txt       |    4 +
 .../list/REVERSE-TooManyArguments.cmake}           |    0
 Tests/RunCMake/list/RunCMakeTest.cmake             |   19 +
 Tests/RunCMake/list/SORT-NotList-result.txt        |    1 +
 Tests/RunCMake/list/SORT-NotList-stderr.txt        |    4 +
 .../list/SORT-NotList.cmake}                       |    0
 .../RunCMake/list/SORT-TooManyArguments-result.txt |    1 +
 .../RunCMake/list/SORT-TooManyArguments-stderr.txt |    4 +
 .../list/SORT-TooManyArguments.cmake}              |    0
 .../set_property/COMPILE_DEFINITIONS-stdout.txt    |    2 +
 .../set_property/COMPILE_DEFINITIONS.cmake         |    3 +
 .../set_property/COMPILE_FEATURES-stdout.txt       |    1 +
 Tests/RunCMake/set_property/COMPILE_FEATURES.cmake |    2 +
 .../set_property/COMPILE_OPTIONS-stdout.txt        |    2 +
 Tests/RunCMake/set_property/COMPILE_OPTIONS.cmake  |    3 +
 Tests/RunCMake/set_property/Common.cmake           |   28 +
 .../set_property/INCLUDE_DIRECTORIES-stdout.txt    |    2 +
 .../set_property/INCLUDE_DIRECTORIES.cmake         |    3 +
 .../set_property/LINK_LIBRARIES-stdout.txt         |    1 +
 Tests/RunCMake/set_property/LINK_LIBRARIES.cmake   |    9 +-
 Tests/RunCMake/set_property/RunCMakeTest.cmake     |    6 +
 Tests/RunCMake/set_property/SOURCES-stdout.txt     |    1 +
 Tests/RunCMake/set_property/SOURCES.cmake          |    2 +
 Tests/RunCMake/set_property/USER_PROP-stdout.txt   |    2 +
 Tests/RunCMake/set_property/USER_PROP.cmake        |    3 +
 Tests/RunCMake/string/Append.cmake                 |   58 +
 Tests/RunCMake/string/AppendNoArgs-result.txt      |    1 +
 Tests/RunCMake/string/AppendNoArgs-stderr.txt      |    4 +
 Tests/RunCMake/string/AppendNoArgs.cmake           |    1 +
 Tests/RunCMake/string/RunCMakeTest.cmake           |    3 +
 .../target_link_libraries/RunCMakeTest.cmake       |    1 +
 .../target_link_libraries/SharedDepNotTarget.cmake |   10 +
 .../CMakeLists.txt                                 |    0
 Tests/RunCMake/while/EndAlone-result.txt           |    1 +
 Tests/RunCMake/while/EndAlone-stderr.txt           |    5 +
 .../while/EndAlone.cmake}                          |    0
 Tests/RunCMake/while/EndAloneArgs-result.txt       |    1 +
 Tests/RunCMake/while/EndAloneArgs-stderr.txt       |    5 +
 .../while/EndAloneArgs.cmake}                      |    0
 Tests/RunCMake/while/EndMismatch-stderr.txt        |   13 +
 .../while/EndMismatch.cmake}                       |    0
 Tests/RunCMake/while/EndMissing-result.txt         |    1 +
 Tests/RunCMake/while/EndMissing-stderr.txt         |    6 +
 .../while/EndMissing.cmake}                        |    0
 Tests/RunCMake/while/MissingArgument-result.txt    |    1 +
 Tests/RunCMake/while/MissingArgument-stderr.txt    |    4 +
 .../while/MissingArgument.cmake}                   |    0
 Tests/RunCMake/while/RunCMakeTest.cmake            |    7 +
 Tests/SimpleInstall/CMakeLists.txt                 |   10 +-
 Tests/SimpleInstallS2/CMakeLists.txt               |   10 +-
 Tests/SwiftMix/CMain.c                             |    4 +
 Tests/SwiftMix/CMakeLists.txt                      |    5 +
 Tests/SwiftMix/ObjC-Swift.h                        |    0
 Tests/SwiftMix/ObjCMain.m                          |    4 +
 Tests/SwiftMix/SwiftMain.swift                     |   12 +
 Tests/SwiftOnly/CMakeLists.txt                     |    4 +
 Tests/SwiftOnly/main.swift                         |    1 +
 Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt   |    6 +-
 Tests/VSNsightTegra/CMakeLists.txt                 |   19 +-
 Tests/VSNsightTegra/proguard-android.txt           |   57 +
 Tests/VSResource/CMakeLists.txt                    |    3 +
 Tests/VSResource/lib.cpp                           |    1 +
 Tests/VSResource/lib.rc                            |    4 +
 Tests/VSResource/main.cpp                          |    4 +-
 Tests/VSWinStorePhone/CMakeLists.txt               |   17 +-
 .../Direct3DApp1/Assets/SmallLogo44x44.png         |  Bin 0 -> 554 bytes
 .../cmake/Package_vc14.store.appxmanifest.in       |   36 +
 Tests/iOSNavApp/CMakeLists.txt                     |    1 -
 Utilities/Doxygen/doc_makeall.sh.in                |   26 +-
 Utilities/Release/Cygwin/README.cygwin.in          |    2 +-
 Utilities/Release/create-cmake-release.cmake       |    2 +-
 Utilities/Release/dash2win64_cygwin.cmake          |    2 +
 Utilities/Release/dash2win64_release.cmake         |    4 +-
 Utilities/Release/dashmacmini2_release.cmake       |    3 +-
 Utilities/Release/dashmacmini5_release.cmake       |    5 +-
 Utilities/Release/ibm_aix_release.cmake            |   15 -
 Utilities/Release/linux64_release.cmake            |    8 +-
 Utilities/Release/magrathea_release.cmake          |    8 +-
 Utilities/Release/release_cmake.sh.in              |   12 +-
 Utilities/Release/upload_release.cmake             |    2 +-
 Utilities/Sphinx/CMakeLists.txt                    |   14 +-
 Utilities/Sphinx/templates/layout.html             |    2 +-
 .../cmcurl/CMake/CurlCheckCSourceCompiles.cmake    |   71 -
 Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake  |   83 -
 Utilities/cmcurl/CMake/CurlTests.c                 |  316 +-
 Utilities/cmcurl/CMake/FindGSS.cmake               |  289 ++
 Utilities/cmcurl/CMake/Macros.cmake                |    8 +-
 Utilities/cmcurl/CMake/OtherTests.cmake            |  200 +-
 .../cmcurl/CMake/Platforms/WindowsCache.cmake      |    2 +-
 Utilities/cmcurl/CMakeLists.txt                    |  516 ++-
 Utilities/cmcurl/COPYING                           |    2 +-
 Utilities/cmcurl/README-CMake.txt                  |    8 +-
 Utilities/cmcurl/include/curl/curl.h               |   94 +-
 Utilities/cmcurl/include/curl/curlver.h            |   18 +-
 Utilities/cmcurl/include/curl/mprintf.h            |    9 +-
 Utilities/cmcurl/include/curl/multi.h              |   38 +-
 Utilities/cmcurl/include/curl/typecheck-gcc.h      |    2 +
 Utilities/cmcurl/lib/CMakeLists.txt                |   28 +-
 Utilities/cmcurl/lib/Makefile.inc                  |   86 +-
 Utilities/cmcurl/lib/amigaos.c                     |    4 +-
 Utilities/cmcurl/lib/asyn-ares.c                   |   37 +-
 Utilities/cmcurl/lib/asyn-thread.c                 |   45 +-
 Utilities/cmcurl/lib/base64.c                      |   23 +-
 Utilities/cmcurl/lib/bundles.c                     |  110 -
 Utilities/cmcurl/lib/bundles.h                     |   45 -
 Utilities/cmcurl/lib/conncache.c                   |  179 +-
 Utilities/cmcurl/lib/conncache.h                   |   21 +-
 Utilities/cmcurl/lib/connect.c                     |  227 +-
 Utilities/cmcurl/lib/connect.h                     |    2 +-
 Utilities/cmcurl/lib/cookie.c                      |  208 +-
 Utilities/cmcurl/lib/curl_addrinfo.c               |   59 +-
 Utilities/cmcurl/lib/curl_addrinfo.h               |    4 +
 Utilities/cmcurl/lib/curl_config.h.cmake           |   12 +-
 Utilities/cmcurl/lib/curl_des.c                    |   63 +
 Utilities/cmcurl/lib/curl_des.h                    |   34 +
 Utilities/cmcurl/lib/curl_endian.c                 |  236 ++
 Utilities/cmcurl/lib/curl_endian.h                 |   70 +
 Utilities/cmcurl/lib/curl_fnmatch.c                |    7 +-
 Utilities/cmcurl/lib/curl_gssapi.c                 |   53 +-
 Utilities/cmcurl/lib/curl_gssapi.h                 |   19 +-
 Utilities/cmcurl/lib/curl_md4.h                    |   12 +-
 Utilities/cmcurl/lib/curl_memory.h                 |    3 +
 Utilities/cmcurl/lib/curl_memrchr.c                |    8 +-
 Utilities/cmcurl/lib/curl_multibyte.c              |   18 +-
 Utilities/cmcurl/lib/curl_multibyte.h              |   12 +-
 Utilities/cmcurl/lib/curl_ntlm.c                   |   79 +-
 Utilities/cmcurl/lib/curl_ntlm.h                   |   10 +-
 Utilities/cmcurl/lib/curl_ntlm_core.c              |  292 +-
 Utilities/cmcurl/lib/curl_ntlm_core.h              |   59 +-
 Utilities/cmcurl/lib/curl_ntlm_msgs.c              |  461 +--
 Utilities/cmcurl/lib/curl_ntlm_msgs.h              |   34 -
 Utilities/cmcurl/lib/curl_ntlm_wb.c                |   46 +-
 Utilities/cmcurl/lib/curl_ntlm_wb.h                |    7 +-
 Utilities/cmcurl/lib/curl_printf.h                 |   56 +
 Utilities/cmcurl/lib/curl_rtmp.c                   |   27 +-
 Utilities/cmcurl/lib/curl_sasl.c                   | 1158 +++++-
 Utilities/cmcurl/lib/curl_sasl.h                   |  164 +-
 Utilities/cmcurl/lib/curl_sasl_gssapi.c            |  392 ++
 Utilities/cmcurl/lib/curl_sasl_sspi.c              |  861 +++-
 Utilities/cmcurl/lib/curl_sec.h                    |    4 +-
 Utilities/cmcurl/lib/curl_setup.h                  |   53 +-
 Utilities/cmcurl/lib/curl_sspi.c                   |   30 +-
 Utilities/cmcurl/lib/curl_sspi.h                   |  191 +-
 Utilities/cmcurl/lib/curl_threads.c                |   15 +-
 Utilities/cmcurl/lib/curl_threads.h                |    9 +-
 Utilities/cmcurl/lib/curlx.h                       |    5 +-
 Utilities/cmcurl/lib/dict.c                        |   16 +-
 Utilities/cmcurl/lib/easy.c                        |  180 +-
 Utilities/cmcurl/lib/escape.c                      |   28 +-
 Utilities/cmcurl/lib/file.c                        |   63 +-
 Utilities/cmcurl/lib/fileinfo.c                    |    6 +-
 Utilities/cmcurl/lib/formdata.c                    |  127 +-
 Utilities/cmcurl/lib/ftp.c                         |  305 +-
 Utilities/cmcurl/lib/ftp.h                         |   11 +-
 Utilities/cmcurl/lib/ftplistparser.c               |   57 +-
 Utilities/cmcurl/lib/getinfo.c                     |   55 +-
 Utilities/cmcurl/lib/gopher.c                      |   16 +-
 Utilities/cmcurl/lib/hash.c                        |   72 +-
 Utilities/cmcurl/lib/hash.h                        |   10 +-
 Utilities/cmcurl/lib/hmac.c                        |    6 +-
 Utilities/cmcurl/lib/hostasyn.c                    |   24 +-
 Utilities/cmcurl/lib/hostcheck.c                   |    7 +-
 Utilities/cmcurl/lib/hostip.c                      |  287 +-
 Utilities/cmcurl/lib/hostip.h                      |   22 +-
 Utilities/cmcurl/lib/hostip4.c                     |   15 +-
 Utilities/cmcurl/lib/hostip6.c                     |   17 +-
 Utilities/cmcurl/lib/hostsyn.c                     |    6 +-
 Utilities/cmcurl/lib/http.c                        |  378 +-
 Utilities/cmcurl/lib/http.h                        |   64 +-
 Utilities/cmcurl/lib/http2.c                       | 1184 ++++--
 Utilities/cmcurl/lib/http2.h                       |   17 +-
 Utilities/cmcurl/lib/http_chunks.c                 |   12 +-
 Utilities/cmcurl/lib/http_digest.c                 |  549 +--
 Utilities/cmcurl/lib/http_digest.h                 |   21 +-
 Utilities/cmcurl/lib/http_negotiate.c              |  163 +-
 Utilities/cmcurl/lib/http_negotiate.h              |    6 +-
 Utilities/cmcurl/lib/http_negotiate_sspi.c         |  118 +-
 Utilities/cmcurl/lib/http_proxy.c                  |   64 +-
 Utilities/cmcurl/lib/http_proxy.h                  |    7 +-
 Utilities/cmcurl/lib/idn_win32.c                   |   29 +-
 Utilities/cmcurl/lib/if2ip.c                       |   87 +-
 Utilities/cmcurl/lib/if2ip.h                       |   13 +-
 Utilities/cmcurl/lib/imap.c                        |  989 +----
 Utilities/cmcurl/lib/imap.h                        |   23 +-
 Utilities/cmcurl/lib/inet_ntop.c                   |    3 +-
 Utilities/cmcurl/lib/inet_ntop.h                   |    4 +-
 Utilities/cmcurl/lib/krb5.c                        |   36 +-
 Utilities/cmcurl/lib/ldap.c                        |  622 ++-
 Utilities/cmcurl/lib/md4.c                         |  502 +--
 Utilities/cmcurl/lib/md5.c                         |  579 +--
 Utilities/cmcurl/lib/memdebug.c                    |   39 +-
 Utilities/cmcurl/lib/memdebug.h                    |   20 +-
 Utilities/cmcurl/lib/multi.c                       |  819 ++--
 Utilities/cmcurl/lib/multihandle.h                 |   52 +-
 Utilities/cmcurl/lib/multiif.h                     |   22 +-
 Utilities/cmcurl/lib/netrc.c                       |   20 +-
 Utilities/cmcurl/lib/non-ascii.c                   |   55 +-
 Utilities/cmcurl/lib/nwlib.c                       |    8 +-
 Utilities/cmcurl/lib/openldap.c                    |  142 +-
 Utilities/cmcurl/lib/parsedate.c                   |    2 +-
 Utilities/cmcurl/lib/pingpong.c                    |   56 +-
 Utilities/cmcurl/lib/pipeline.c                    |  119 +-
 Utilities/cmcurl/lib/pipeline.h                    |   12 +
 Utilities/cmcurl/lib/pop3.c                        |  972 +----
 Utilities/cmcurl/lib/pop3.h                        |   23 +-
 Utilities/cmcurl/lib/progress.c                    |    6 +-
 Utilities/cmcurl/lib/rtsp.c                        |   24 +-
 Utilities/cmcurl/lib/security.c                    |  187 +-
 Utilities/cmcurl/lib/select.c                      |   12 +-
 Utilities/cmcurl/lib/sendf.c                       |  218 +-
 Utilities/cmcurl/lib/sendf.h                       |    6 +-
 Utilities/cmcurl/lib/setup-os400.h                 |   18 +-
 Utilities/cmcurl/lib/setup-vms.h                   |   47 +-
 Utilities/cmcurl/lib/share.c                       |   27 +-
 Utilities/cmcurl/lib/share.h                       |    4 +-
 Utilities/cmcurl/lib/slist.c                       |    4 +-
 Utilities/cmcurl/lib/smb.c                         |  976 +++++
 Utilities/cmcurl/lib/smb.h                         |  271 ++
 Utilities/cmcurl/lib/smtp.c                        | 1019 +----
 Utilities/cmcurl/lib/smtp.h                        |   23 +-
 Utilities/cmcurl/lib/socks.c                       |   42 +-
 Utilities/cmcurl/lib/socks_gssapi.c                |   80 +-
 Utilities/cmcurl/lib/socks_sspi.c                  |   59 +-
 Utilities/cmcurl/lib/splay.c                       |   10 +-
 Utilities/cmcurl/lib/ssh.c                         |  160 +-
 Utilities/cmcurl/lib/ssh.h                         |   36 +-
 Utilities/cmcurl/lib/strdup.c                      |   33 +-
 Utilities/cmcurl/lib/strdup.h                      |    3 +-
 Utilities/cmcurl/lib/strerror.c                    |   38 +-
 Utilities/cmcurl/lib/strtoofft.h                   |   11 +-
 Utilities/cmcurl/lib/telnet.c                      |  165 +-
 Utilities/cmcurl/lib/tftp.c                        |  163 +-
 Utilities/cmcurl/lib/timeval.c                     |   12 +-
 Utilities/cmcurl/lib/transfer.c                    |  145 +-
 Utilities/cmcurl/lib/transfer.h                    |    5 +-
 Utilities/cmcurl/lib/url.c                         |  744 ++--
 Utilities/cmcurl/lib/url.h                         |    6 +-
 Utilities/cmcurl/lib/urldata.h                     |  162 +-
 Utilities/cmcurl/lib/version.c                     |   23 +-
 Utilities/cmcurl/lib/vtls/axtls.c                  |   34 +-
 Utilities/cmcurl/lib/vtls/axtls.h                  |   23 +-
 Utilities/cmcurl/lib/vtls/curl_darwinssl.c         | 2485 ------------
 Utilities/cmcurl/lib/vtls/curl_darwinssl.h         |   77 -
 Utilities/cmcurl/lib/vtls/curl_schannel.c          | 1346 -------
 Utilities/cmcurl/lib/vtls/curl_schannel.h          |  137 -
 Utilities/cmcurl/lib/vtls/cyassl.c                 |  273 +-
 Utilities/cmcurl/lib/vtls/cyassl.h                 |   30 +-
 Utilities/cmcurl/lib/vtls/darwinssl.c              | 2484 ++++++++++++
 Utilities/cmcurl/lib/vtls/darwinssl.h              |   76 +
 Utilities/cmcurl/lib/vtls/gskit.c                  |  326 +-
 Utilities/cmcurl/lib/vtls/gskit.h                  |   26 +-
 Utilities/cmcurl/lib/vtls/gtls.c                   |  398 +-
 Utilities/cmcurl/lib/vtls/gtls.h                   |   37 +-
 Utilities/cmcurl/lib/vtls/nss.c                    |  599 +--
 Utilities/cmcurl/lib/vtls/nssg.h                   |   41 +-
 Utilities/cmcurl/lib/vtls/openssl.c                | 1091 +++--
 Utilities/cmcurl/lib/vtls/openssl.h                |   35 +-
 Utilities/cmcurl/lib/vtls/polarssl.c               |  197 +-
 Utilities/cmcurl/lib/vtls/polarssl.h               |   26 +-
 Utilities/cmcurl/lib/vtls/polarssl_threadlock.c    |    5 +-
 Utilities/cmcurl/lib/vtls/qssl.c                   |  527 ---
 Utilities/cmcurl/lib/vtls/qssl.h                   |   62 -
 Utilities/cmcurl/lib/vtls/schannel.c               | 1501 +++++++
 Utilities/cmcurl/lib/vtls/schannel.h               |  118 +
 Utilities/cmcurl/lib/vtls/vtls.c                   |  355 +-
 Utilities/cmcurl/lib/vtls/vtls.h                   |   55 +-
 Utilities/cmcurl/lib/wildcard.c                    |   20 +-
 Utilities/cmcurl/lib/x509asn1.c                    |   55 +-
 Utilities/cmcurl/lib/x509asn1.h                    |   11 +-
 Utilities/cmjsoncpp/src/lib_json/json_reader.cpp   |    2 +-
 Utilities/cmjsoncpp/src/lib_json/json_writer.cpp   |    4 +-
 bootstrap                                          |  279 +-
 1643 files changed, 53311 insertions(+), 39770 deletions(-)

diff --git a/Auxiliary/cmake-indent.vim b/Auxiliary/cmake-indent.vim
index 6cee9c8..fa088e4 100644
--- a/Auxiliary/cmake-indent.vim
+++ b/Auxiliary/cmake-indent.vim
@@ -16,7 +16,7 @@
 " Version:      $Revision$
 "
 " Licence:      The CMake license applies to this file. See
-"               http://www.cmake.org/licensing
+"               https://cmake.org/licensing
 "               This implies that distribution with Vim is allowed
 
 if exists("b:did_indent")
diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el
index 7458a66..e50ae7b 100644
--- a/Auxiliary/cmake-mode.el
+++ b/Auxiliary/cmake-mode.el
@@ -43,7 +43,14 @@ set the path with these commands:
  (setenv \"PATH\" (concat (getenv \"PATH\") \":/usr/local/cmake/bin\"))"
   :type 'file
   :group 'cmake)
-;;
+
+;; Keywords
+(defconst cmake-keywords-block-open '("IF" "MACRO" "FOREACH" "ELSE" "ELSEIF" "WHILE" "FUNCTION"))
+(defconst cmake-keywords-block-close '("ENDIF" "ENDFOREACH" "ENDMACRO" "ELSE" "ELSEIF" "ENDWHILE" "ENDFUNCTION"))
+(defconst cmake-keywords
+  (let ((kwds (append cmake-keywords-block-open cmake-keywords-block-close nil)))
+    (delete-dups kwds)))
+
 ;; Regular expressions used by line indentation function.
 ;;
 (defconst cmake-regex-blank "^[ \t]*$")
@@ -51,40 +58,39 @@ set the path with these commands:
 (defconst cmake-regex-paren-left "(")
 (defconst cmake-regex-paren-right ")")
 (defconst cmake-regex-argument-quoted
-  "\"\\([^\"\\\\]\\|\\\\\\(.\\|\n\\)\\)*\"")
+  (rx ?\" (* (or (not (any ?\" ?\\)) (and ?\\ anything))) ?\"))
 (defconst cmake-regex-argument-unquoted
-  "\\([^ \t\r\n()#\"\\\\]\\|\\\\.\\)\\([^ \t\r\n()#\\\\]\\|\\\\.\\)*")
-(defconst cmake-regex-token (concat "\\(" cmake-regex-comment
-                                    "\\|" cmake-regex-paren-left
-                                    "\\|" cmake-regex-paren-right
-                                    "\\|" cmake-regex-argument-unquoted
-                                    "\\|" cmake-regex-argument-quoted
-                                    "\\)"))
-(defconst cmake-regex-indented (concat "^\\("
-                                       cmake-regex-token
-                                       "\\|" "[ \t\r\n]"
-                                       "\\)*"))
+  (rx (or (not (any space "()#\"\\\n")) (and ?\\ nonl))
+      (* (or (not (any space "()#\\\n")) (and ?\\ nonl)))))
+(defconst cmake-regex-token
+  (rx-to-string `(group (or (regexp ,cmake-regex-comment)
+                            ?( ?)
+                            (regexp ,cmake-regex-argument-unquoted)
+                            (regexp ,cmake-regex-argument-quoted)))))
+(defconst cmake-regex-indented
+  (rx-to-string `(and bol (* (group (or (regexp ,cmake-regex-token) (any space ?\n)))))))
 (defconst cmake-regex-block-open
-  "^\\(if\\|macro\\|foreach\\|else\\|elseif\\|while\\|function\\)$")
+  (rx-to-string `(and symbol-start (or ,@(append cmake-keywords-block-open
+                                        (mapcar 'downcase cmake-keywords-block-open))) symbol-end)))
 (defconst cmake-regex-block-close
-  "^[ \t]*\\(endif\\|endforeach\\|endmacro\\|else\\|elseif\\|endwhile\\|endfunction\\)[ \t]*(")
+  (rx-to-string `(and symbol-start (or ,@(append cmake-keywords-block-close
+                                        (mapcar 'downcase cmake-keywords-block-close))) symbol-end)))
+(defconst cmake-regex-close
+  (rx-to-string `(and bol (* space) (regexp ,cmake-regex-block-close)
+                      (* space) (regexp ,cmake-regex-paren-left))))
 
 ;------------------------------------------------------------------------------
 
-;;
-;; Helper functions for line indentation function.
-;;
+;; Line indentation helper functions
+
 (defun cmake-line-starts-inside-string ()
   "Determine whether the beginning of the current line is in a string."
-  (if (save-excursion
-        (beginning-of-line)
-        (let ((parse-end (point)))
-          (goto-char (point-min))
-          (nth 3 (parse-partial-sexp (point) parse-end))
-          )
-        )
-      t
-    nil
+  (save-excursion
+    (beginning-of-line)
+    (let ((parse-end (point)))
+      (goto-char (point-min))
+      (nth 3 (parse-partial-sexp (point) parse-end))
+      )
     )
   )
 
@@ -111,57 +117,40 @@ set the path with these commands:
 ;; Line indentation function.
 ;;
 (defun cmake-indent ()
-  "Indent current line as CMAKE code."
+  "Indent current line as CMake code."
   (interactive)
-  (if (cmake-line-starts-inside-string)
-      ()
+  (unless (cmake-line-starts-inside-string)
     (if (bobp)
         (cmake-indent-line-to 0)
       (let (cur-indent)
-
         (save-excursion
           (beginning-of-line)
-
           (let ((point-start (point))
                 (case-fold-search t)  ;; case-insensitive
                 token)
-
             ; Search back for the last indented line.
             (cmake-find-last-indented-line)
-
             ; Start with the indentation on this line.
             (setq cur-indent (current-indentation))
-
             ; Search forward counting tokens that adjust indentation.
             (while (re-search-forward cmake-regex-token point-start t)
               (setq token (match-string 0))
-              (if (string-match (concat "^" cmake-regex-paren-left "$") token)
-                  (setq cur-indent (+ cur-indent cmake-tab-width))
-                )
-              (if (string-match (concat "^" cmake-regex-paren-right "$") token)
-                  (setq cur-indent (- cur-indent cmake-tab-width))
-                )
-              (if (and
-                   (string-match cmake-regex-block-open token)
-                   (looking-at (concat "[ \t]*" cmake-regex-paren-left))
-                   )
-                  (setq cur-indent (+ cur-indent cmake-tab-width))
-                )
+              (when (or (string-match (concat "^" cmake-regex-paren-left "$") token)
+                        (and (string-match cmake-regex-block-open token)
+                             (looking-at (concat "[ \t]*" cmake-regex-paren-left))))
+                (setq cur-indent (+ cur-indent cmake-tab-width)))
+              (when (string-match (concat "^" cmake-regex-paren-right "$") token)
+                (setq cur-indent (- cur-indent cmake-tab-width)))
               )
             (goto-char point-start)
-
-            ; If this is the end of a block, decrease indentation.
-            (if (looking-at cmake-regex-block-close)
-                (setq cur-indent (- cur-indent cmake-tab-width))
+            ;; If next token closes the block, decrease indentation
+            (when (looking-at cmake-regex-close)
+              (setq cur-indent (- cur-indent cmake-tab-width))
               )
             )
           )
-
         ; Indent this line by the amount selected.
-        (if (< cur-indent 0)
-            (cmake-indent-line-to 0)
-          (cmake-indent-line-to cur-indent)
-          )
+        (cmake-indent-line-to (max cur-indent 0))
         )
       )
     )
@@ -183,17 +172,19 @@ the indentation.  Otherwise it retains the same position on the line"
 ;;
 ;; Helper functions for buffer
 ;;
-(defun unscreamify-cmake-buffer ()
+(defun cmake-unscreamify-buffer ()
   "Convert all CMake commands to lowercase in buffer."
   (interactive)
-  (goto-char (point-min))
-  (while (re-search-forward "^\\([ \t]*\\)\\(\\w+\\)\\([ \t]*(\\)" nil t)
-    (replace-match
-     (concat
-      (match-string 1)
-      (downcase (match-string 2))
-      (match-string 3))
-     t))
+  (save-excursion
+    (goto-char (point-min))
+    (while (re-search-forward "^\\([ \t]*\\)\\(\\w+\\)\\([ \t]*(\\)" nil t)
+      (replace-match
+       (concat
+        (match-string 1)
+        (downcase (match-string 2))
+        (match-string 3))
+       t))
+    )
   )
 
 ;------------------------------------------------------------------------------
@@ -202,18 +193,32 @@ the indentation.  Otherwise it retains the same position on the line"
 ;; Keyword highlighting regex-to-face map.
 ;;
 (defconst cmake-font-lock-keywords
-  (list '("^[ \t]*\\([[:word:]_]+\\)[ \t]*(" 1 font-lock-function-name-face))
-  "Highlighting expressions for CMAKE mode."
-  )
+  `((,(rx-to-string `(and symbol-start
+                          (or , at cmake-keywords
+                              ,@(mapcar #'downcase cmake-keywords))
+                          symbol-end))
+     . font-lock-keyword-face)
+    (,(rx symbol-start (group (+ (or word (syntax symbol)))) (* blank) ?\()
+     1 font-lock-function-name-face)
+    (,(rx "${" (group (+(any alnum "-_+/."))) "}")
+     1 font-lock-variable-name-face t)
+    )
+  "Highlighting expressions for CMake mode.")
 
 ;------------------------------------------------------------------------------
 
-;;
-;; Syntax table for this mode.  Initialize to nil so that it is
-;; regenerated when the cmake-mode function is called.
-;;
-(defvar cmake-mode-syntax-table nil "Syntax table for cmake-mode.")
-(setq cmake-mode-syntax-table nil)
+;; Syntax table for this mode.
+(defvar cmake-mode-syntax-table nil
+  "Syntax table for CMake mode.")
+(or cmake-mode-syntax-table
+    (setq cmake-mode-syntax-table
+          (let ((table (make-syntax-table)))
+            (modify-syntax-entry ?\(  "()" table)
+            (modify-syntax-entry ?\)  ")(" table)
+            (modify-syntax-entry ?# "<" table)
+            (modify-syntax-entry ?\n ">" table)
+            (modify-syntax-entry ?$ "'" table)
+            table)))
 
 ;;
 ;; User hook entry point.
@@ -227,39 +232,23 @@ the indentation.  Otherwise it retains the same position on the line"
 
 ;------------------------------------------------------------------------------
 
-;;
-;; CMake mode startup function.
+;; For compatibility with Emacs < 24
+(defalias 'cmake--parent-mode
+  (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
+
+;;------------------------------------------------------------------------------
+;; Mode definition.
 ;;
 ;;;###autoload
-(defun cmake-mode ()
-  "Major mode for editing CMake listfiles."
-  (interactive)
-  (kill-all-local-variables)
-  (setq major-mode 'cmake-mode)
-  (setq mode-name "CMAKE")
-
-  ; Create the syntax table
-  (setq cmake-mode-syntax-table (make-syntax-table))
-  (set-syntax-table cmake-mode-syntax-table)
-  (modify-syntax-entry ?\(  "()" cmake-mode-syntax-table)
-  (modify-syntax-entry ?\)  ")(" cmake-mode-syntax-table)
-  (modify-syntax-entry ?# "<" cmake-mode-syntax-table)
-  (modify-syntax-entry ?\n ">" cmake-mode-syntax-table)
+(define-derived-mode cmake-mode cmake--parent-mode "CMake"
+  "Major mode for editing CMake source files."
 
   ; Setup font-lock mode.
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults '(cmake-font-lock-keywords))
-
+  (set (make-local-variable 'font-lock-defaults) '(cmake-font-lock-keywords))
   ; Setup indentation function.
-  (make-local-variable 'indent-line-function)
-  (setq indent-line-function 'cmake-indent)
-
+  (set (make-local-variable 'indent-line-function) 'cmake-indent)
   ; Setup comment syntax.
-  (make-local-variable 'comment-start)
-  (setq comment-start "#")
-
-  ; Run user hooks.
-  (run-hooks 'cmake-mode-hook))
+  (set (make-local-variable 'comment-start) "#"))
 
 ; Help mode starts here
 
diff --git a/Auxiliary/cmake-syntax.vim b/Auxiliary/cmake-syntax.vim
index 3e4a122..624a8c4 100644
--- a/Auxiliary/cmake-syntax.vim
+++ b/Auxiliary/cmake-syntax.vim
@@ -16,7 +16,7 @@
 " Version:      $Revision$
 "
 " Licence:      The CMake license applies to this file. See
-"               http://www.cmake.org/licensing
+"               https://cmake.org/licensing
 "               This implies that distribution with Vim is allowed
 
 " For version 5.x: Clear all syntax items
diff --git a/CMakeCPack.cmake b/CMakeCPack.cmake
index 22ca8cf..a0aadcc 100644
--- a/CMakeCPack.cmake
+++ b/CMakeCPack.cmake
@@ -22,7 +22,9 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
       set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
     endif()
 
-    include(${CMake_SOURCE_DIR}/Modules/InstallRequiredSystemLibraries.cmake)
+    if(CMake_INSTALL_DEPENDENCIES)
+      include(${CMake_SOURCE_DIR}/Modules/InstallRequiredSystemLibraries.cmake)
+    endif()
   endif()
 
   set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CMake is a build tool")
@@ -65,6 +67,61 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
     endif()
   endif()
 
+  # Components
+  if(CMake_INSTALL_COMPONENTS)
+    set(_CPACK_IFW_COMPONENTS_ALL cmake ctest cpack)
+    if(APPLE)
+      list(APPEND _CPACK_IFW_COMPONENTS_ALL cmakexbuild)
+    endif()
+    if(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+      set(_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME
+        ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME})
+    else()
+      set(_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME Unspecified)
+    endif()
+    list(APPEND _CPACK_IFW_COMPONENTS_ALL ${_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME})
+    string(TOUPPER "${_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME}"
+      _CPACK_IFW_COMPONENT_UNSPECIFIED_UNAME)
+    if(BUILD_CursesDialog)
+      list(APPEND _CPACK_IFW_COMPONENTS_ALL ccmake)
+    endif()
+    if(BUILD_QtDialog)
+      list(APPEND _CPACK_IFW_COMPONENTS_ALL cmake-gui)
+      set(_CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES "set(CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES
+    \"LGPLv2.1\" \"${CMake_SOURCE_DIR}/Licenses/LGPLv2.1.txt\")")
+    endif()
+    if(SPHINX_MAN)
+      list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-man)
+    endif()
+    if(SPHINX_HTML)
+      list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-html)
+    endif()
+    if(SPHINX_SINGLEHTML)
+      list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-singlehtml)
+    endif()
+    if(SPHINX_QTHELP)
+      list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-qthelp)
+    endif()
+    set(_CPACK_IFW_COMPONENTS_CONFIGURATION "
+  # Components
+  set(CPACK_COMPONENTS_ALL \"${_CPACK_IFW_COMPONENTS_ALL}\")
+  set(CPACK_COMPONENTS_GROUPING IGNORE)
+")
+  else()
+    if(BUILD_QtDialog AND CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL)
+      set(_CPACK_IFW_ADDITIONAL_LICENSES
+        "\"LGPLv2.1\" \"${CMake_SOURCE_DIR}/Licenses/LGPLv2.1.txt\"")
+    endif()
+  endif()
+
+  # Components scripts configuration
+  foreach(_script
+    CMake
+    CMake.Documentation.SphinxHTML)
+    configure_file("${CMake_SOURCE_DIR}/Source/QtIFW/${_script}.qs.in"
+      "${CMake_BINARY_DIR}/${_script}.qs" @ONLY)
+  endforeach()
+
   if(${CMAKE_SYSTEM_NAME} MATCHES Windows)
     set(_CPACK_IFW_PACKAGE_ICON
         "set(CPACK_IFW_PACKAGE_ICON \"${CMake_SOURCE_DIR}/Source/QtDialog/CMakeSetup.ico\")")
@@ -78,9 +135,13 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
       "${CMake_BINARY_DIR}/installscript.qs" @ONLY
     )
     install(FILES "${CMake_SOURCE_DIR}/Source/QtIFW/cmake.org.html"
-      DESTINATION "."
+      DESTINATION "${CMAKE_DOC_DIR}"
     )
-    set(_CPACK_IFW_PACKAGE_SCRIPT "set(CPACK_IFW_COMPONENT_GROUP_CMAKE_SCRIPT \"${CMake_BINARY_DIR}/installscript.qs\")")
+    if(CMake_INSTALL_COMPONENTS)
+      set(_CPACK_IFW_PACKAGE_SCRIPT "${CMake_BINARY_DIR}/CMake.qs")
+    else()
+      set(_CPACK_IFW_PACKAGE_SCRIPT "${CMake_BINARY_DIR}/installscript.qs")
+    endif()
   endif()
 
   if(${CMAKE_SYSTEM_NAME} MATCHES Linux)
diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in
index 6003565..b6013ef 100644
--- a/CMakeCPackOptions.cmake.in
+++ b/CMakeCPackOptions.cmake.in
@@ -14,14 +14,14 @@ if(CPACK_GENERATOR MATCHES "NSIS")
   # tell cpack to create links to the doc files
   set(CPACK_NSIS_MENU_LINKS
     "@CMAKE_DOC_DIR@/html/index.html" "CMake Documentation"
-    "http://www.cmake.org" "CMake Web Site"
+    "https://cmake.org" "CMake Web Site"
     )
   # Use the icon from cmake-gui for add-remove programs
   set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\cmake-gui.exe")
 
   set(CPACK_NSIS_PACKAGE_NAME "@CPACK_NSIS_PACKAGE_NAME@")
   set(CPACK_NSIS_DISPLAY_NAME "@CPACK_NSIS_PACKAGE_NAME@, a cross-platform, open-source build system")
-  set(CPACK_NSIS_HELP_LINK "http://www.cmake.org")
+  set(CPACK_NSIS_HELP_LINK "https://cmake.org")
   set(CPACK_NSIS_URL_INFO_ABOUT "http://www.kitware.com")
   set(CPACK_NSIS_CONTACT @CPACK_PACKAGE_CONTACT@)
   set(CPACK_NSIS_MODIFY_PATH ON)
@@ -32,29 +32,141 @@ endif()
 include("@QT_DIALOG_CPACK_OPTIONS_FILE@" OPTIONAL)
 
 if(CPACK_GENERATOR MATCHES "IFW")
+
   # Installer configuration
   set(CPACK_IFW_PACKAGE_TITLE "CMake Build Tool")
-  set(CPACK_IFW_PRODUCT_URL "http://www.cmake.org")
+  set(CPACK_IFW_PRODUCT_URL "https://cmake.org")
   @_CPACK_IFW_PACKAGE_ICON@
   set(CPACK_IFW_PACKAGE_WINDOW_ICON
     "@CMake_SOURCE_DIR@/Source/QtDialog/CMakeSetup128.png")
   set(CPACK_IFW_PACKAGE_CONTROL_SCRIPT
     "@CMake_SOURCE_DIR@/Source/QtIFW/controlscript.qs")
+
   # Uninstaller configuration
   set(CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME "cmake-maintenance")
+  @_CPACK_IFW_COMPONENTS_CONFIGURATION@
+  # Unspecified
+  set(CPACK_IFW_COMPONENT_ at _CPACK_IFW_COMPONENT_UNSPECIFIED_UNAME@_VERSION
+    "@_CPACK_IFW_PACKAGE_VERSION@")
+
   # Package configuration group
   set(CPACK_IFW_PACKAGE_GROUP CMake)
+
   # Group configuration
+
+  # CMake
   set(CPACK_COMPONENT_GROUP_CMAKE_DISPLAY_NAME
     "@CPACK_PACKAGE_NAME@")
   set(CPACK_COMPONENT_GROUP_CMAKE_DESCRIPTION
     "@CPACK_PACKAGE_DESCRIPTION_SUMMARY@")
-  # IFW group configuration
   set(CPACK_IFW_COMPONENT_GROUP_CMAKE_VERSION
     "@_CPACK_IFW_PACKAGE_VERSION@")
   set(CPACK_IFW_COMPONENT_GROUP_CMAKE_LICENSES
-    "@CPACK_PACKAGE_NAME@ Copyright" "@CPACK_RESOURCE_FILE_LICENSE@")
-  @_CPACK_IFW_PACKAGE_SCRIPT@
+    "@CPACK_PACKAGE_NAME@ Copyright" "@CPACK_RESOURCE_FILE_LICENSE@"
+    @_CPACK_IFW_ADDITIONAL_LICENSES@)
+  set(CPACK_IFW_COMPONENT_GROUP_CMAKE_SCRIPT "@_CPACK_IFW_PACKAGE_SCRIPT@")
+  set(CPACK_IFW_COMPONENT_GROUP_CMAKE_PRIORITY 100)
+
+  # Tools
+  set(CPACK_COMPONENT_GROUP_TOOLS_DISPLAY_NAME "Command-Line Tools")
+  set(CPACK_COMPONENT_GROUP_TOOLS_DESCRIPTION
+    "Command-Line Tools: cmake, ctest and cpack")
+  set(CPACK_COMPONENT_GROUP_TOOLS_PARENT_GROUP CMake)
+  set(CPACK_IFW_COMPONENT_GROUP_TOOLS_PRIORITY 90)
+  set(CPACK_IFW_COMPONENT_GROUP_TOOLS_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  set(CPACK_COMPONENT_CMAKE_DISPLAY_NAME "cmake")
+  set(CPACK_COMPONENT_CMAKE_DESCRIPTION
+    "The \"cmake\" executable is the CMake command-line interface")
+  set(CPACK_COMPONENT_CMAKE_REQUIRED TRUE)
+  set(CPACK_COMPONENT_CMAKE_GROUP Tools)
+  set(CPACK_IFW_COMPONENT_CMAKE_NAME "CMake")
+  set(CPACK_IFW_COMPONENT_CMAKE_PRIORITY 89)
+  set(CPACK_IFW_COMPONENT_CMAKE_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  set(CPACK_COMPONENT_CTEST_DISPLAY_NAME "ctest")
+  set(CPACK_COMPONENT_CTEST_DESCRIPTION
+    "The \"ctest\" executable is the CMake test driver program")
+  set(CPACK_COMPONENT_CTEST_REQUIRED TRUE)
+  set(CPACK_COMPONENT_CTEST_GROUP Tools)
+  set(CPACK_IFW_COMPONENT_CTEST_NAME "CTest")
+  set(CPACK_IFW_COMPONENT_CTEST_PRIORITY 88)
+  set(CPACK_IFW_COMPONENT_CTEST_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  set(CPACK_COMPONENT_CPACK_DISPLAY_NAME "cpack")
+  set(CPACK_COMPONENT_CPACK_DESCRIPTION
+    "The \"cpack\" executable is the CMake packaging program")
+  set(CPACK_COMPONENT_CPACK_REQUIRED TRUE)
+  set(CPACK_COMPONENT_CPACK_GROUP Tools)
+  set(CPACK_IFW_COMPONENT_CPACK_NAME "CPack")
+  set(CPACK_IFW_COMPONENT_CPACK_PRIORITY 87)
+  set(CPACK_IFW_COMPONENT_CPACK_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  set(CPACK_COMPONENT_CMAKEXBUILD_DISPLAY_NAME "cmakexbuild")
+  set(CPACK_COMPONENT_CMAKEXBUILD_DESCRIPTION
+    "The \"cmakexbuild\" executable is a wrapper program for \"xcodebuild\"")
+  set(CPACK_COMPONENT_CMAKEXBUILD_REQUIRED TRUE)
+  set(CPACK_COMPONENT_CMAKEXBUILD_GROUP Tools)
+  set(CPACK_IFW_COMPONENT_CMAKEXBUILD_NAME "CMakeXBuild")
+  set(CPACK_IFW_COMPONENT_CMAKEXBUILD_PRIORITY 86)
+  set(CPACK_IFW_COMPONENT_CMAKEXBUILD_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  # Dialogs
+  set(CPACK_COMPONENT_GROUP_DIALOGS_DISPLAY_NAME "Interactive Dialogs")
+  set(CPACK_COMPONENT_GROUP_DIALOGS_DESCRIPTION
+    "Interactive Dialogs with Console and GUI interfaces")
+  set(CPACK_COMPONENT_GROUP_DIALOGS_PARENT_GROUP CMake)
+  set(CPACK_IFW_COMPONENT_GROUP_DIALOGS_PRIORITY 80)
+  set(CPACK_IFW_COMPONENT_GROUP_DIALOGS_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  set(CPACK_COMPONENT_CMAKE-GUI_DISPLAY_NAME "cmake-gui")
+  set(CPACK_COMPONENT_CMAKE-GUI_GROUP Dialogs)
+  set(CPACK_IFW_COMPONENT_CMAKE-GUI_NAME "QtGUI")
+  set(CPACK_IFW_COMPONENT_CMAKE-GUI_SCRIPT
+    "@CMake_SOURCE_DIR@/Source/QtIFW/CMake.Dialogs.QtGUI.qs")
+  set(CPACK_IFW_COMPONENT_CMAKE-GUI_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+  @_CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES@
+
+  set(CPACK_COMPONENT_CCMAKE_DISPLAY_NAME "ccmake")
+  set(CPACK_COMPONENT_CCMAKE_GROUP Dialogs)
+  set(CPACK_IFW_COMPONENT_CCMAKE_NAME "CursesGUI")
+  set(CPACK_IFW_COMPONENT_CCMAKE_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  # Documentation
+  set(CPACK_COMPONENT_GROUP_DOCUMENTATION_DISPLAY_NAME "Documentation")
+  set(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
+    "CMake Documentation in different formats (html, man, qch)")
+  set(CPACK_COMPONENT_GROUP_DOCUMENTATION_PARENT_GROUP CMake)
+  set(CPACK_IFW_COMPONENT_GROUP_DOCUMENTATION_PRIORITY 60)
+  set(CPACK_IFW_COMPONENT_GROUP_DOCUMENTATION_VERSION
+    "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  set(CPACK_COMPONENT_SPHINX-MAN_DISPLAY_NAME "man")
+  set(CPACK_COMPONENT_SPHINX-MAN_GROUP Documentation)
+  set(CPACK_COMPONENT_SPHINX-MAN_DISABLED TRUE)
+  set(CPACK_IFW_COMPONENT_SPHINX-MAN_NAME "SphinxMan")
+  set(CPACK_IFW_COMPONENT_SPHINX-MAN_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  set(CPACK_COMPONENT_SPHINX-HTML_DISPLAY_NAME "HTML")
+  set(CPACK_COMPONENT_SPHINX-HTML_GROUP Documentation)
+  set(CPACK_IFW_COMPONENT_SPHINX-HTML_NAME "SphinxHTML")
+  set(CPACK_IFW_COMPONENT_SPHINX-HTML_SCRIPT
+    "@CMake_BINARY_DIR@/CMake.Documentation.SphinxHTML.qs")
+  set(CPACK_IFW_COMPONENT_SPHINX-HTML_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  set(CPACK_COMPONENT_SPHINX-SINGLEHTML_DISPLAY_NAME "Single HTML")
+  set(CPACK_COMPONENT_SPHINX-SINGLEHTML_GROUP Documentation)
+  set(CPACK_COMPONENT_SPHINX-SINGLEHTML_DISABLED TRUE)
+  set(CPACK_IFW_COMPONENT_SPHINX-SINGLEHTML_NAME "SphinxSingleHTML")
+  set(CPACK_IFW_COMPONENT_SPHINX-SINGLEHTML_VERSION
+    "@_CPACK_IFW_PACKAGE_VERSION@")
+
+  set(CPACK_COMPONENT_SPHINX-QTHELP_DISPLAY_NAME "Qt Compressed Help")
+  set(CPACK_COMPONENT_SPHINX-QTHELP_GROUP Documentation)
+  set(CPACK_COMPONENT_SPHINX-QTHELP_DISABLED TRUE)
+  set(CPACK_IFW_COMPONENT_SPHINX-QTHELP_NAME "SphinxQtHelp")
+  set(CPACK_IFW_COMPONENT_SPHINX-QTHELP_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
 endif()
 
 if(CPACK_GENERATOR MATCHES "CygwinSource")
@@ -92,7 +204,7 @@ if("${CPACK_GENERATOR}" STREQUAL "WIX")
     set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.${patch}")
   endif()
 
-  set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "http://www.cmake.org")
+  set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "https://cmake.org")
 
   set(CPACK_WIX_PROPERTY_ARPCONTACT "@CPACK_PACKAGE_CONTACT@")
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1b91ab8..c96f68b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,9 @@ cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
 if(POLICY CMP0025)
   cmake_policy(SET CMP0025 NEW)
 endif()
+if(POLICY CMP0053)
+  cmake_policy(SET CMP0053 NEW)
+endif()
 project(CMake)
 
 if(CMAKE_BOOTSTRAP)
@@ -38,7 +41,12 @@ endif()
 
 # Use most-recent available language dialects with GNU and Clang
 if(NOT DEFINED CMAKE_C_STANDARD AND NOT CMake_NO_C_STANDARD)
-  set(CMAKE_C_STANDARD 11)
+  include(${CMake_SOURCE_DIR}/Source/Checks/cm_c11_thread_local.cmake)
+  if(NOT CMake_C11_THREAD_LOCAL_BROKEN)
+    set(CMAKE_C_STANDARD 11)
+  else()
+    set(CMAKE_C_STANDARD 99)
+  endif()
 endif()
 if(NOT DEFINED CMAKE_CXX_STANDARD AND NOT CMake_NO_CXX_STANDARD)
   include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx14_cstdio.cmake)
@@ -59,6 +67,22 @@ if(CMAKE_ENCODING_UTF8)
   set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_UTF8)
 endif()
 
+# option to use COMPONENT with install command
+option(CMake_INSTALL_COMPONENTS "Using components when installing" OFF)
+mark_as_advanced(CMake_INSTALL_COMPONENTS)
+macro(CMake_OPTIONAL_COMPONENT NAME)
+  if(CMake_INSTALL_COMPONENTS)
+    set(COMPONENT COMPONENT ${NAME})
+  else()
+    set(COMPONENT)
+  endif()
+endmacro()
+
+# option to disable installing 3rd-party dependencies
+option(CMake_INSTALL_DEPENDENCIES
+  "Whether to install 3rd-party runtime dependencies" OFF)
+mark_as_advanced(CMake_INSTALL_DEPENDENCIES)
+
 #-----------------------------------------------------------------------
 # a macro to deal with system libraries, implemented as a macro
 # simply to improve readability of the main script
@@ -128,17 +152,6 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
 
 endmacro()
 
-
-
-
-if(NOT CMake_TEST_EXTERNAL_CMAKE)
-  set(CMAKE_BUILD_ON_VISUAL_STUDIO 0)
-  if(WIN32 AND NOT UNIX AND NOT MINGW)
-    set(CMAKE_BUILD_ON_VISUAL_STUDIO 1)
-  endif()
-endif()
-
-
 #-----------------------------------------------------------------------
 # a macro to determine the generator and ctest executable to use
 # for testing. Simply to improve readability of the main script.
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 3499da8..0e5c7e1 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -14,7 +14,7 @@ Please subscribe and post to the `CMake Developers List`_ to offer
 contributions.  Regular and productive contributors may be invited
 to gain direct push access.
 
-.. _`CMake Developers List`: http://www.cmake.org/mailman/listinfo/cmake-developers
+.. _`CMake Developers List`: https://cmake.org/mailman/listinfo/cmake-developers
 
 Patches
 =======
@@ -28,7 +28,7 @@ License
 
 We do not require any formal copyright assignment or contributor license
 agreement.  Any contributions intentionally sent upstream are presumed
-to be offerred under terms of the OSI-approved BSD 3-clause License.
+to be offered under terms of the OSI-approved BSD 3-clause License.
 See `Copyright.txt`_ for details.
 
 .. _`Copyright.txt`: Copyright.txt
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 7f20d10..2adf317 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -1,9 +1,7 @@
-set(CTEST_CUSTOM_ERROR_MATCH
-  ${CTEST_CUSTOM_ERROR_MATCH}
+list(APPEND CTEST_CUSTOM_ERROR_MATCH
   "ERROR:")
 
-set(CTEST_CUSTOM_WARNING_EXCEPTION
-  ${CTEST_CUSTOM_WARNING_EXCEPTION}
+list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
   "xtree.[0-9]+. : warning C4702: unreachable code"
   "warning LNK4221"
   "warning LNK4204" # Occurs by race condition with objects in small libs
@@ -32,6 +30,7 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION
   "remark: .*LOOP WAS VECTORIZED"
   "warning .980: wrong number of actual arguments to intrinsic function .std::basic_"
   "LINK : warning LNK4089: all references to.*ADVAPI32.dll.*discarded by /OPT:REF"
+  "LINK : warning LNK4089: all references to.*CRYPT32.dll.*discarded by /OPT:REF"
   "LINK : warning LNK4089: all references to.*PSAPI.DLL.*discarded by /OPT:REF"
   "LINK : warning LNK4089: all references to.*RPCRT4.dll.*discarded by /OPT:REF"
   "LINK : warning LNK4089: all references to.*SHELL32.dll.*discarded by /OPT:REF"
@@ -83,22 +82,18 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION
   )
 
 if(NOT "@CMAKE_GENERATOR@" MATCHES "Xcode")
-  set(CTEST_CUSTOM_COVERAGE_EXCLUDE
-    ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
+  list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
     "XCode"
     )
 endif ()
 
 if(NOT "@CMAKE_GENERATOR@" MATCHES "KDevelop")
-  set(CTEST_CUSTOM_COVERAGE_EXCLUDE
-    ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
+  list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
     "Kdevelop"
     )
 endif ()
 
-set(CTEST_CUSTOM_COVERAGE_EXCLUDE
-  ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
-
+list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
   # Exclude kwsys files from coverage results. They are reported
   # (with better coverage results) on kwsys dashboards...
   "/Source/(cm|kw)sys/"
@@ -109,3 +104,7 @@ set(CTEST_CUSTOM_COVERAGE_EXCLUDE
   # Exclude Qt source files from coverage results:
   "[A-Za-z]./[Qq]t/qt-.+-opensource-src"
   )
+
+list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE
+  kwsys.testProcess-10 # See Source/kwsys/CTestCustom.cmake.in
+  )
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index 9358329..bd4d295 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -33,36 +33,47 @@ and the search will not be repeated unless the variable is cleared.
 If nothing is found, the result will be
 ``<VAR>-NOTFOUND``, and the search will be attempted again the
 next time |FIND_XXX| is invoked with the same variable.
-The name of the |SEARCH_XXX| that
-is searched for is specified by the names listed
-after the NAMES argument.   Additional search locations
-can be specified after the PATHS argument.  If ENV var is
-found in the HINTS or PATHS section the environment variable var
-will be read and converted from a system environment variable to
-a cmake style list of paths.  For example ENV PATH would be a way
-to list the system path variable. The argument
-after DOC will be used for the documentation string in
-the cache.
-PATH_SUFFIXES specifies additional subdirectories to check below
-each search path.
-
-If NO_DEFAULT_PATH is specified, then no additional paths are
+
+Options include:
+
+``NAMES``
+  Specify one or more possible names for the |SEARCH_XXX|.
+
+  When using this to specify names with and without a version
+  suffix, we recommend specifying the unversioned name first
+  so that locally-built packages can be found before those
+  provided by distributions.
+
+``HINTS``, ``PATHS``
+  Specify directories to search in addition to the default locations.
+  The ``ENV var`` sub-option reads paths from a system environment
+  variable.
+
+``PATH_SUFFIXES``
+  Specify additional subdirectories to check below each directory
+  location otherwise considered.
+
+``DOC``
+  Specify the documentation string for the ``<VAR>`` cache entry.
+
+If ``NO_DEFAULT_PATH`` is specified, then no additional paths are
 added to the search.
-If NO_DEFAULT_PATH is not specified, the search process is as follows:
+If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
 
 .. |CMAKE_PREFIX_PATH_XXX_SUBDIR| replace::
-   <prefix>/|XXX_SUBDIR| for each <prefix> in CMAKE_PREFIX_PATH
+   |prefix_XXX_SUBDIR| for each ``<prefix>`` in :variable:`CMAKE_PREFIX_PATH`
 
 .. |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR| replace::
-   <prefix>/|XXX_SUBDIR| for each <prefix>/[s]bin in PATH, and
-   <entry>/|XXX_SUBDIR| for other entries in PATH
+   |prefix_XXX_SUBDIR| for each ``<prefix>/[s]bin`` in ``PATH``, and
+   |entry_XXX_SUBDIR| for other entries in ``PATH``
 
 .. |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR| replace::
-   <prefix>/|XXX_SUBDIR| for each <prefix> in CMAKE_SYSTEM_PREFIX_PATH
+   |prefix_XXX_SUBDIR| for each ``<prefix>`` in
+   :variable:`CMAKE_SYSTEM_PREFIX_PATH`
 
 1. Search paths specified in cmake-specific cache variables.
-   These are intended to be used on the command line with a -DVAR=value.
-   This can be skipped if NO_CMAKE_PATH is passed.
+   These are intended to be used on the command line with a ``-DVAR=value``.
+   This can be skipped if ``NO_CMAKE_PATH`` is passed.
 
    * |CMAKE_PREFIX_PATH_XXX|
    * |CMAKE_XXX_PATH|
@@ -70,24 +81,24 @@ If NO_DEFAULT_PATH is not specified, the search process is as follows:
 
 2. Search paths specified in cmake-specific environment variables.
    These are intended to be set in the user's shell configuration.
-   This can be skipped if NO_CMAKE_ENVIRONMENT_PATH is passed.
+   This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed.
 
    * |CMAKE_PREFIX_PATH_XXX|
    * |CMAKE_XXX_PATH|
    * |CMAKE_XXX_MAC_PATH|
 
-3. Search the paths specified by the HINTS option.
+3. Search the paths specified by the ``HINTS`` option.
    These should be paths computed by system introspection, such as a
    hint provided by the location of another item already found.
-   Hard-coded guesses should be specified with the PATHS option.
+   Hard-coded guesses should be specified with the ``PATHS`` option.
 
 4. Search the standard system environment variables.
-   This can be skipped if NO_SYSTEM_ENVIRONMENT_PATH is an argument.
+   This can be skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is an argument.
 
    * |SYSTEM_ENVIRONMENT_PATH_XXX|
 
 5. Search cmake variables defined in the Platform files
-   for the current system.  This can be skipped if NO_CMAKE_SYSTEM_PATH
+   for the current system.  This can be skipped if ``NO_CMAKE_SYSTEM_PATH``
    is passed.
 
    * |CMAKE_SYSTEM_PREFIX_PATH_XXX|
@@ -100,6 +111,9 @@ If NO_DEFAULT_PATH is not specified, the search process is as follows:
 
 .. |FIND_ARGS_XXX| replace:: <VAR> NAMES name
 
-.. include:: FIND_XXX_MAC.txt
+On OS X the :variable:`CMAKE_FIND_FRAMEWORK` and
+:variable:`CMAKE_FIND_APPBUNDLE` variables determine the order of
+preference between Apple-style and unix-style package components.
+
 .. include:: FIND_XXX_ROOT.txt
 .. include:: FIND_XXX_ORDER.txt
diff --git a/Help/command/FIND_XXX_MAC.txt b/Help/command/FIND_XXX_MAC.txt
deleted file mode 100644
index eb3900c..0000000
--- a/Help/command/FIND_XXX_MAC.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-On Darwin or systems supporting OS X Frameworks, the cmake variable
-CMAKE_FIND_FRAMEWORK can be set to empty or one of the following:
-
-* FIRST: Try to find frameworks before standard libraries or headers.
-  This is the default on Darwin.
-
-* LAST: Try to find frameworks after standard libraries or headers.
-
-* ONLY: Only try to find frameworks.
-
-* NEVER: Never try to find frameworks.
-
-On Darwin or systems supporting OS X Application Bundles, the cmake
-variable CMAKE_FIND_APPBUNDLE can be set to empty or one of the
-following:
-
-* FIRST: Try to find application bundles before standard programs.
-  This is the default on Darwin.
-
-* LAST: Try to find application bundles after standard programs.
-
-* ONLY: Only try to find application bundles.
-
-* NEVER: Never try to find application bundles.
diff --git a/Help/command/FIND_XXX_ROOT.txt b/Help/command/FIND_XXX_ROOT.txt
index b5cab68..fab2303 100644
--- a/Help/command/FIND_XXX_ROOT.txt
+++ b/Help/command/FIND_XXX_ROOT.txt
@@ -16,8 +16,14 @@ search there too.  By default at first the directories listed in
 directory is searched, and then the non-rooted directories will be
 searched.  The default behavior can be adjusted by setting
 |CMAKE_FIND_ROOT_PATH_MODE_XXX|.  This behavior can be manually
-overridden on a per-call basis.  By using CMAKE_FIND_ROOT_PATH_BOTH
-the search order will be as described above.  If
-NO_CMAKE_FIND_ROOT_PATH is used then :variable:`CMAKE_FIND_ROOT_PATH` will not be
-used.  If ONLY_CMAKE_FIND_ROOT_PATH is used then only the re-rooted
-directories and directories below :variable:`CMAKE_STAGING_PREFIX` will be searched.
+overridden on a per-call basis using options:
+
+``CMAKE_FIND_ROOT_PATH_BOTH``
+  Search in the order described above.
+
+``NO_CMAKE_FIND_ROOT_PATH``
+  Do not use the :variable:`CMAKE_FIND_ROOT_PATH` variable.
+
+``ONLY_CMAKE_FIND_ROOT_PATH``
+  Search only the re-rooted directories and directories below
+  :variable:`CMAKE_STAGING_PREFIX`.
diff --git a/Help/command/add_executable.rst b/Help/command/add_executable.rst
index 4ed10e1..8b3fb57 100644
--- a/Help/command/add_executable.rst
+++ b/Help/command/add_executable.rst
@@ -14,7 +14,7 @@ files listed in the command invocation.  The ``<name>`` corresponds to the
 logical target name and must be globally unique within a project.  The
 actual file name of the executable built is constructed based on
 conventions of the native platform (such as ``<name>.exe`` or just
-``<name>``.
+``<name>``).
 
 By default the executable file will be created in the build tree
 directory corresponding to the source tree directory in which the
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 7c06203..5033e18 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -33,6 +33,14 @@ type is ``STATIC`` or ``SHARED`` based on whether the current value of the
 variable :variable:`BUILD_SHARED_LIBS` is ``ON``.  For ``SHARED`` and
 ``MODULE`` libraries the :prop_tgt:`POSITION_INDEPENDENT_CODE` target
 property is set to ``ON`` automatically.
+A ``SHARED`` library may be marked with the :prop_tgt:`FRAMEWORK`
+target property to create an OS X Framework.
+
+If a library does not export any symbols, it must not be declared as a
+``SHARED`` library.  For example, a Windows resource DLL or a managed C++/CLI
+DLL that exports no unmanaged symbols would need to be a ``MODULE`` library.
+This is because CMake expects a ``SHARED`` library to always have an
+associated import library on Windows.
 
 By default the library file will be created in the build tree directory
 corresponding to the source tree directory in which the command was
diff --git a/Help/command/add_subdirectory.rst b/Help/command/add_subdirectory.rst
index 29b5017..e979253 100644
--- a/Help/command/add_subdirectory.rst
+++ b/Help/command/add_subdirectory.rst
@@ -12,23 +12,23 @@ Add a subdirectory to the build.  The source_dir specifies the
 directory in which the source CMakeLists.txt and code files are
 located.  If it is a relative path it will be evaluated with respect
 to the current directory (the typical usage), but it may also be an
-absolute path.  The binary_dir specifies the directory in which to
+absolute path.  The ``binary_dir`` specifies the directory in which to
 place the output files.  If it is a relative path it will be evaluated
 with respect to the current output directory, but it may also be an
-absolute path.  If binary_dir is not specified, the value of
-source_dir, before expanding any relative path, will be used (the
+absolute path.  If ``binary_dir`` is not specified, the value of
+``source_dir``, before expanding any relative path, will be used (the
 typical usage).  The CMakeLists.txt file in the specified source
 directory will be processed immediately by CMake before processing in
 the current input file continues beyond this command.
 
-If the EXCLUDE_FROM_ALL argument is provided then targets in the
-subdirectory will not be included in the ALL target of the parent
+If the ``EXCLUDE_FROM_ALL`` argument is provided then targets in the
+subdirectory will not be included in the ``ALL`` target of the parent
 directory by default, and will be excluded from IDE project files.
 Users must explicitly build targets in the subdirectory.  This is
 meant for use when the subdirectory contains a separate part of the
 project that is useful but not necessary, such as a set of examples.
-Typically the subdirectory should contain its own project() command
-invocation so that a full build system will be generated in the
+Typically the subdirectory should contain its own :command:`project`
+command invocation so that a full build system will be generated in the
 subdirectory (such as a VS IDE solution file).  Note that inter-target
 dependencies supercede this exclusion.  If a target built by the
 parent project depends on a target in the subdirectory, the dependee
diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst
index 7e7e6bd..d8a96e9 100644
--- a/Help/command/add_test.rst
+++ b/Help/command/add_test.rst
@@ -28,6 +28,13 @@ quotes, or other characters special in CMake syntax.  The options are:
   directory set to the build directory corresponding to the
   current source directory.
 
+The given test command is expected to exit with code ``0`` to pass and
+non-zero to fail, or vice-versa if the :prop_test:`WILL_FAIL` test
+property is set.  Any output written to stdout or stderr will be
+captured by :manual:`ctest(1)` but does not affect the pass/fail status
+unless the :prop_test:`PASS_REGULAR_EXPRESSION` or
+:prop_test:`FAIL_REGULAR_EXPRESSION` test property is used.
+
 The ``COMMAND`` and ``WORKING_DIRECTORY`` options may use "generator
 expressions" with the syntax ``$<...>``.  See the
 :manual:`cmake-generator-expressions(7)` manual for available expressions.
diff --git a/Help/command/aux_source_directory.rst b/Help/command/aux_source_directory.rst
index 434d7a9..dcd1cdf 100644
--- a/Help/command/aux_source_directory.rst
+++ b/Help/command/aux_source_directory.rst
@@ -8,7 +8,7 @@ Find all source files in a directory.
   aux_source_directory(<dir> <variable>)
 
 Collects the names of all the source files in the specified directory
-and stores the list in the <variable> provided.  This command is
+and stores the list in the ``<variable>`` provided.  This command is
 intended to be used by projects that use explicit template
 instantiation.  Template instantiation files can be stored in a
 "Templates" subdirectory and collected automatically using this
diff --git a/Help/command/build_name.rst b/Help/command/build_name.rst
index 53cd05e..f717db1 100644
--- a/Help/command/build_name.rst
+++ b/Help/command/build_name.rst
@@ -3,7 +3,7 @@ build_name
 
 Disallowed.  See CMake Policy :policy:`CMP0036`.
 
-Use ${CMAKE_SYSTEM} and ${CMAKE_CXX_COMPILER} instead.
+Use ``${CMAKE_SYSTEM}`` and ``${CMAKE_CXX_COMPILER}`` instead.
 
 ::
 
@@ -11,4 +11,5 @@ Use ${CMAKE_SYSTEM} and ${CMAKE_CXX_COMPILER} instead.
 
 Sets the specified variable to a string representing the platform and
 compiler settings.  These values are now available through the
-CMAKE_SYSTEM and CMAKE_CXX_COMPILER variables.
+:variable:`CMAKE_SYSTEM` and
+:variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>` variables.
diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst
index ba545d5..9402d57 100644
--- a/Help/command/cmake_host_system_information.rst
+++ b/Help/command/cmake_host_system_information.rst
@@ -8,10 +8,10 @@ Query host system specific information.
   cmake_host_system_information(RESULT <variable> QUERY <key> ...)
 
 Queries system information of the host system on which cmake runs.
-One or more <key> can be provided to select the information to be
-queried.  The list of queried values is stored in <variable>.
+One or more ``<key>`` can be provided to select the information to be
+queried.  The list of queried values is stored in ``<variable>``.
 
-<key> can be one of the following values:
+``<key>`` can be one of the following values:
 
 ::
 
diff --git a/Help/command/cmake_minimum_required.rst b/Help/command/cmake_minimum_required.rst
index 9865eeb..8573218 100644
--- a/Help/command/cmake_minimum_required.rst
+++ b/Help/command/cmake_minimum_required.rst
@@ -25,7 +25,7 @@ When version 2.4 or lower is given the command implicitly invokes
 
 which enables compatibility features for CMake 2.4 and lower.
 
-The FATAL_ERROR option is accepted but ignored by CMake 2.6 and
+The ``FATAL_ERROR`` option is accepted but ignored by CMake 2.6 and
 higher.  It should be specified so CMake versions 2.4 and lower fail
 with an error instead of just a warning.
 
diff --git a/Help/command/create_test_sourcelist.rst b/Help/command/create_test_sourcelist.rst
index 9addd67..dde6812 100644
--- a/Help/command/create_test_sourcelist.rst
+++ b/Help/command/create_test_sourcelist.rst
@@ -14,17 +14,17 @@ A test driver is a program that links together many small tests into a
 single executable.  This is useful when building static executables
 with large libraries to shrink the total required size.  The list of
 source files needed to build the test driver will be in
-sourceListName.  DriverName is the name of the test driver program.
+``sourceListName``.  ``driverName`` is the name of the test driver program.
 The rest of the arguments consist of a list of test source files, can
 be semicolon separated.  Each test source file should have a function
 in it that is the same name as the file with no extension (foo.cxx
-should have int foo(int, char*[]);) DriverName will be able to call
-each of the tests by name on the command line.  If EXTRA_INCLUDE is
+should have int foo(int, char*[]);) ``driverName`` will be able to call
+each of the tests by name on the command line.  If ``EXTRA_INCLUDE`` is
 specified, then the next argument is included into the generated file.
-If FUNCTION is specified, then the next argument is taken as a
+If ``FUNCTION`` is specified, then the next argument is taken as a
 function name that is passed a pointer to ac and av.  This can be used
-to add extra command line processing to each test.  The cmake variable
-CMAKE_TESTDRIVER_BEFORE_TESTMAIN can be set to have code that will be
-placed directly before calling the test main function.
-CMAKE_TESTDRIVER_AFTER_TESTMAIN can be set to have code that will be
-placed directly after the call to the test main function.
+to add extra command line processing to each test.  The
+``CMAKE_TESTDRIVER_BEFORE_TESTMAIN`` cmake variable can be set to
+have code that will be placed directly before calling the test main function.
+``CMAKE_TESTDRIVER_AFTER_TESTMAIN`` can be set to have code that
+will be placed directly after the call to the test main function.
diff --git a/Help/command/ctest_memcheck.rst b/Help/command/ctest_memcheck.rst
index 2800511..29bdf7d 100644
--- a/Help/command/ctest_memcheck.rst
+++ b/Help/command/ctest_memcheck.rst
@@ -14,6 +14,7 @@ Perform the :ref:`CTest MemCheck Step` as a :ref:`Dashboard Client`.
                  [EXCLUDE_LABEL <label-exclude-regex>]
                  [INCLUDE_LABEL <label-include-regex>]
                  [PARALLEL_LEVEL <level>]
+                 [TEST_LOAD <threshold>]
                  [SCHEDULE_RANDOM <ON|OFF>]
                  [STOP_TIME <time-of-day>]
                  [RETURN_VALUE <result-var>]
diff --git a/Help/command/ctest_read_custom_files.rst b/Help/command/ctest_read_custom_files.rst
index 0bc57cd..cf8e17a 100644
--- a/Help/command/ctest_read_custom_files.rst
+++ b/Help/command/ctest_read_custom_files.rst
@@ -9,3 +9,6 @@ read CTestCustom files.
 
 Read all the CTestCustom.ctest or CTestCustom.cmake files from the
 given directory.
+
+By default, invoking :manual:`ctest(1)` without a script will read custom
+files from the binary directory.
diff --git a/Help/command/ctest_run_script.rst b/Help/command/ctest_run_script.rst
index 0f35019..5ec543e 100644
--- a/Help/command/ctest_run_script.rst
+++ b/Help/command/ctest_run_script.rst
@@ -10,6 +10,6 @@ runs a ctest -S script
 
 Runs a script or scripts much like if it was run from ctest -S.  If no
 argument is provided then the current script is run using the current
-settings of the variables.  If NEW_PROCESS is specified then each
-script will be run in a separate process.If RETURN_VALUE is specified
-the return value of the last script run will be put into var.
+settings of the variables.  If ``NEW_PROCESS`` is specified then each
+script will be run in a separate process.If ``RETURN_VALUE`` is specified
+the return value of the last script run will be put into ``var``.
diff --git a/Help/command/ctest_start.rst b/Help/command/ctest_start.rst
index b5c7b34..63db32f 100644
--- a/Help/command/ctest_start.rst
+++ b/Help/command/ctest_start.rst
@@ -14,7 +14,7 @@ after the binary directory is initialized.  If the 'source' and
 If the track is
 specified, the submissions will go to the specified track.  If APPEND
 is used, the existing TAG is used rather than creating a new one based
-on the current time stamp.  If QUIET is used, CTest will suppress any
+on the current time stamp.  If ``QUIET`` is used, CTest will suppress any
 non-error messages that it otherwise would have printed to the console.
 
 If the :variable:`CTEST_CHECKOUT_COMMAND` variable
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst
index 8cbb9ec..412e323 100644
--- a/Help/command/ctest_test.rst
+++ b/Help/command/ctest_test.rst
@@ -14,6 +14,7 @@ Perform the :ref:`CTest Test Step` as a :ref:`Dashboard Client`.
              [EXCLUDE_LABEL <label-exclude-regex>]
              [INCLUDE_LABEL <label-include-regex>]
              [PARALLEL_LEVEL <level>]
+             [TEST_LOAD <threshold>]
              [SCHEDULE_RANDOM <ON|OFF>]
              [STOP_TIME <time-of-day>]
              [RETURN_VALUE <result-var>]
@@ -41,7 +42,7 @@ The options are:
   Specify the end of a range of test numbers.
 
 ``STRIDE <stride-number>``
-  Specify the stride by which to step acorss a range of test numbers.
+  Specify the stride by which to step across a range of test numbers.
 
 ``EXCLUDE <exclude-regex>``
   Specify a regular expression matching test names to exclude.
@@ -61,6 +62,13 @@ The options are:
   Specify a positive number representing the number of tests to
   be run in parallel.
 
+``TEST_LOAD <threshold>``
+  While running tests in parallel, try not to start tests when they
+  may cause the CPU load to pass above a given threshold.  If not
+  specified the :variable:`CTEST_TEST_LOAD` variable will be checked,
+  and then the ``--test-load`` command-line argument to :manual:`ctest(1)`.
+  See also the ``TestLoad`` setting in the :ref:`CTest Test Step`.
+
 ``SCHEDULE_RANDOM <ON|OFF>``
   Launch tests in a random order.  This may be useful for detecting
   implicit test dependencies.
@@ -77,3 +85,6 @@ The options are:
   been printed to the console.  Output from the underlying test command is not
   affected.  Summary info detailing the percentage of passing tests is also
   unaffected by the ``QUIET`` option.
+
+See also the :variable:`CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE`
+and :variable:`CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE` variables.
diff --git a/Help/command/define_property.rst b/Help/command/define_property.rst
index 62bcd1b..873c6ca 100644
--- a/Help/command/define_property.rst
+++ b/Help/command/define_property.rst
@@ -11,11 +11,11 @@ Define and document custom properties.
                    BRIEF_DOCS <brief-doc> [docs...]
                    FULL_DOCS <full-doc> [docs...])
 
-Define one property in a scope for use with the set_property and
-get_property commands.  This is primarily useful to associate
+Define one property in a scope for use with the :command:`set_property` and
+:command:`get_property` commands.  This is primarily useful to associate
 documentation with property names that may be retrieved with the
-get_property command.  The first argument determines the kind of scope
-in which the property should be used.  It must be one of the
+:command:`get_property` command. The first argument determines the kind of
+scope in which the property should be used.  It must be one of the
 following:
 
 ::
@@ -28,18 +28,18 @@ following:
   VARIABLE  = documents a CMake language variable
   CACHED_VARIABLE = documents a CMake cache variable
 
-Note that unlike set_property and get_property no actual scope needs
-to be given; only the kind of scope is important.
+Note that unlike :command:`set_property` and :command:`get_property` no
+actual scope needs to be given; only the kind of scope is important.
 
-The required PROPERTY option is immediately followed by the name of
+The required ``PROPERTY`` option is immediately followed by the name of
 the property being defined.
 
-If the INHERITED option then the get_property command will chain up to
-the next higher scope when the requested property is not set in the
-scope given to the command.  DIRECTORY scope chains to GLOBAL.
-TARGET, SOURCE, and TEST chain to DIRECTORY.
+If the ``INHERITED`` option then the :command:`get_property` command will
+chain up to the next higher scope when the requested property is not set
+in the scope given to the command. ``DIRECTORY`` scope chains to
+``GLOBAL``. ``TARGET``, ``SOURCE``, and ``TEST`` chain to ``DIRECTORY``.
 
-The BRIEF_DOCS and FULL_DOCS options are followed by strings to be
+The ``BRIEF_DOCS`` and ``FULL_DOCS`` options are followed by strings to be
 associated with the property as its brief and full documentation.
-Corresponding options to the get_property command will retrieve the
-documentation.
+Corresponding options to the :command:`get_property` command will retrieve
+the documentation.
diff --git a/Help/command/else.rst b/Help/command/else.rst
index 5eece95..0e5a198 100644
--- a/Help/command/else.rst
+++ b/Help/command/else.rst
@@ -7,4 +7,4 @@ Starts the else portion of an if block.
 
   else(expression)
 
-See the if command.
+See the :command:`if` command.
diff --git a/Help/command/elseif.rst b/Help/command/elseif.rst
index 96ee0e9..9a8dfed 100644
--- a/Help/command/elseif.rst
+++ b/Help/command/elseif.rst
@@ -7,4 +7,4 @@ Starts the elseif portion of an if block.
 
   elseif(expression)
 
-See the if command.
+See the :command:`if` command.
diff --git a/Help/command/enable_language.rst b/Help/command/enable_language.rst
index d46ff7e..4445561 100644
--- a/Help/command/enable_language.rst
+++ b/Help/command/enable_language.rst
@@ -18,5 +18,5 @@ targets using the named language directly for compiling sources or
 indirectly through link dependencies.  It is simplest to enable all
 needed languages in the top-level directory of a project.
 
-The OPTIONAL keyword is a placeholder for future implementation and
+The ``OPTIONAL`` keyword is a placeholder for future implementation and
 does not currently work.
diff --git a/Help/command/enable_testing.rst b/Help/command/enable_testing.rst
index 41ecd5b..1e3e279 100644
--- a/Help/command/enable_testing.rst
+++ b/Help/command/enable_testing.rst
@@ -7,7 +7,7 @@ Enable testing for current directory and below.
 
   enable_testing()
 
-Enables testing for this directory and below.  See also the add_test
-command.  Note that ctest expects to find a test file in the build
-directory root.  Therefore, this command should be in the source
-directory root.
+Enables testing for this directory and below.  See also the
+:command:`add_test` command.  Note that ctest expects to find a test file
+in the build directory root.  Therefore, this command should be in the
+source directory root.
diff --git a/Help/command/endforeach.rst b/Help/command/endforeach.rst
index f23552d..9af972b 100644
--- a/Help/command/endforeach.rst
+++ b/Help/command/endforeach.rst
@@ -1,10 +1,10 @@
 endforeach
 ----------
 
-Ends a list of commands in a FOREACH block.
+Ends a list of commands in a foreach block.
 
 ::
 
   endforeach(expression)
 
-See the FOREACH command.
+See the :command:`foreach` command.
diff --git a/Help/command/endfunction.rst b/Help/command/endfunction.rst
index 63e70ba..6cc196c 100644
--- a/Help/command/endfunction.rst
+++ b/Help/command/endfunction.rst
@@ -7,4 +7,4 @@ Ends a list of commands in a function block.
 
   endfunction(expression)
 
-See the function command.
+See the :command:`function` command.
diff --git a/Help/command/endif.rst b/Help/command/endif.rst
index 4c9955c..a0163bf 100644
--- a/Help/command/endif.rst
+++ b/Help/command/endif.rst
@@ -7,4 +7,4 @@ Ends a list of commands in an if block.
 
   endif(expression)
 
-See the if command.
+See the :command:`if` command.
diff --git a/Help/command/endmacro.rst b/Help/command/endmacro.rst
index 524fc80..47327a7 100644
--- a/Help/command/endmacro.rst
+++ b/Help/command/endmacro.rst
@@ -7,4 +7,4 @@ Ends a list of commands in a macro block.
 
   endmacro(expression)
 
-See the macro command.
+See the :command:`macro` command.
diff --git a/Help/command/endwhile.rst b/Help/command/endwhile.rst
index 11fdc1b..798c20e 100644
--- a/Help/command/endwhile.rst
+++ b/Help/command/endwhile.rst
@@ -7,4 +7,4 @@ Ends a list of commands in a while block.
 
   endwhile(expression)
 
-See the while command.
+See the :command:`while` command.
diff --git a/Help/command/exec_program.rst b/Help/command/exec_program.rst
index aaa0dac..6dfdad3 100644
--- a/Help/command/exec_program.rst
+++ b/Help/command/exec_program.rst
@@ -1,7 +1,7 @@
 exec_program
 ------------
 
-Deprecated.  Use the execute_process() command instead.
+Deprecated.  Use the :command:`execute_process` command instead.
 
 Run an executable program during the processing of the CMakeList.txt
 file.
@@ -15,10 +15,10 @@ file.
 
 The executable is run in the optionally specified directory.  The
 executable can include arguments if it is double quoted, but it is
-better to use the optional ARGS argument to specify arguments to the
+better to use the optional ``ARGS`` argument to specify arguments to the
 program.  This is because cmake will then be able to escape spaces in
-the executable path.  An optional argument OUTPUT_VARIABLE specifies a
+the executable path.  An optional argument ``OUTPUT_VARIABLE`` specifies a
 variable in which to store the output.  To capture the return value of
-the execution, provide a RETURN_VALUE.  If OUTPUT_VARIABLE is
+the execution, provide a ``RETURN_VALUE``.  If ``OUTPUT_VARIABLE`` is
 specified, then no output will go to the stdout/stderr of the console
 running cmake.
diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst
index c38ec1a..ca44b53 100644
--- a/Help/command/execute_process.rst
+++ b/Help/command/execute_process.rst
@@ -26,7 +26,7 @@ A single standard error pipe is used for all processes.
 
 Options:
 
-COMMAND
+``COMMAND``
  A child process command line.
 
  CMake executes the child process using operating system APIs directly.
@@ -36,31 +36,31 @@ COMMAND
  (Use the ``INPUT_*``, ``OUTPUT_*``, and ``ERROR_*`` options to
  redirect stdin, stdout, and stderr.)
 
-WORKING_DIRECTORY
+``WORKING_DIRECTORY``
  The named directory will be set as the current working directory of
  the child processes.
 
-TIMEOUT
+``TIMEOUT``
  The child processes will be terminated if they do not finish in the
  specified number of seconds (fractions are allowed).
 
-RESULT_VARIABLE
+``RESULT_VARIABLE``
  The variable will be set to contain the result of running the processes.
  This will be an integer return code from the last child or a string
  describing an error condition.
 
-OUTPUT_VARIABLE, ERROR_VARIABLE
+``OUTPUT_VARIABLE``, ``ERROR_VARIABLE``
  The variable named will be set with the contents of the standard output
  and standard error pipes, respectively.  If the same variable is named
  for both pipes their output will be merged in the order produced.
 
-INPUT_FILE, OUTPUT_FILE, ERROR_FILE
+``INPUT_FILE, OUTPUT_FILE``, ``ERROR_FILE``
  The file named will be attached to the standard input of the first
  process, standard output of the last process, or standard error of
  all processes, respectively.  If the same file is named for both
  output and error then it will be used for both.
 
-OUTPUT_QUIET, ERROR_QUIET
+``OUTPUT_QUIET``, ``ERROR_QUIET``
  The standard output or standard error results will be quietly ignored.
 
 If more than one ``OUTPUT_*`` or ``ERROR_*`` option is given for the
diff --git a/Help/command/export.rst b/Help/command/export.rst
index d4bab35..4419dc1 100644
--- a/Help/command/export.rst
+++ b/Help/command/export.rst
@@ -7,20 +7,20 @@ Export targets from the build tree for use by outside projects.
 
   export(EXPORT <export-name> [NAMESPACE <namespace>] [FILE <filename>])
 
-Create a file <filename> that may be included by outside projects to
+Create a file ``<filename>`` that may be included by outside projects to
 import targets from the current project's build tree.  This is useful
 during cross-compiling to build utility executables that can run on
 the host platform in one project and then import them into another
-project being compiled for the target platform.  If the NAMESPACE
-option is given the <namespace> string will be prepended to all target
+project being compiled for the target platform.  If the ``NAMESPACE``
+option is given the ``<namespace>`` string will be prepended to all target
 names written to the file.
 
-Target installations are associated with the export <export-name>
+Target installations are associated with the export ``<export-name>``
 using the ``EXPORT`` option of the :command:`install(TARGETS)` command.
 
 The file created by this command is specific to the build tree and
-should never be installed.  See the install(EXPORT) command to export
-targets from an installation tree.
+should never be installed.  See the :command:`install(EXPORT)` command to
+export targets from an installation tree.
 
 The properties set on the generated IMPORTED targets will have the
 same values as the final values of the input TARGETS.
@@ -45,12 +45,12 @@ unspecified.
   export(PACKAGE <name>)
 
 Store the current build directory in the CMake user package registry
-for package <name>.  The find_package command may consider the
-directory while searching for package <name>.  This helps dependent
+for package ``<name>``.  The find_package command may consider the
+directory while searching for package ``<name>``.  This helps dependent
 projects find and use a package from the current project's build tree
 without help from the user.  Note that the entry in the package
 registry that this command creates works only in conjunction with a
-package configuration file (<name>Config.cmake) that works with the
+package configuration file (``<name>Config.cmake``) that works with the
 build tree. In some cases, for example for packaging and for system
 wide installations, it is not desirable to write the user package
 registry. If the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable
diff --git a/Help/command/export_library_dependencies.rst b/Help/command/export_library_dependencies.rst
index 73c0b42..2cb437e 100644
--- a/Help/command/export_library_dependencies.rst
+++ b/Help/command/export_library_dependencies.rst
@@ -7,22 +7,22 @@ Use :command:`install(EXPORT)` or :command:`export` command.
 
 This command generates an old-style library dependencies file.
 Projects requiring CMake 2.6 or later should not use the command.  Use
-instead the install(EXPORT) command to help export targets from an
-installation tree and the export() command to export targets from a
+instead the :command:`install(EXPORT)` command to help export targets from an
+installation tree and the :command:`export` command to export targets from a
 build tree.
 
 The old-style library dependencies file does not take into account
-per-configuration names of libraries or the LINK_INTERFACE_LIBRARIES
-target property.
+per-configuration names of libraries or the
+:prop_tgt:`LINK_INTERFACE_LIBRARIES` target property.
 
 ::
 
   export_library_dependencies(<file> [APPEND])
 
-Create a file named <file> that can be included into a CMake listfile
+Create a file named ``<file>`` that can be included into a CMake listfile
 with the INCLUDE command.  The file will contain a number of SET
 commands that will set all the variables needed for library dependency
 information.  This should be the last command in the top level
-CMakeLists.txt file of the project.  If the APPEND option is
+CMakeLists.txt file of the project.  If the ``APPEND`` option is
 specified, the SET commands will be appended to the given file instead
 of replacing it.
diff --git a/Help/command/file.rst b/Help/command/file.rst
index bbddd40..96ac6c7 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -103,7 +103,8 @@ Generate a list of files that match the ``<globbing-expressions>`` and
 store it into the ``<variable>``.  Globbing expressions are similar to
 regular expressions, but much simpler.  If ``RELATIVE`` flag is
 specified, the results will be returned as relative paths to the given
-path.
+path.  No specific order of results is defined.  If order is important then
+sort the list explicitly (e.g. using the :command:`list(SORT)` command).
 
 By default ``GLOB`` lists directories - directories are omited in result if
 ``LIST_DIRECTORIES`` is set to false.
diff --git a/Help/command/find_file.rst b/Help/command/find_file.rst
index be309a5..bf7a919 100644
--- a/Help/command/find_file.rst
+++ b/Help/command/find_file.rst
@@ -5,24 +5,27 @@ find_file
 .. |NAMES| replace:: NAMES name1 [name2 ...]
 .. |SEARCH_XXX| replace:: full path to a file
 .. |SEARCH_XXX_DESC| replace:: full path to named file
-.. |XXX_SUBDIR| replace:: include
+.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/include``
+.. |entry_XXX_SUBDIR| replace:: ``<entry>/include``
 
 .. |CMAKE_PREFIX_PATH_XXX| replace::
-   <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and
-   |CMAKE_PREFIX_PATH_XXX_SUBDIR|
-.. |CMAKE_XXX_PATH| replace:: CMAKE_INCLUDE_PATH
-.. |CMAKE_XXX_MAC_PATH| replace:: CMAKE_FRAMEWORK_PATH
+   ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+   is set, and |CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH`
+.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
 
-.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in INCLUDE,
-   <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and
-   |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|,
-   and the directories in PATH itself.
+.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in ``INCLUDE``,
+   ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+   is set, and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, and the
+   directories in ``PATH`` itself.
 
 .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace::
-   <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and
-   |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
-.. |CMAKE_SYSTEM_XXX_PATH| replace:: CMAKE_SYSTEM_INCLUDE_PATH
-.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace:: CMAKE_SYSTEM_FRAMEWORK_PATH
+   ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+   is set, and |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_SYSTEM_XXX_PATH| replace::
+   :variable:`CMAKE_SYSTEM_INCLUDE_PATH`
+.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace::
+   :variable:`CMAKE_SYSTEM_FRAMEWORK_PATH`
 
 .. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
    :variable:`CMAKE_FIND_ROOT_PATH_MODE_INCLUDE`
diff --git a/Help/command/find_library.rst b/Help/command/find_library.rst
index e3dcd2b..5d07574 100644
--- a/Help/command/find_library.rst
+++ b/Help/command/find_library.rst
@@ -5,33 +5,36 @@ find_library
 .. |NAMES| replace:: NAMES name1 [name2 ...] [NAMES_PER_DIR]
 .. |SEARCH_XXX| replace:: library
 .. |SEARCH_XXX_DESC| replace:: library
-.. |XXX_SUBDIR| replace:: lib
+.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/lib``
+.. |entry_XXX_SUBDIR| replace:: ``<entry>/lib``
 
 .. |CMAKE_PREFIX_PATH_XXX| replace::
-   <prefix>/lib/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and
-   |CMAKE_PREFIX_PATH_XXX_SUBDIR|
-.. |CMAKE_XXX_PATH| replace:: CMAKE_LIBRARY_PATH
-.. |CMAKE_XXX_MAC_PATH| replace:: CMAKE_FRAMEWORK_PATH
+   ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+   and |CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_LIBRARY_PATH`
+.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
 
-.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in LIB,
-   <prefix>/lib/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and
-   |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|,
-   and the directories in PATH itself.
+.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in ``LIB``,
+   ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+   and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|,
+   and the directories in ``PATH`` itself.
 
 .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace::
-   <prefix>/lib/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and
-   |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
-.. |CMAKE_SYSTEM_XXX_PATH| replace:: CMAKE_SYSTEM_LIBRARY_PATH
-.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace:: CMAKE_SYSTEM_FRAMEWORK_PATH
+   ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+   and |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_SYSTEM_XXX_PATH| replace::
+   :variable:`CMAKE_SYSTEM_LIBRARY_PATH`
+.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace::
+   :variable:`CMAKE_SYSTEM_FRAMEWORK_PATH`
 
 .. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
    :variable:`CMAKE_FIND_ROOT_PATH_MODE_LIBRARY`
 
 .. include:: FIND_XXX.txt
 
-When more than one value is given to the NAMES option this command by
+When more than one value is given to the ``NAMES`` option this command by
 default will consider one name at a time and search every directory
-for it.  The NAMES_PER_DIR option tells this command to consider one
+for it.  The ``NAMES_PER_DIR`` option tells this command to consider one
 directory at a time and search for all names in it.
 
 Each library name given to the ``NAMES`` option is first considered
@@ -40,14 +43,14 @@ prefixes (e.g. ``lib``) and suffixes (e.g. ``.so``).  Therefore one
 may specify library file names such as ``libfoo.a`` directly.
 This can be used to locate static libraries on UNIX-like systems.
 
-If the library found is a framework, then VAR will be set to the full
-path to the framework <fullPath>/A.framework.  When a full path to a
-framework is used as a library, CMake will use a -framework A, and a
--F<fullPath> to link the framework to the target.
+If the library found is a framework, then ``<VAR>`` will be set to the full
+path to the framework ``<fullPath>/A.framework``.  When a full path to a
+framework is used as a library, CMake will use a ``-framework A``, and a
+``-F<fullPath>`` to link the framework to the target.
 
-If the global property FIND_LIBRARY_USE_LIB64_PATHS is set all search
-paths will be tested as normal, with "64/" appended, and with all
-matches of "lib/" replaced with "lib64/".  This property is
+If the :prop_gbl:`FIND_LIBRARY_USE_LIB64_PATHS` global property is set
+all search paths will be tested as normal, with ``64/`` appended, and
+with all matches of ``lib/`` replaced with ``lib64/``.  This property is
 automatically set for the platforms that are known to need it if at
-least one of the languages supported by the PROJECT command is
-enabled.
+least one of the languages supported by the :command:`project` command
+is enabled.
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index a5efba6..58dff9d 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -228,9 +228,9 @@ installation directory.  Those marked with (U) are intended for
 installations on UNIX platforms where the prefix is shared by multiple
 packages.  This is merely a convention, so all (W) and (U) directories
 are still searched on all platforms.  Directories marked with (A) are
-intended for installations on Apple platforms.  The cmake variables
-``CMAKE_FIND_FRAMEWORK`` and ``CMAKE_FIND_APPBUNDLE``
-determine the order of preference as specified below.
+intended for installations on Apple platforms.  The
+:variable:`CMAKE_FIND_FRAMEWORK` and :variable:`CMAKE_FIND_APPBUNDLE`
+variables determine the order of preference.
 
 The set of installation prefixes is constructed using the following
 steps.  If ``NO_DEFAULT_PATH`` is specified all ``NO_*`` options are
@@ -295,7 +295,6 @@ enabled.
 .. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
    :variable:`CMAKE_FIND_ROOT_PATH_MODE_PACKAGE`
 
-.. include:: FIND_XXX_MAC.txt
 .. include:: FIND_XXX_ROOT.txt
 .. include:: FIND_XXX_ORDER.txt
 
diff --git a/Help/command/find_path.rst b/Help/command/find_path.rst
index b5a6e37..4403cb5 100644
--- a/Help/command/find_path.rst
+++ b/Help/command/find_path.rst
@@ -5,31 +5,34 @@ find_path
 .. |NAMES| replace:: NAMES name1 [name2 ...]
 .. |SEARCH_XXX| replace:: file in a directory
 .. |SEARCH_XXX_DESC| replace:: directory containing the named file
-.. |XXX_SUBDIR| replace:: include
+.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/include``
+.. |entry_XXX_SUBDIR| replace:: ``<entry>/include``
 
 .. |CMAKE_PREFIX_PATH_XXX| replace::
-   <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and
-   |CMAKE_PREFIX_PATH_XXX_SUBDIR|
-.. |CMAKE_XXX_PATH| replace:: CMAKE_INCLUDE_PATH
-.. |CMAKE_XXX_MAC_PATH| replace:: CMAKE_FRAMEWORK_PATH
+   ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+   is set, and |CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH`
+.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
 
-.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in INCLUDE,
-   <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and
-   |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|,
-   and the directories in PATH itself.
+.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in ``INCLUDE``,
+   ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+   is set, and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, and the
+   directories in ``PATH`` itself.
 
 .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace::
-   <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and
-   |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
-.. |CMAKE_SYSTEM_XXX_PATH| replace:: CMAKE_SYSTEM_INCLUDE_PATH
-.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace:: CMAKE_SYSTEM_FRAMEWORK_PATH
+   ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+   is set, and |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_SYSTEM_XXX_PATH| replace::
+   :variable:`CMAKE_SYSTEM_INCLUDE_PATH`
+.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace::
+   :variable:`CMAKE_SYSTEM_FRAMEWORK_PATH`
 
 .. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
    :variable:`CMAKE_FIND_ROOT_PATH_MODE_INCLUDE`
 
 .. include:: FIND_XXX.txt
 
-When searching for frameworks, if the file is specified as A/b.h, then
-the framework search will look for A.framework/Headers/b.h.  If that
+When searching for frameworks, if the file is specified as ``A/b.h``, then
+the framework search will look for ``A.framework/Headers/b.h``.  If that
 is found the path will be set to the path to the framework.  CMake
-will convert this to the correct -F option to include the file.
+will convert this to the correct ``-F`` option to include the file.
diff --git a/Help/command/find_program.rst b/Help/command/find_program.rst
index c62a8a5..d3430c0 100644
--- a/Help/command/find_program.rst
+++ b/Help/command/find_program.rst
@@ -2,24 +2,32 @@ find_program
 ------------
 
 .. |FIND_XXX| replace:: find_program
-.. |NAMES| replace:: NAMES name1 [name2 ...]
+.. |NAMES| replace:: NAMES name1 [name2 ...] [NAMES_PER_DIR]
 .. |SEARCH_XXX| replace:: program
 .. |SEARCH_XXX_DESC| replace:: program
-.. |XXX_SUBDIR| replace:: [s]bin
+.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/[s]bin``
+.. |entry_XXX_SUBDIR| replace:: ``<entry>/[s]bin``
 
 .. |CMAKE_PREFIX_PATH_XXX| replace::
    |CMAKE_PREFIX_PATH_XXX_SUBDIR|
-.. |CMAKE_XXX_PATH| replace:: CMAKE_PROGRAM_PATH
-.. |CMAKE_XXX_MAC_PATH| replace:: CMAKE_APPBUNDLE_PATH
+.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_PROGRAM_PATH`
+.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_APPBUNDLE_PATH`
 
-.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: PATH
+.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: ``PATH``
 
 .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace::
    |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
-.. |CMAKE_SYSTEM_XXX_PATH| replace:: CMAKE_SYSTEM_PROGRAM_PATH
-.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace:: CMAKE_SYSTEM_APPBUNDLE_PATH
+.. |CMAKE_SYSTEM_XXX_PATH| replace::
+   :variable:`CMAKE_SYSTEM_PROGRAM_PATH`
+.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace::
+   :variable:`CMAKE_SYSTEM_APPBUNDLE_PATH`
 
 .. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
    :variable:`CMAKE_FIND_ROOT_PATH_MODE_PROGRAM`
 
 .. include:: FIND_XXX.txt
+
+When more than one value is given to the ``NAMES`` option this command by
+default will consider one name at a time and search every directory
+for it.  The ``NAMES_PER_DIR`` option tells this command to consider one
+directory at a time and search for all names in it.
diff --git a/Help/command/fltk_wrap_ui.rst b/Help/command/fltk_wrap_ui.rst
index 448ae64..041e5a7 100644
--- a/Help/command/fltk_wrap_ui.rst
+++ b/Help/command/fltk_wrap_ui.rst
@@ -10,5 +10,5 @@ Create FLTK user interfaces Wrappers.
 
 Produce .h and .cxx files for all the .fl and .fld files listed.  The
 resulting .h and .cxx files will be added to a variable named
-resultingLibraryName_FLTK_UI_SRCS which should be added to your
+``resultingLibraryName_FLTK_UI_SRCS`` which should be added to your
 library.
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst
index 348ebd8..c0f3679 100644
--- a/Help/command/foreach.rst
+++ b/Help/command/foreach.rst
@@ -15,7 +15,7 @@ All commands between foreach and the matching endforeach are recorded
 without being invoked.  Once the endforeach is evaluated, the recorded
 list of commands is invoked once for each argument listed in the
 original foreach command.  Before each iteration of the loop
-"${loop_var}" will be set as a variable with the current value in the
+``${loop_var}`` will be set as a variable with the current value in the
 list.
 
 ::
@@ -40,8 +40,8 @@ three types of this iteration:
   foreach(loop_var IN [LISTS [list1 [...]]]
                       [ITEMS [item1 [...]]])
 
-Iterates over a precise list of items.  The LISTS option names
+Iterates over a precise list of items.  The ``LISTS`` option names
 list-valued variables to be traversed, including empty elements (an
 empty string is a zero-length list).  (Note macro
-arguments are not variables.)  The ITEMS option ends argument
+arguments are not variables.)  The ``ITEMS`` option ends argument
 parsing and includes all arguments following it in the iteration.
diff --git a/Help/command/get_cmake_property.rst b/Help/command/get_cmake_property.rst
index bcfc5e8..3a6fb41 100644
--- a/Help/command/get_cmake_property.rst
+++ b/Help/command/get_cmake_property.rst
@@ -8,8 +8,8 @@ Get a property of the CMake instance.
   get_cmake_property(VAR property)
 
 Get a property from the CMake instance.  The value of the property is
-stored in the variable VAR.  If the property is not found, VAR will be
-set to "NOTFOUND".  Some supported properties include: VARIABLES,
-CACHE_VARIABLES, COMMANDS, MACROS, and COMPONENTS.
+stored in the variable ``VAR``.  If the property is not found, ``VAR``
+will be  set to "NOTFOUND".  See the :manual:`cmake-properties(7)` manual
+for available properties.
 
-See also the more general get_property() command.
+See also the more general :command:`get_property` command.
diff --git a/Help/command/get_directory_property.rst b/Help/command/get_directory_property.rst
index f2a0a80..e50abe0 100644
--- a/Help/command/get_directory_property.rst
+++ b/Help/command/get_directory_property.rst
@@ -1,14 +1,14 @@
 get_directory_property
 ----------------------
 
-Get a property of DIRECTORY scope.
+Get a property of ``DIRECTORY`` scope.
 
 ::
 
   get_directory_property(<variable> [DIRECTORY <dir>] <prop-name>)
 
 Store a property of directory scope in the named variable.  If the
-property is not defined the empty-string is returned.  The DIRECTORY
+property is not defined the empty-string is returned.  The ``DIRECTORY``
 argument specifies another directory from which to retrieve the
 property value.  The specified directory must have already been
 traversed by CMake.
@@ -21,4 +21,4 @@ traversed by CMake.
 Get a variable definition from a directory.  This form is useful to
 get a variable definition from another directory.
 
-See also the more general get_property() command.
+See also the more general :command:`get_property` command.
diff --git a/Help/command/get_filename_component.rst b/Help/command/get_filename_component.rst
index 5eec792..14c8cf2 100644
--- a/Help/command/get_filename_component.rst
+++ b/Help/command/get_filename_component.rst
@@ -3,11 +3,13 @@ get_filename_component
 
 Get a specific component of a full filename.
 
+------------------------------------------------------------------------------
+
 ::
 
   get_filename_component(<VAR> <FileName> <COMP> [CACHE])
 
-Set <VAR> to a component of <FileName>, where <COMP> is one of:
+Set ``<VAR>`` to a component of ``<FileName>``, where ``<COMP>`` is one of:
 
 ::
 
@@ -15,23 +17,48 @@ Set <VAR> to a component of <FileName>, where <COMP> is one of:
  NAME      = File name without directory
  EXT       = File name longest extension (.b.c from d/a.b.c)
  NAME_WE   = File name without directory or longest extension
- ABSOLUTE  = Full path to file
- REALPATH  = Full path to existing file with symlinks resolved
  PATH      = Legacy alias for DIRECTORY (use for CMake <= 2.8.11)
 
-Paths are returned with forward slashes and have no trailing slahes.
+Paths are returned with forward slashes and have no trailing slashes.
 The longest file extension is always considered.  If the optional
-CACHE argument is specified, the result variable is added to the
+``CACHE`` argument is specified, the result variable is added to the
+cache.
+
+------------------------------------------------------------------------------
+
+::
+
+  get_filename_component(<VAR> <FileName>
+                         <COMP> [BASE_DIR <BASE_DIR>]
+                         [CACHE])
+
+Set ``<VAR>`` to the absolute path of ``<FileName>``, where ``<COMP>`` is one
+of:
+
+::
+
+ ABSOLUTE  = Full path to file
+ REALPATH  = Full path to existing file with symlinks resolved
+
+If the provided ``<FileName>`` is a relative path, it is evaluated relative
+to the given base directory ``<BASE_DIR>``.  If no base directory is
+provided, the default base directory will be
+:variable:`CMAKE_CURRENT_SOURCE_DIR`.
+
+Paths are returned with forward slashes and have no trailing slahes.  If the
+optional ``CACHE`` argument is specified, the result variable is added to the
 cache.
 
+------------------------------------------------------------------------------
+
 ::
 
-  get_filename_component(<VAR> FileName
+  get_filename_component(<VAR> <FileName>
                          PROGRAM [PROGRAM_ARGS <ARG_VAR>]
                          [CACHE])
 
-The program in FileName will be found in the system search path or
-left as a full path.  If PROGRAM_ARGS is present with PROGRAM, then
-any command-line arguments present in the FileName string are split
-from the program name and stored in <ARG_VAR>.  This is used to
+The program in ``<FileName>`` will be found in the system search path or
+left as a full path.  If ``PROGRAM_ARGS`` is present with ``PROGRAM``, then
+any command-line arguments present in the ``<FileName>`` string are split
+from the program name and stored in ``<ARG_VAR>``.  This is used to
 separate a program name from its arguments in a command line string.
diff --git a/Help/command/get_source_file_property.rst b/Help/command/get_source_file_property.rst
index 80c512b..3e975c2 100644
--- a/Help/command/get_source_file_property.rst
+++ b/Help/command/get_source_file_property.rst
@@ -8,9 +8,9 @@ Get a property for a source file.
   get_source_file_property(VAR file property)
 
 Get a property from a source file.  The value of the property is
-stored in the variable VAR.  If the property is not found, VAR will be
-set to "NOTFOUND".  Use set_source_files_properties to set property
-values.  Source file properties usually control how the file is built.
-One property that is always there is LOCATION
+stored in the variable ``VAR``.  If the property is not found, ``VAR``
+will be set to "NOTFOUND".  Use :command:`set_source_files_properties`
+to set property values.  Source file properties usually control how the
+file is built. One property that is always there is :prop_sf:`LOCATION`
 
-See also the more general get_property() command.
+See also the more general :command:`get_property` command.
diff --git a/Help/command/get_target_property.rst b/Help/command/get_target_property.rst
index 4017d31..7798252 100644
--- a/Help/command/get_target_property.rst
+++ b/Help/command/get_target_property.rst
@@ -8,11 +8,11 @@ Get a property from a target.
   get_target_property(VAR target property)
 
 Get a property from a target.  The value of the property is stored in
-the variable VAR.  If the property is not found, VAR will be set to
-"NOTFOUND".  Use set_target_properties to set property values.
+the variable ``VAR``.  If the property is not found, ``VAR`` will be set to
+"NOTFOUND".  Use :command:`set_target_properties` to set property values.
 Properties are usually used to control how a target is built, but some
 query the target instead.  This command can get properties for any
 target so far created.  The targets do not need to be in the current
 CMakeLists.txt file.
 
-See also the more general get_property() command.
+See also the more general :command:`get_property` command.
diff --git a/Help/command/get_test_property.rst b/Help/command/get_test_property.rst
index 391a32e..e359f4b 100644
--- a/Help/command/get_test_property.rst
+++ b/Help/command/get_test_property.rst
@@ -8,8 +8,8 @@ Get a property of the test.
   get_test_property(test property VAR)
 
 Get a property from the test.  The value of the property is stored in
-the variable VAR.  If the test or property is not found, VAR will be
-set to "NOTFOUND".  For a list of standard properties you can type cmake
---help-property-list.
+the variable ``VAR``.  If the test or property is not found, ``VAR`` will
+be set to "NOTFOUND".  For a list of standard properties you can type
+``cmake --help-property-list``.
 
-See also the more general get_property() command.
+See also the more general :command:`get_property` command.
diff --git a/Help/command/if.rst b/Help/command/if.rst
index 396becf..2465bde 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -71,6 +71,10 @@ Possible expressions are:
  created by the :command:`add_executable`, :command:`add_library`, or
  :command:`add_custom_target` commands.
 
+``if(TEST test-name)``
+ True if the given name is an existing test name created by the
+ :command:`add_test` command.
+
 ``if(EXISTS path-to-file-or-directory)``
  True if the named file or directory exists.  Behavior is well-defined
  only for full paths.
diff --git a/Help/command/include.rst b/Help/command/include.rst
index a9074c1..c391561 100644
--- a/Help/command/include.rst
+++ b/Help/command/include.rst
@@ -9,17 +9,17 @@ Load and run CMake code from a file or module.
                         [NO_POLICY_SCOPE])
 
 Load and run CMake code from the file given.  Variable reads and
-writes access the scope of the caller (dynamic scoping).  If OPTIONAL
+writes access the scope of the caller (dynamic scoping).  If ``OPTIONAL``
 is present, then no error is raised if the file does not exist.  If
-RESULT_VARIABLE is given the variable will be set to the full filename
+``RESULT_VARIABLE`` is given the variable will be set to the full filename
 which has been included or NOTFOUND if it failed.
 
 If a module is specified instead of a file, the file with name
-<modulename>.cmake is searched first in CMAKE_MODULE_PATH, then in the
-CMake module directory.  There is one exception to this: if the file
-which calls include() is located itself in the CMake module directory,
-then first the CMake module directory is searched and
-CMAKE_MODULE_PATH afterwards.  See also policy CMP0017.
+<modulename>.cmake is searched first in :variable:`CMAKE_MODULE_PATH`,
+then in the CMake module directory.  There is one exception to this: if
+the file which calls ``include()`` is located itself in the CMake module
+directory, then first the CMake module directory is searched and
+:variable:`CMAKE_MODULE_PATH` afterwards.  See also policy :policy:`CMP0017`.
 
-See the cmake_policy() command documentation for discussion of the
-NO_POLICY_SCOPE option.
+See the :command:`cmake_policy` command documentation for discussion of the
+``NO_POLICY_SCOPE`` option.
diff --git a/Help/command/include_external_msproject.rst b/Help/command/include_external_msproject.rst
index ba9a393..595762d 100644
--- a/Help/command/include_external_msproject.rst
+++ b/Help/command/include_external_msproject.rst
@@ -13,10 +13,10 @@ Include an external Microsoft project file in a workspace.
 
 Includes an external Microsoft project in the generated workspace
 file.  Currently does nothing on UNIX.  This will create a target
-named [projectname].  This can be used in the add_dependencies command
-to make things depend on the external project.
+named [projectname].  This can be used in the :command:`add_dependencies`
+command to make things depend on the external project.
 
-TYPE, GUID and PLATFORM are optional parameters that allow one to
+``TYPE``, ``GUID`` and ``PLATFORM`` are optional parameters that allow one to
 specify the type of project, id (GUID) of the project and the name of
 the target platform.  This is useful for projects requiring values
 other than the default (e.g.  WIX projects).  These options are not
diff --git a/Help/command/include_regular_expression.rst b/Help/command/include_regular_expression.rst
index dd887df..ab5a563 100644
--- a/Help/command/include_regular_expression.rst
+++ b/Help/command/include_regular_expression.rst
@@ -8,8 +8,8 @@ Set the regular expression used for dependency checking.
   include_regular_expression(regex_match [regex_complain])
 
 Set the regular expressions used in dependency checking.  Only files
-matching regex_match will be traced as dependencies.  Only files
-matching regex_complain will generate warnings if they cannot be found
+matching ``regex_match`` will be traced as dependencies.  Only files
+matching ``regex_complain`` will generate warnings if they cannot be found
 (standard header paths are not searched).  The defaults are:
 
 ::
diff --git a/Help/command/install.rst b/Help/command/install.rst
index c99ed73..423899e 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -192,6 +192,10 @@ The list of ``files...`` given to ``FILES`` or ``PROGRAMS`` may use
 However, if any item begins in a generator expression it must evaluate
 to a full path.
 
+The install destination given to the files install ``DESTINATION`` may
+use "generator expressions" with the syntax ``$<...>``.  See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+
 Installing Directories
 ^^^^^^^^^^^^^^^^^^^^^^
 
@@ -267,6 +271,10 @@ will install the ``icons`` directory to ``share/myproj/icons`` and the
 file permissions, the scripts will be given specific permissions, and any
 ``CVS`` directories will be excluded.
 
+The install destination given to the directory install ``DESTINATION`` may
+use "generator expressions" with the syntax ``$<...>``.  See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+
 Custom Installation Logic
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Help/command/install_files.rst b/Help/command/install_files.rst
index 7b6bd81..1850be6 100644
--- a/Help/command/install_files.rst
+++ b/Help/command/install_files.rst
@@ -1,13 +1,13 @@
 install_files
 -------------
 
-Deprecated.  Use the install(FILES ) command instead.
+Deprecated.  Use the :command:`install(FILES)` command instead.
 
-This command has been superceded by the install command.  It is
-provided for compatibility with older CMake code.  The FILES form is
-directly replaced by the FILES form of the install command.  The
-regexp form can be expressed more clearly using the GLOB form of the
-file command.
+This command has been superceded by the :command:`install` command.  It is
+provided for compatibility with older CMake code.  The ``FILES`` form is
+directly replaced by the ``FILES`` form of the :command:`install`
+command.  The regexp form can be expressed more clearly using the ``GLOB``
+form of the :command:`file` command.
 
 ::
 
@@ -32,8 +32,8 @@ expression will be installed.
 
   install_files(<dir> FILES file file ...)
 
-Any files listed after the FILES keyword will be installed explicitly
+Any files listed after the ``FILES`` keyword will be installed explicitly
 from the names given.  Full paths are allowed in this form.
 
-The directory <dir> is relative to the installation prefix, which is
-stored in the variable CMAKE_INSTALL_PREFIX.
+The directory ``<dir>`` is relative to the installation prefix, which is
+stored in the variable :variable:`CMAKE_INSTALL_PREFIX`.
diff --git a/Help/command/install_programs.rst b/Help/command/install_programs.rst
index 26789d8..79aa486 100644
--- a/Help/command/install_programs.rst
+++ b/Help/command/install_programs.rst
@@ -1,13 +1,13 @@
 install_programs
 ----------------
 
-Deprecated. Use the install(PROGRAMS ) command instead.
+Deprecated. Use the :command:`install(PROGRAMS)` command instead.
 
-This command has been superceded by the install command.  It is
-provided for compatibility with older CMake code.  The FILES form is
-directly replaced by the PROGRAMS form of the INSTALL command.  The
-regexp form can be expressed more clearly using the GLOB form of the
-FILE command.
+This command has been superceded by the :command:`install` command.  It is
+provided for compatibility with older CMake code.  The ``FILES`` form is
+directly replaced by the ``PROGRAMS`` form of the :command:`install`
+command.  The regexp form can be expressed more clearly using the ``GLOB``
+form of the :command:`file` command.
 
 ::
 
@@ -15,7 +15,7 @@ FILE command.
   install_programs(<dir> FILES file1 [file2 ...])
 
 Create rules to install the listed programs into the given directory.
-Use the FILES argument to guarantee that the file list version of the
+Use the ``FILES`` argument to guarantee that the file list version of the
 command will be used even when there is only one argument.
 
 ::
@@ -26,8 +26,9 @@ In the second form any program in the current source directory that
 matches the regular expression will be installed.
 
 This command is intended to install programs that are not built by
-cmake, such as shell scripts.  See the TARGETS form of the INSTALL
-command to create installation rules for targets built by cmake.
+cmake, such as shell scripts.  See the ``TARGETS`` form of the
+:command:`install` command to create installation rules for targets built
+by cmake.
 
-The directory <dir> is relative to the installation prefix, which is
-stored in the variable CMAKE_INSTALL_PREFIX.
+The directory ``<dir>`` is relative to the installation prefix, which is
+stored in the variable :variable:`CMAKE_INSTALL_PREFIX`.
diff --git a/Help/command/install_targets.rst b/Help/command/install_targets.rst
index caa933f..49ca696 100644
--- a/Help/command/install_targets.rst
+++ b/Help/command/install_targets.rst
@@ -1,9 +1,9 @@
 install_targets
 ---------------
 
-Deprecated. Use the install(TARGETS )  command instead.
+Deprecated. Use the :command:`install(TARGETS)` command instead.
 
-This command has been superceded by the install command.  It is
+This command has been superceded by the :command:`install` command.  It is
 provided for compatibility with older CMake code.
 
 ::
@@ -11,7 +11,7 @@ provided for compatibility with older CMake code.
   install_targets(<dir> [RUNTIME_DIRECTORY dir] target target)
 
 Create rules to install the listed targets into the given directory.
-The directory <dir> is relative to the installation prefix, which is
-stored in the variable CMAKE_INSTALL_PREFIX.  If RUNTIME_DIRECTORY is
-specified, then on systems with special runtime files (Windows DLL),
-the files will be copied to that directory.
+The directory ``<dir>`` is relative to the installation prefix, which is
+stored in the variable :variable:`CMAKE_INSTALL_PREFIX`.  If
+``RUNTIME_DIRECTORY`` is specified, then on systems with special runtime
+files (Windows DLL), the files will be copied to that directory.
diff --git a/Help/command/link_directories.rst b/Help/command/link_directories.rst
index bdc94cd..5c64bc6 100644
--- a/Help/command/link_directories.rst
+++ b/Help/command/link_directories.rst
@@ -10,10 +10,10 @@ Specify directories in which the linker will look for libraries.
 Specify the paths in which the linker should search for libraries.
 The command will apply only to targets created after it is called.
 Relative paths given to this command are interpreted as relative to
-the current source directory, see CMP0015.
+the current source directory, see :policy:`CMP0015`.
 
 Note that this command is rarely necessary.  Library locations
-returned by find_package() and find_library() are absolute paths.
-Pass these absolute library file paths directly to the
-target_link_libraries() command.  CMake will ensure the linker finds
+returned by :command:`find_package` and :command:`find_library` are
+absolute paths. Pass these absolute library file paths directly to the
+:command:`target_link_libraries` command.  CMake will ensure the linker finds
 them.
diff --git a/Help/command/list.rst b/Help/command/list.rst
index aeb1e94..a7a05c7 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -17,45 +17,45 @@ List operations.
   list(REVERSE <list>)
   list(SORT <list>)
 
-LENGTH will return a given list's length.
+``LENGTH`` will return a given list's length.
 
-GET will return list of elements specified by indices from the list.
+``GET`` will return list of elements specified by indices from the list.
 
-APPEND will append elements to the list.
+``APPEND`` will append elements to the list.
 
-FIND will return the index of the element specified in the list or -1
+``FIND`` will return the index of the element specified in the list or -1
 if it wasn't found.
 
-INSERT will insert elements to the list to the specified location.
+``INSERT`` will insert elements to the list to the specified location.
 
-REMOVE_AT and REMOVE_ITEM will remove items from the list.  The
-difference is that REMOVE_ITEM will remove the given items, while
-REMOVE_AT will remove the items at the given indices.
+``REMOVE_AT`` and ``REMOVE_ITEM`` will remove items from the list.  The
+difference is that ``REMOVE_ITEM`` will remove the given items, while
+``REMOVE_AT`` will remove the items at the given indices.
 
-REMOVE_DUPLICATES will remove duplicated items in the list.
+``REMOVE_DUPLICATES`` will remove duplicated items in the list.
 
-REVERSE reverses the contents of the list in-place.
+``REVERSE`` reverses the contents of the list in-place.
 
-SORT sorts the list in-place alphabetically.
+``SORT`` sorts the list in-place alphabetically.
 
-The list subcommands APPEND, INSERT, REMOVE_AT, REMOVE_ITEM,
-REMOVE_DUPLICATES, REVERSE and SORT may create new values for the list
-within the current CMake variable scope.  Similar to the SET command,
-the LIST command creates new variable values in the current scope,
-even if the list itself is actually defined in a parent scope.  To
-propagate the results of these operations upwards, use SET with
-PARENT_SCOPE, SET with CACHE INTERNAL, or some other means of value
-propagation.
+The list subcommands ``APPEND``, ``INSERT``, ``REMOVE_AT``, ``REMOVE_ITEM``,
+``REMOVE_DUPLICATES``, ``REVERSE`` and ``SORT`` may create new values for
+the list within the current CMake variable scope.  Similar to the
+:command:`set` command, the LIST command creates new variable values in the
+current scope, even if the list itself is actually defined in a parent
+scope.  To propagate the results of these operations upwards, use
+:command:`set` with ``PARENT_SCOPE``, :command:`set` with
+``CACHE INTERNAL``, or some other means of value propagation.
 
-NOTES: A list in cmake is a ; separated group of strings.  To create a
-list the set command can be used.  For example, set(var a b c d e)
-creates a list with a;b;c;d;e, and set(var "a b c d e") creates a
+NOTES: A list in cmake is a ``;`` separated group of strings.  To create a
+list the set command can be used.  For example, ``set(var a b c d e)``
+creates a list with ``a;b;c;d;e``, and ``set(var "a b c d e")`` creates a
 string or a list with one item in it.   (Note macro arguments are not
 variables, and therefore cannot be used in LIST commands.)
 
-When specifying index values, if <element index> is 0 or greater, it
+When specifying index values, if ``<element index>`` is 0 or greater, it
 is indexed from the beginning of the list, with 0 representing the
-first list element.  If <element index> is -1 or lesser, it is indexed
+first list element.  If ``<element index>`` is -1 or lesser, it is indexed
 from the end of the list, with -1 representing the last list element.
 Be careful when counting with negative indices: they do not start from
 0.  -0 is equivalent to 0, the first list element.
diff --git a/Help/command/load_cache.rst b/Help/command/load_cache.rst
index b7484cb..f113447 100644
--- a/Help/command/load_cache.rst
+++ b/Help/command/load_cache.rst
@@ -19,9 +19,9 @@ does not create entries in the local project's cache.
 
 Load in the values from another cache and store them in the local
 project's cache as internal entries.  This is useful for a project
-that depends on another project built in a different tree.  EXCLUDE
+that depends on another project built in a different tree.  ``EXCLUDE``
 option can be used to provide a list of entries to be excluded.
-INCLUDE_INTERNALS can be used to provide a list of internal entries to
+``INCLUDE_INTERNALS`` can be used to provide a list of internal entries to
 be included.  Normally, no internal entries are brought in.  Use of
 this form of the command is strongly discouraged, but it is provided
 for backward compatibility.
diff --git a/Help/command/load_command.rst b/Help/command/load_command.rst
index fc316d4..a1576e8 100644
--- a/Help/command/load_command.rst
+++ b/Help/command/load_command.rst
@@ -11,9 +11,9 @@ Load a command into a running CMake.
 
 The given locations are searched for a library whose name is
 cmCOMMAND_NAME.  If found, it is loaded as a module and the command is
-added to the set of available CMake commands.  Usually, TRY_COMPILE is
-used before this command to compile the module.  If the command is
-successfully loaded a variable named
+added to the set of available CMake commands.  Usually,
+:command:`try_compile` is used before this command to compile the
+module.  If the command is successfully loaded a variable named
 
 ::
 
diff --git a/Help/command/make_directory.rst b/Help/command/make_directory.rst
index 44dbe97..27ecf51 100644
--- a/Help/command/make_directory.rst
+++ b/Help/command/make_directory.rst
@@ -1,7 +1,7 @@
 make_directory
 --------------
 
-Deprecated. Use the file(MAKE_DIRECTORY ) command instead.
+Deprecated. Use the :command:`file(MAKE_DIRECTORY)` command instead.
 
 ::
 
diff --git a/Help/command/mark_as_advanced.rst b/Help/command/mark_as_advanced.rst
index 30b1289..c3f94fc 100644
--- a/Help/command/mark_as_advanced.rst
+++ b/Help/command/mark_as_advanced.rst
@@ -9,10 +9,10 @@ Mark cmake cached variables as advanced.
 
 Mark the named cached variables as advanced.  An advanced variable
 will not be displayed in any of the cmake GUIs unless the show
-advanced option is on.  If CLEAR is the first argument advanced
-variables are changed back to unadvanced.  If FORCE is the first
-argument, then the variable is made advanced.  If neither FORCE nor
-CLEAR is specified, new values will be marked as advanced, but if the
+advanced option is on.  If ``CLEAR`` is the first argument advanced
+variables are changed back to unadvanced.  If ``FORCE`` is the first
+argument, then the variable is made advanced.  If neither ``FORCE`` nor
+``CLEAR`` is specified, new values will be marked as advanced, but if the
 variable already has an advanced/non-advanced state, it will not be
 changed.
 
diff --git a/Help/command/math.rst b/Help/command/math.rst
index 38fde1d..d4deb16 100644
--- a/Help/command/math.rst
+++ b/Help/command/math.rst
@@ -7,7 +7,7 @@ Mathematical expressions.
 
   math(EXPR <output variable> <math expression>)
 
-EXPR evaluates mathematical expression and returns result in the
+``EXPR`` evaluates mathematical expression and returns result in the
 output variable.  Example mathematical expression is '5 * ( 10 + 13
 )'.  Supported operators are + - * / % | & ^ ~ << >> * / %.  They have
 the same meaning as they do in C code.
diff --git a/Help/command/message.rst b/Help/command/message.rst
index a20325a..04c62fd 100644
--- a/Help/command/message.rst
+++ b/Help/command/message.rst
@@ -7,7 +7,7 @@ Display a message to the user.
 
   message([<mode>] "message to display" ...)
 
-The optional <mode> keyword determines the type of message:
+The optional ``<mode>`` keyword determines the type of message:
 
 ::
 
diff --git a/Help/command/option.rst b/Help/command/option.rst
index 244ed07..91cd0a7 100644
--- a/Help/command/option.rst
+++ b/Help/command/option.rst
@@ -8,8 +8,8 @@ Provides an option that the user can optionally select.
   option(<option_variable> "help string describing option"
          [initial value])
 
-Provide an option for the user to select as ON or OFF.  If no initial
-value is provided, OFF is used.
+Provide an option for the user to select as ``ON`` or ``OFF``.  If no
+initial value is provided, ``OFF`` is used.
 
 If you have options that depend on the values of other options, see
-the module help for CMakeDependentOption.
+the module help for :module:`CMakeDependentOption`.
diff --git a/Help/command/qt_wrap_cpp.rst b/Help/command/qt_wrap_cpp.rst
index 81bbc06..3843bf5 100644
--- a/Help/command/qt_wrap_cpp.rst
+++ b/Help/command/qt_wrap_cpp.rst
@@ -9,4 +9,4 @@ Create Qt Wrappers.
               SourceLists ...)
 
 Produce moc files for all the .h files listed in the SourceLists.  The
-moc files will be added to the library using the DestName source list.
+moc files will be added to the library using the ``DestName`` source list.
diff --git a/Help/command/qt_wrap_ui.rst b/Help/command/qt_wrap_ui.rst
index 4e033a8..f731ed9 100644
--- a/Help/command/qt_wrap_ui.rst
+++ b/Help/command/qt_wrap_ui.rst
@@ -9,6 +9,6 @@ Create Qt user interfaces Wrappers.
              SourcesDestName SourceLists ...)
 
 Produce .h and .cxx files for all the .ui files listed in the
-SourceLists.  The .h files will be added to the library using the
-HeadersDestNamesource list.  The .cxx files will be added to the
-library using the SourcesDestNamesource list.
+``SourceLists``.  The .h files will be added to the library using the
+``HeadersDestNamesource`` list.  The .cxx files will be added to the
+library using the ``SourcesDestNamesource`` list.
diff --git a/Help/command/remove.rst b/Help/command/remove.rst
index ddf0e9a..4628277 100644
--- a/Help/command/remove.rst
+++ b/Help/command/remove.rst
@@ -1,12 +1,12 @@
 remove
 ------
 
-Deprecated. Use the list(REMOVE_ITEM ) command instead.
+Deprecated. Use the :command:`list(REMOVE_ITEM)` command instead.
 
 ::
 
   remove(VAR VALUE VALUE ...)
 
-Removes VALUE from the variable VAR.  This is typically used to remove
-entries from a vector (e.g.  semicolon separated list).  VALUE is
-expanded.
+Removes ``VALUE`` from the variable ``VAR``.  This is typically used to
+remove entries from a vector (e.g.  semicolon separated list).  ``VALUE``
+is expanded.
diff --git a/Help/command/remove_definitions.rst b/Help/command/remove_definitions.rst
index 566da6e..ea18918 100644
--- a/Help/command/remove_definitions.rst
+++ b/Help/command/remove_definitions.rst
@@ -1,11 +1,11 @@
 remove_definitions
 ------------------
 
-Removes -D define flags added by add_definitions.
+Removes -D define flags added by :command:`add_definitions`.
 
 ::
 
   remove_definitions(-DFOO -DBAR ...)
 
-Removes flags (added by add_definitions) from the compiler command
-line for sources in the current directory and below.
+Removes flags (added by :command:`add_definitions`) from the compiler
+command line for sources in the current directory and below.
diff --git a/Help/command/return.rst b/Help/command/return.rst
index 899470c..e49fb3c 100644
--- a/Help/command/return.rst
+++ b/Help/command/return.rst
@@ -8,11 +8,11 @@ Return from a file, directory or function.
   return()
 
 Returns from a file, directory or function.  When this command is
-encountered in an included file (via include() or find_package()), it
-causes processing of the current file to stop and control is returned
-to the including file.  If it is encountered in a file which is not
-included by another file, e.g.  a CMakeLists.txt, control is returned
-to the parent directory if there is one.  If return is called in a
-function, control is returned to the caller of the function.  Note
-that a macro is not a function and does not handle return like a
+encountered in an included file (via :command:`include` or
+:command:`find_package`), it causes processing of the current file to stop
+and control is returned to the including file.  If it is encountered in a
+file which is not included by another file, e.g.  a ``CMakeLists.txt``,
+control is returned to the parent directory if there is one.  If return is
+called in a function, control is returned to the caller of the function.
+Note that a macro is not a function and does not handle return like a
 function does.
diff --git a/Help/command/separate_arguments.rst b/Help/command/separate_arguments.rst
index a876595..0e3e5a5 100644
--- a/Help/command/separate_arguments.rst
+++ b/Help/command/separate_arguments.rst
@@ -8,15 +8,15 @@ Parse space-separated arguments into a semicolon-separated list.
   separate_arguments(<var> <UNIX|WINDOWS>_COMMAND "<args>")
 
 Parses a unix- or windows-style command-line string "<args>" and
-stores a semicolon-separated list of the arguments in <var>.  The
+stores a semicolon-separated list of the arguments in ``<var>``.  The
 entire command line must be given in one "<args>" argument.
 
-The UNIX_COMMAND mode separates arguments by unquoted whitespace.  It
+The ``UNIX_COMMAND`` mode separates arguments by unquoted whitespace.  It
 recognizes both single-quote and double-quote pairs.  A backslash
 escapes the next literal character (\" is "); there are no special
 escapes (\n is just n).
 
-The WINDOWS_COMMAND mode parses a windows command-line using the same
+The ``WINDOWS_COMMAND`` mode parses a windows command-line using the same
 syntax the runtime library uses to construct argv at startup.  It
 separates arguments by whitespace that is not double-quoted.
 Backslashes are literal unless they precede double-quotes.  See the
@@ -26,6 +26,6 @@ MSDN article "Parsing C Command-Line Arguments" for details.
 
   separate_arguments(VARIABLE)
 
-Convert the value of VARIABLE to a semi-colon separated list.  All
+Convert the value of ``VARIABLE`` to a semi-colon separated list.  All
 spaces are replaced with ';'.  This helps with generating command
 lines.
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
index 6200230..5ed788e 100644
--- a/Help/command/set_property.rst
+++ b/Help/command/set_property.rst
@@ -64,3 +64,6 @@ property value in the form of a semicolon-separated list.  If the
 value.  If the ``APPEND_STRING`` option is given the string is append to any
 existing property value as string, i.e.  it results in a longer string
 and not a list of strings.
+
+See the :manual:`cmake-properties(7)` manual for a list of properties
+in each scope.
diff --git a/Help/command/set_target_properties.rst b/Help/command/set_target_properties.rst
index f65ee24..b894eac 100644
--- a/Help/command/set_target_properties.rst
+++ b/Help/command/set_target_properties.rst
@@ -12,93 +12,7 @@ Targets can have properties that affect how they are built.
 Set properties on a target.  The syntax for the command is to list all
 the files you want to change, and then provide the values you want to
 set next.  You can use any prop value pair you want and extract it
-later with the GET_TARGET_PROPERTY command.
+later with the :command:`get_property` or :command:`get_target_property`
+command.
 
-Properties that affect the name of a target's output file are as
-follows.  The PREFIX and SUFFIX properties override the default target
-name prefix (such as "lib") and suffix (such as ".so").  IMPORT_PREFIX
-and IMPORT_SUFFIX are the equivalent properties for the import library
-corresponding to a DLL (for SHARED library targets).  OUTPUT_NAME sets
-the real name of a target when it is built and can be used to help
-create two targets of the same name even though CMake requires unique
-logical target names.  There is also a <CONFIG>_OUTPUT_NAME that can
-set the output name on a per-configuration basis.  <CONFIG>_POSTFIX
-sets a postfix for the real name of the target when it is built under
-the configuration named by <CONFIG> (in upper-case, such as
-"DEBUG_POSTFIX").  The value of this property is initialized when the
-target is created to the value of the variable CMAKE_<CONFIG>_POSTFIX
-(except for executable targets because earlier CMake versions which
-did not use this variable for executables).
-
-The LINK_FLAGS property can be used to add extra flags to the link
-step of a target.  LINK_FLAGS_<CONFIG> will add to the configuration
-<CONFIG>, for example, DEBUG, RELEASE, MINSIZEREL, RELWITHDEBINFO.
-DEFINE_SYMBOL sets the name of the preprocessor symbol defined when
-compiling sources in a shared library.  If not set here then it is set
-to target_EXPORTS by default (with some substitutions if the target is
-not a valid C identifier).  This is useful for headers to know whether
-they are being included from inside their library or outside to
-properly setup dllexport/dllimport decorations.  The COMPILE_FLAGS
-property sets additional compiler flags used to build sources within
-the target.  It may also be used to pass additional preprocessor
-definitions.
-
-The LINKER_LANGUAGE property is used to change the tool used to link
-an executable or shared library.  The default is set the language to
-match the files in the library.  CXX and C are common values for this
-property.
-
-For shared libraries VERSION and SOVERSION can be used to specify the
-build version and API version respectively.  When building or
-installing appropriate symlinks are created if the platform supports
-symlinks and the linker supports so-names.  If only one of both is
-specified the missing is assumed to have the same version number.  For
-executables VERSION can be used to specify the build version.  When
-building or installing appropriate symlinks are created if the
-platform supports symlinks.  For shared libraries and executables on
-Windows the VERSION attribute is parsed to extract a "major.minor"
-version number.  These numbers are used as the image version of the
-binary.
-
-There are a few properties used to specify RPATH rules.  INSTALL_RPATH
-is a semicolon-separated list specifying the rpath to use in installed
-targets (for platforms that support it).  INSTALL_RPATH_USE_LINK_PATH
-is a boolean that if set to true will append directories in the linker
-search path and outside the project to the INSTALL_RPATH.
-SKIP_BUILD_RPATH is a boolean specifying whether to skip automatic
-generation of an rpath allowing the target to run from the build tree.
-BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link the
-target in the build tree with the INSTALL_RPATH.  This takes
-precedence over SKIP_BUILD_RPATH and avoids the need for relinking
-before installation.  INSTALL_NAME_DIR is a string specifying the
-directory portion of the "install_name" field of shared libraries on
-Mac OSX to use in the installed targets.  When the target is created
-the values of the variables CMAKE_INSTALL_RPATH,
-CMAKE_INSTALL_RPATH_USE_LINK_PATH, CMAKE_SKIP_BUILD_RPATH,
-CMAKE_BUILD_WITH_INSTALL_RPATH, and CMAKE_INSTALL_NAME_DIR are used to
-initialize these properties.
-
-PROJECT_LABEL can be used to change the name of the target in an IDE
-like visual studio.  VS_KEYWORD can be set to change the visual studio
-keyword, for example Qt integration works better if this is set to
-Qt4VSv1.0.
-
-VS_SCC_PROJECTNAME, VS_SCC_LOCALPATH, VS_SCC_PROVIDER and
-VS_SCC_AUXPATH can be set to add support for source control bindings
-in a Visual Studio project file.
-
-VS_GLOBAL_<variable> can be set to add a Visual Studio
-project-specific global variable.  Qt integration works better if
-VS_GLOBAL_QtVersion is set to the Qt version FindQt4.cmake found.  For
-example, "4.7.3"
-
-The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the old
-way to specify CMake scripts to run before and after installing a
-target.  They are used only when the old INSTALL_TARGETS command is
-used to install the target.  Use the INSTALL command instead.
-
-The EXCLUDE_FROM_DEFAULT_BUILD property is used by the visual studio
-generators.  If it is set to 1 the target will not be part of the
-default build when you select "Build Solution".  This can also be set
-on a per-configuration basis using
-EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>.
+See :ref:`Target Properties` for the list of properties known to CMake.
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 351385b..0361c74 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -1,99 +1,84 @@
 string
 ------
 
+.. only:: html
+
+   .. contents::
+
 String operations.
 
+Search and Replace
+^^^^^^^^^^^^^^^^^^
+
+FIND
+""""
+
+::
+
+  string(FIND <string> <substring> <output variable> [REVERSE])
+
+Return the position where the given substring was found in
+the supplied string.  If the ``REVERSE`` flag was used, the command will
+search for the position of the last occurrence of the specified
+substring.  If the substring is not found, a position of -1 is returned.
+
+REPLACE
+"""""""
+
 ::
 
-  string(REGEX MATCH <regular_expression>
-         <output variable> <input> [<input>...])
-  string(REGEX MATCHALL <regular_expression>
-         <output variable> <input> [<input>...])
-  string(REGEX REPLACE <regular_expression>
-         <replace_expression> <output variable>
-         <input> [<input>...])
   string(REPLACE <match_string>
          <replace_string> <output variable>
          <input> [<input>...])
-  string(CONCAT <output variable> [<input>...])
-  string(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512>
-         <output variable> <input>)
-  string(COMPARE EQUAL <string1> <string2> <output variable>)
-  string(COMPARE NOTEQUAL <string1> <string2> <output variable>)
-  string(COMPARE LESS <string1> <string2> <output variable>)
-  string(COMPARE GREATER <string1> <string2> <output variable>)
-  string(ASCII <number> [<number> ...] <output variable>)
-  string(CONFIGURE <string1> <output variable>
-         [@ONLY] [ESCAPE_QUOTES])
-  string(TOUPPER <string1> <output variable>)
-  string(TOLOWER <string1> <output variable>)
-  string(LENGTH <string> <output variable>)
-  string(SUBSTRING <string> <begin> <length> <output variable>)
-  string(STRIP <string> <output variable>)
-  string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]
-         [RANDOM_SEED <seed>] <output variable>)
-  string(FIND <string> <substring> <output variable> [REVERSE])
-  string(TIMESTAMP <output variable> [<format string>] [UTC])
-  string(MAKE_C_IDENTIFIER <input string> <output variable>)
-  string(GENEX_STRIP <input string> <output variable>)
-  string(UUID <output variable> NAMESPACE <namespace> NAME <name>
-         TYPE <MD5|SHA1> [UPPER])
 
-REGEX MATCH will match the regular expression once and store the match
-in the output variable.
+Replace all occurrences of ``match_string`` in the input
+with ``replace_string`` and store the result in the output.
 
-REGEX MATCHALL will match the regular expression as many times as
-possible and store the matches in the output variable as a list.
+Regular Expressions
+^^^^^^^^^^^^^^^^^^^
 
-REGEX REPLACE will match the regular expression as many times as
-possible and substitute the replacement expression for the match in
-the output.  The replace expression may refer to paren-delimited
-subexpressions of the match using \1, \2, ..., \9.  Note that two
-backslashes (\\1) are required in CMake code to get a backslash
-through argument parsing.
+REGEX MATCH
+"""""""""""
 
-REPLACE will replace all occurrences of match_string in the input with
-replace_string and store the result in the output.
+::
 
-CONCAT will concatenate all the input arguments together and store
-the result in the named output variable.
+  string(REGEX MATCH <regular_expression>
+         <output variable> <input> [<input>...])
 
-MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 will compute a
-cryptographic hash of the input string.
+Match the regular expression once and store the match in the output variable.
+All ``<input>`` arguments are concatenated before matching.
 
-COMPARE EQUAL/NOTEQUAL/LESS/GREATER will compare the strings and store
-true or false in the output variable.
+REGEX MATCHALL
+""""""""""""""
 
-ASCII will convert all numbers into corresponding ASCII characters.
+::
 
-CONFIGURE will transform a string like CONFIGURE_FILE transforms a
-file.
+  string(REGEX MATCHALL <regular_expression>
+         <output variable> <input> [<input>...])
 
-TOUPPER/TOLOWER will convert string to upper/lower characters.
+Match the regular expression as many times as possible and store the matches
+in the output variable as a list.
+All ``<input>`` arguments are concatenated before matching.
 
-LENGTH will return a given string's length.
+REGEX REPLACE
+"""""""""""""
 
-SUBSTRING will return a substring of a given string. If length is -1
-the remainder of the string starting at begin will be returned.
-If string is shorter than length then end of string is used instead.
+::
 
-.. note::
-  CMake 3.1 and below reported an error if length pointed past
-  the end of string.
+  string(REGEX REPLACE <regular_expression>
+         <replace_expression> <output variable>
+         <input> [<input>...])
 
-STRIP will return a substring of a given string with leading and
-trailing spaces removed.
+Match the regular expression as many times as possible and substitute the
+replacement expression for the match in the output.
+All ``<input>`` arguments are concatenated before matching.
 
-RANDOM will return a random string of given length consisting of
-characters from the given alphabet.  Default length is 5 characters
-and default alphabet is all numbers and upper and lower case letters.
-If an integer RANDOM_SEED is given, its value will be used to seed the
-random number generator.
+The replace expression may refer to paren-delimited subexpressions of the
+match using ``\1``, ``\2``, ..., ``\9``.  Note that two backslashes (``\\1``)
+are required in CMake code to get a backslash through argument parsing.
 
-FIND will return the position where the given substring was found in
-the supplied string.  If the REVERSE flag was used, the command will
-search for the position of the last occurrence of the specified
-substring.
+Regex Specification
+"""""""""""""""""""
 
 The following characters have special meaning in regular expressions:
 
@@ -118,21 +103,170 @@ The following characters have special meaning in regular expressions:
              by all regular expression-related commands, including
              e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).
 
-``*``, ``+`` and ``?`` have higher precedence than concatenation.  | has lower
-precedence than concatenation.  This means that the regular expression
-"^ab+d$" matches "abbd" but not "ababd", and the regular expression
-"^(ab|cd)$" matches "ab" but not "abd".
+``*``, ``+`` and ``?`` have higher precedence than concatenation.  ``|``
+has lower precedence than concatenation.  This means that the regular
+expression ``^ab+d$`` matches ``abbd`` but not ``ababd``, and the regular
+expression ``^(ab|cd)$`` matches ``ab`` but not ``abd``.
+
+Manipulation
+^^^^^^^^^^^^
+
+APPEND
+""""""
+
+::
+
+  string(APPEND <string variable> [<input>...])
+
+Append all the input arguments to the string.
+
+CONCAT
+""""""
+
+::
+
+  string(CONCAT <output variable> [<input>...])
+
+Concatenate all the input arguments together and store
+the result in the named output variable.
+
+TOLOWER
+"""""""
+
+::
+
+  string(TOLOWER <string1> <output variable>)
+
+Convert string to lower characters.
+
+TOUPPER
+"""""""
+
+::
+
+  string(TOUPPER <string1> <output variable>)
+
+Convert string to upper characters.
 
-TIMESTAMP will write a string representation of the current date
+LENGTH
+""""""
+
+::
+
+  string(LENGTH <string> <output variable>)
+
+Store in an output variable a given string's length.
+
+SUBSTRING
+"""""""""
+
+::
+
+  string(SUBSTRING <string> <begin> <length> <output variable>)
+
+Store in an output variable a substring of a given string.  If length is
+``-1`` the remainder of the string starting at begin will be returned.
+If string is shorter than length then end of string is used instead.
+
+.. note::
+  CMake 3.1 and below reported an error if length pointed past
+  the end of string.
+
+STRIP
+"""""
+
+::
+
+  string(STRIP <string> <output variable>)
+
+Store in an output variable a substring of a given string with leading and
+trailing spaces removed.
+
+GENEX_STRIP
+"""""""""""
+
+::
+
+  string(GENEX_STRIP <input string> <output variable>)
+
+Strip any :manual:`generator expressions <cmake-generator-expressions(7)>`
+from the ``input string`` and store the result in the ``output variable``.
+
+Comparison
+^^^^^^^^^^
+
+::
+
+  string(COMPARE EQUAL <string1> <string2> <output variable>)
+  string(COMPARE NOTEQUAL <string1> <string2> <output variable>)
+  string(COMPARE LESS <string1> <string2> <output variable>)
+  string(COMPARE GREATER <string1> <string2> <output variable>)
+
+Compare the strings and store true or false in the output variable.
+
+Hashing
+^^^^^^^
+
+::
+
+  string(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512>
+         <output variable> <input>)
+
+Compute a cryptographic hash of the input string.
+
+Generation
+^^^^^^^^^^
+
+ASCII
+"""""
+
+::
+
+  string(ASCII <number> [<number> ...] <output variable>)
+
+Convert all numbers into corresponding ASCII characters.
+
+CONFIGURE
+"""""""""
+
+::
+
+  string(CONFIGURE <string1> <output variable>
+         [@ONLY] [ESCAPE_QUOTES])
+
+Transform a string like :command:`configure_file` transforms a file.
+
+RANDOM
+""""""
+
+::
+
+  string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]
+         [RANDOM_SEED <seed>] <output variable>)
+
+Return a random string of given length consisting of
+characters from the given alphabet.  Default length is 5 characters
+and default alphabet is all numbers and upper and lower case letters.
+If an integer ``RANDOM_SEED`` is given, its value will be used to seed the
+random number generator.
+
+TIMESTAMP
+"""""""""
+
+::
+
+  string(TIMESTAMP <output variable> [<format string>] [UTC])
+
+Write a string representation of the current date
 and/or time to the output variable.
 
 Should the command be unable to obtain a timestamp the output variable
 will be set to the empty string "".
 
-The optional UTC flag requests the current date/time representation to
+The optional ``UTC`` flag requests the current date/time representation to
 be in Coordinated Universal Time (UTC) rather than local time.
 
-The optional <format string> may contain the following format
+The optional ``<format string>`` may contain the following format
 specifiers:
 
 ::
@@ -153,23 +287,31 @@ specifiers:
 Unknown format specifiers will be ignored and copied to the output
 as-is.
 
-If no explicit <format string> is given it will default to:
+If no explicit ``<format string>`` is given it will default to:
 
 ::
 
    %Y-%m-%dT%H:%M:%S    for local time.
    %Y-%m-%dT%H:%M:%SZ   for UTC.
 
-MAKE_C_IDENTIFIER will write a string which can be used as an
-identifier in C.
 
-``GENEX_STRIP`` will strip any
-:manual:`generator expressions <cmake-generator-expressions(7)>` from the
-``input string`` and store the result in the ``output variable``.
+::
+
+  string(MAKE_C_IDENTIFIER <input string> <output variable>)
+
+Write a string which can be used as an identifier in C.
+
+UUID
+""""
+
+::
+
+  string(UUID <output variable> NAMESPACE <namespace> NAME <name>
+         TYPE <MD5|SHA1> [UPPER])
 
-UUID creates a univerally unique identifier (aka GUID) as per RFC4122
-based on the hash of the combined values of <namespace>
-(which itself has to be a valid UUID) and <name>.
+Create a univerally unique identifier (aka GUID) as per RFC4122
+based on the hash of the combined values of ``<namespace>``
+(which itself has to be a valid UUID) and ``<name>``.
 The hash algorithm can be either ``MD5`` (Version 3 UUID) or
 ``SHA1`` (Version 5 UUID).
 A UUID has the format ``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``
diff --git a/Help/command/subdirs.rst b/Help/command/subdirs.rst
index dee49f8..43b87d4 100644
--- a/Help/command/subdirs.rst
+++ b/Help/command/subdirs.rst
@@ -1,7 +1,7 @@
 subdirs
 -------
 
-Deprecated. Use the add_subdirectory() command instead.
+Deprecated. Use the :command:`add_subdirectory` command instead.
 
 Add a list of subdirectories to the build.
 
@@ -10,12 +10,12 @@ Add a list of subdirectories to the build.
   subdirs(dir1 dir2 ...[EXCLUDE_FROM_ALL exclude_dir1 exclude_dir2 ...]
           [PREORDER] )
 
-Add a list of subdirectories to the build.  The add_subdirectory
-command should be used instead of subdirs although subdirs will still
+Add a list of subdirectories to the build.  The :command:`add_subdirectory`
+command should be used instead of ``subdirs`` although ``subdirs`` will still
 work.  This will cause any CMakeLists.txt files in the sub directories
-to be processed by CMake.  Any directories after the PREORDER flag are
-traversed first by makefile builds, the PREORDER flag has no effect on
-IDE projects.  Any directories after the EXCLUDE_FROM_ALL marker will
+to be processed by CMake.  Any directories after the ``PREORDER`` flag are
+traversed first by makefile builds, the ``PREORDER`` flag has no effect on
+IDE projects.  Any directories after the ``EXCLUDE_FROM_ALL`` marker will
 not be included in the top level makefile or project file.  This is
 useful for having CMake create makefiles or projects for a set of
 examples in a project.  You would want CMake to generate makefiles or
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 9a70885..28dae80 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -96,5 +96,19 @@ the try_compile call of interest, and then re-run cmake again with
 Other Behavior Settings
 ^^^^^^^^^^^^^^^^^^^^^^^
 
+If set, the following variables are passed in to the generated
+try_compile CMakeLists.txt to initialize compile target properties with
+default values:
+
+* :variable:`CMAKE_ENABLE_EXPORTS`
+* :variable:`CMAKE_LINK_SEARCH_START_STATIC`
+* :variable:`CMAKE_LINK_SEARCH_END_STATIC`
+* :variable:`CMAKE_POSITION_INDEPENDENT_CODE`
+
+If :policy:`CMP0056` is set to ``NEW``, then
+:variable:`CMAKE_EXE_LINKER_FLAGS` is passed in as well.
+
+The current setting of :policy:`CMP0065` is set in the generated project.
+
 Set the :variable:`CMAKE_TRY_COMPILE_CONFIGURATION` variable to choose
 a build configuration.
diff --git a/Help/command/unset.rst b/Help/command/unset.rst
index d8f0dcd..a1fc95c 100644
--- a/Help/command/unset.rst
+++ b/Help/command/unset.rst
@@ -8,14 +8,14 @@ Unset a variable, cache variable, or environment variable.
   unset(<variable> [CACHE | PARENT_SCOPE])
 
 Removes the specified variable causing it to become undefined.  If
-CACHE is present then the variable is removed from the cache instead
+``CACHE`` is present then the variable is removed from the cache instead
 of the current scope.
 
-If PARENT_SCOPE is present then the variable is removed from the scope
-above the current scope.  See the same option in the set() command for
-further details.
+If ``PARENT_SCOPE`` is present then the variable is removed from the scope
+above the current scope.  See the same option in the :command:`set` command
+for further details.
 
-<variable> can be an environment variable such as:
+``<variable>`` can be an environment variable such as:
 
 ::
 
diff --git a/Help/command/utility_source.rst b/Help/command/utility_source.rst
index 5122e52..ee34492 100644
--- a/Help/command/utility_source.rst
+++ b/Help/command/utility_source.rst
@@ -12,11 +12,11 @@ Specify the source tree of a third-party utility.
 
 When a third-party utility's source is included in the distribution,
 this command specifies its location and name.  The cache entry will
-not be set unless the path_to_source and all listed files exist.  It
+not be set unless the ``path_to_source`` and all listed files exist.  It
 is assumed that the source tree of the utility will have been built
 before it is needed.
 
-When cross compiling CMake will print a warning if a utility_source()
+When cross compiling CMake will print a warning if a ``utility_source()``
 command is executed, because in many cases it is used to build an
 executable which is executed later on.  This doesn't work when cross
 compiling, since the executable can run only on their target platform.
diff --git a/Help/command/variable_requires.rst b/Help/command/variable_requires.rst
index 831dd00..9cf9f3f 100644
--- a/Help/command/variable_requires.rst
+++ b/Help/command/variable_requires.rst
@@ -3,7 +3,7 @@ variable_requires
 
 Disallowed.  See CMake Policy :policy:`CMP0035`.
 
-Use the if() command instead.
+Use the :command:`if` command instead.
 
 Assert satisfaction of an option's required variables.
 
@@ -13,10 +13,10 @@ Assert satisfaction of an option's required variables.
                     REQUIRED_VARIABLE1
                     REQUIRED_VARIABLE2 ...)
 
-The first argument (TEST_VARIABLE) is the name of the variable to be
+The first argument (``TEST_VARIABLE``) is the name of the variable to be
 tested, if that variable is false nothing else is done.  If
-TEST_VARIABLE is true, then the next argument (RESULT_VARIABLE) is a
-variable that is set to true if all the required variables are set.
+``TEST_VARIABLE`` is true, then the next argument (``RESULT_VARIABLE``)
+is a variable that is set to true if all the required variables are set.
 The rest of the arguments are variables that must be true or not set
 to NOTFOUND to avoid an error.  If any are not true, an error is
 reported.
diff --git a/Help/command/while.rst b/Help/command/while.rst
index 72c055d..7509da3 100644
--- a/Help/command/while.rst
+++ b/Help/command/while.rst
@@ -11,7 +11,7 @@ Evaluate a group of commands while a condition is true
     ...
   endwhile(condition)
 
-All commands between while and the matching endwhile are recorded
-without being invoked.  Once the endwhile is evaluated, the recorded
-list of commands is invoked as long as the condition is true.  The
-condition is evaluated using the same logic as the if command.
+All commands between while and the matching :command:`endwhile` are recorded
+without being invoked.  Once the :command:`endwhile` is evaluated, the
+recorded list of commands is invoked as long as the condition is true.  The
+condition is evaluated using the same logic as the :command:`if` command.
diff --git a/Help/command/write_file.rst b/Help/command/write_file.rst
index 015514b..40e7557 100644
--- a/Help/command/write_file.rst
+++ b/Help/command/write_file.rst
@@ -1,20 +1,20 @@
 write_file
 ----------
 
-Deprecated. Use the file(WRITE ) command instead.
+Deprecated. Use the :command:`file(WRITE)` command instead.
 
 ::
 
   write_file(filename "message to write"... [APPEND])
 
 The first argument is the file name, the rest of the arguments are
-messages to write.  If the argument APPEND is specified, then the
+messages to write.  If the argument ``APPEND`` is specified, then the
 message will be appended.
 
-NOTE 1: file(WRITE ...  and file(APPEND ...  do exactly the same as
-this one but add some more functionality.
+NOTE 1: :command:`file(WRITE)`  and :command:`file(APPEND)`  do exactly
+the same as this one but add some more functionality.
 
-NOTE 2: When using write_file the produced file cannot be used as an
+NOTE 2: When using ``write_file`` the produced file cannot be used as an
 input to CMake (CONFIGURE_FILE, source file ...) because it will lead
-to an infinite loop.  Use configure_file if you want to generate input
-files to CMake.
+to an infinite loop.  Use :command:`configure_file` if you want to
+generate input files to CMake.
diff --git a/Help/manual/LINKS.txt b/Help/manual/LINKS.txt
index 38fd151..3993ff8 100644
--- a/Help/manual/LINKS.txt
+++ b/Help/manual/LINKS.txt
@@ -1,25 +1,25 @@
 The following resources are available to get help using CMake:
 
 Home Page
- http://www.cmake.org
+ https://cmake.org
 
  The primary starting point for learning about CMake.
 
 Frequently Asked Questions
- http://www.cmake.org/Wiki/CMake_FAQ
+ https://cmake.org/Wiki/CMake_FAQ
 
  A Wiki is provided containing answers to frequently asked questions.
 
 Online Documentation
- http://www.cmake.org/documentation
+ https://cmake.org/documentation
 
  Links to available documentation may be found on this web page.
 
 Mailing List
- http://www.cmake.org/mailing-lists
+ https://cmake.org/mailing-lists
 
  For help and discussion about using cmake, a mailing list is
  provided at cmake at cmake.org.  The list is member-post-only but one
  may sign up on the CMake web page.  Please first read the full
- documentation at http://www.cmake.org before posting questions to
+ documentation at https://cmake.org before posting questions to
  the list.
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index aefdb71..bc633e6 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -80,11 +80,31 @@ regardless of the library type.  The ``MODULE`` library type is
 dissimilar in that it is generally not linked to -- it is not used in
 the right-hand-side of the :command:`target_link_libraries` command.
 It is a type which is loaded as a plugin using runtime techniques.
+If the library does not export any unmanaged symbols (e.g. Windows
+resource DLL, C++/CLI DLL), it is required that the library not be a
+``SHARED`` library because CMake expects ``SHARED`` libraries to export
+at least one symbol.
 
 .. code-block:: cmake
 
   add_library(archive MODULE 7z.cpp)
 
+.. _`Apple Frameworks`:
+
+Apple Frameworks
+""""""""""""""""
+
+A ``SHARED`` library may be marked with the :prop_tgt:`FRAMEWORK`
+target property to create an OS X Framework:
+
+.. code-block:: cmake
+
+  add_library(MyFramework SHARED MyFramework.cpp)
+  set_target_properties(MyFramework PROPERTIES
+    FRAMEWORK 1
+    FRAMEWORK_VERSION A
+    )
+
 .. _`Object Libraries`:
 
 Object Libraries
@@ -765,7 +785,8 @@ An *archive* output artifact of a buildsystem target may be:
 
 * On DLL platforms: the import library file (e.g. ``.lib``) of a shared
   library target created by the :command:`add_library` command
-  with the ``SHARED`` option.
+  with the ``SHARED`` option.  This file is only guaranteed to exist if
+  the library exports at least one unmanaged symbol.
 
 * On DLL platforms: the import library file (e.g. ``.lib``) of an
   executable target created by the :command:`add_executable` command
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index c916f77..5b92b51 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -71,7 +71,6 @@ These commands may be used freely in CMake projects.
    /command/link_libraries
    /command/list
    /command/load_cache
-   /command/load_command
    /command/macro
    /command/mark_as_advanced
    /command/math
@@ -119,6 +118,7 @@ versions of CMake.  Do not use them in new code.
    /command/install_files
    /command/install_programs
    /command/install_targets
+   /command/load_command
    /command/make_directory
    /command/output_required_files
    /command/remove
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index 90a081d..a335384 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -52,9 +52,9 @@ When adding the first supported feature to a particular CompilerId, it is
 necessary to list support for all features known to cmake (See
 :variable:`CMAKE_C_COMPILE_FEATURES` and
 :variable:`CMAKE_CXX_COMPILE_FEATURES` as appropriate), where available for
-the compiler.  Furthermore, set ``CMAKE_<LANG>_STANDARD_DEFAULT`` to the
-default language standard level the compiler uses, or to the empty string
-if the compiler has no notion of standard levels (such as ``MSVC``).
+the compiler.  Ensure that the ``CMAKE_<LANG>_STANDARD_DEFAULT`` is set to
+the computed internal variable ``CMAKE_<LANG>_STANDARD_COMPUTED_DEFAULT``
+for compiler versions which should be supported.
 
 It is sensible to record the features for the most recent version of a
 particular CompilerId first, and then work backwards.  It is sensible to
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 189c3ef..13ee4bd 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -278,3 +278,7 @@ Available output expressions are:
   object of type ``OBJECT_LIBRARY``.  This expression may only be used in
   the sources of :command:`add_library` and :command:`add_executable`
   commands.
+``$<SHELL_PATH:...>``
+  Content of ``...`` converted to shell path style. For example, slashes are
+  converted to backslashes in Windows shells and drive letters are converted
+  to posix paths in MSYS shells. The ``...`` must be an absolute path.
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 0a313cd..ae5354f 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -121,3 +121,5 @@ All Policies
    /policy/CMP0061
    /policy/CMP0062
    /policy/CMP0063
+   /policy/CMP0064
+   /policy/CMP0065
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 615254e..931363c 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -40,6 +40,7 @@ Properties of Global Scope
    /prop_gbl/RULE_LAUNCH_LINK
    /prop_gbl/RULE_MESSAGES
    /prop_gbl/TARGET_ARCHIVES_MAY_BE_SHARED_LIBS
+   /prop_gbl/TARGET_MESSAGES
    /prop_gbl/TARGET_SUPPORTS_SHARED_LIBS
    /prop_gbl/USE_FOLDERS
 
@@ -85,9 +86,23 @@ Properties on Targets
    :maxdepth: 1
 
    /prop_tgt/ALIASED_TARGET
+   /prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS
    /prop_tgt/ANDROID_API
    /prop_tgt/ANDROID_API_MIN
+   /prop_tgt/ANDROID_ARCH
+   /prop_tgt/ANDROID_ASSETS_DIRECTORIES
    /prop_tgt/ANDROID_GUI
+   /prop_tgt/ANDROID_JAR_DEPENDENCIES
+   /prop_tgt/ANDROID_JAR_DIRECTORIES
+   /prop_tgt/ANDROID_JAVA_SOURCE_DIR
+   /prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES
+   /prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES
+   /prop_tgt/ANDROID_PROCESS_MAX
+   /prop_tgt/ANDROID_PROGUARD
+   /prop_tgt/ANDROID_PROGUARD_CONFIG_PATH
+   /prop_tgt/ANDROID_SECURE_PROPS_PATH
+   /prop_tgt/ANDROID_SKIP_ANT_STEP
+   /prop_tgt/ANDROID_STL_TYPE
    /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG
    /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY
    /prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG
@@ -99,6 +114,7 @@ Properties on Targets
    /prop_tgt/AUTOUIC_OPTIONS
    /prop_tgt/AUTORCC
    /prop_tgt/AUTORCC_OPTIONS
+   /prop_tgt/BINARY_DIR
    /prop_tgt/BUILD_WITH_INSTALL_RPATH
    /prop_tgt/BUNDLE_EXTENSION
    /prop_tgt/BUNDLE
@@ -135,6 +151,7 @@ Properties on Targets
    /prop_tgt/Fortran_FORMAT
    /prop_tgt/Fortran_MODULE_DIRECTORY
    /prop_tgt/FRAMEWORK
+   /prop_tgt/FRAMEWORK_VERSION
    /prop_tgt/GENERATOR_FILE_NAME
    /prop_tgt/GNUtoMS
    /prop_tgt/HAS_CXX
@@ -177,6 +194,7 @@ Properties on Targets
    /prop_tgt/JOB_POOL_COMPILE
    /prop_tgt/JOB_POOL_LINK
    /prop_tgt/LABELS
+   /prop_tgt/LANG_COMPILER_LAUNCHER
    /prop_tgt/LANG_INCLUDE_WHAT_YOU_USE
    /prop_tgt/LANG_VISIBILITY_PRESET
    /prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG
@@ -227,6 +245,7 @@ Properties on Targets
    /prop_tgt/RUNTIME_OUTPUT_NAME_CONFIG
    /prop_tgt/RUNTIME_OUTPUT_NAME
    /prop_tgt/SKIP_BUILD_RPATH
+   /prop_tgt/SOURCE_DIR
    /prop_tgt/SOURCES
    /prop_tgt/SOVERSION
    /prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG
@@ -235,21 +254,27 @@ Properties on Targets
    /prop_tgt/TYPE
    /prop_tgt/VERSION
    /prop_tgt/VISIBILITY_INLINES_HIDDEN
+   /prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION
    /prop_tgt/VS_DOTNET_REFERENCES
    /prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION
    /prop_tgt/VS_GLOBAL_KEYWORD
    /prop_tgt/VS_GLOBAL_PROJECT_TYPES
    /prop_tgt/VS_GLOBAL_ROOTNAMESPACE
    /prop_tgt/VS_GLOBAL_variable
+   /prop_tgt/VS_IOT_EXTENSIONS_VERSION
+   /prop_tgt/VS_IOT_STARTUP_TASK
    /prop_tgt/VS_KEYWORD
+   /prop_tgt/VS_MOBILE_EXTENSIONS_VERSION
    /prop_tgt/VS_SCC_AUXPATH
    /prop_tgt/VS_SCC_LOCALPATH
    /prop_tgt/VS_SCC_PROJECTNAME
    /prop_tgt/VS_SCC_PROVIDER
+   /prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
    /prop_tgt/VS_WINRT_COMPONENT
    /prop_tgt/VS_WINRT_EXTENSIONS
    /prop_tgt/VS_WINRT_REFERENCES
    /prop_tgt/WIN32_EXECUTABLE
+   /prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS
    /prop_tgt/XCODE_ATTRIBUTE_an-attribute
    /prop_tgt/XCTEST
 
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst
index 054438d..492fcac 100644
--- a/Help/manual/cmake-toolchains.7.rst
+++ b/Help/manual/cmake-toolchains.7.rst
@@ -220,6 +220,23 @@ Windows CE to use.  Currently version 8.0 (Windows Embedded Compact 2013) is
 supported out of the box.  Other versions may require one to set
 :variable:`CMAKE_GENERATOR_TOOLSET` to the correct value.
 
+Cross Compiling for Windows 10 Universal Applications
+-----------------------------------------------------
+
+A toolchain file to configure a Visual Studio generator for a
+Windows 10 Universal Application may look like this:
+
+.. code-block:: cmake
+
+  set(CMAKE_SYSTEM_NAME WindowsStore)
+  set(CMAKE_SYSTEM_VERSION 10.0)
+
+A Windows 10 Universal Application targets both Windows Store and
+Windows Phone.  Specify the :variable:`CMAKE_SYSTEM_VERSION` variable
+to be ``10.0`` to build with the latest available Windows 10 SDK.
+Specify a more specific version (e.g. ``10.0.10240.0`` for RTM)
+to build with the corresponding SDK.
+
 Cross Compiling for Windows Phone
 ---------------------------------
 
@@ -256,6 +273,22 @@ like this:
 The :variable:`CMAKE_GENERATOR_TOOLSET` may be set to select
 the Nsight Tegra "Toolchain Version" value.
 
-See the :prop_tgt:`ANDROID_API_MIN`, :prop_tgt:`ANDROID_API`
-and :prop_tgt:`ANDROID_GUI` target properties to configure
-targets within the project.
+See also target properties:
+
+* :prop_tgt:`ANDROID_ANT_ADDITIONAL_OPTIONS`
+* :prop_tgt:`ANDROID_API_MIN`
+* :prop_tgt:`ANDROID_API`
+* :prop_tgt:`ANDROID_ARCH`
+* :prop_tgt:`ANDROID_ASSETS_DIRECTORIES`
+* :prop_tgt:`ANDROID_GUI`
+* :prop_tgt:`ANDROID_JAR_DEPENDENCIES`
+* :prop_tgt:`ANDROID_JAR_DIRECTORIES`
+* :prop_tgt:`ANDROID_JAVA_SOURCE_DIR`
+* :prop_tgt:`ANDROID_NATIVE_LIB_DEPENDENCIES`
+* :prop_tgt:`ANDROID_NATIVE_LIB_DIRECTORIES`
+* :prop_tgt:`ANDROID_PROCESS_MAX`
+* :prop_tgt:`ANDROID_PROGUARD_CONFIG_PATH`
+* :prop_tgt:`ANDROID_PROGUARD`
+* :prop_tgt:`ANDROID_SECURE_PROPS_PATH`
+* :prop_tgt:`ANDROID_SKIP_ANT_STEP`
+* :prop_tgt:`ANDROID_STL_TYPE`
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index bd02f8b..2116900 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -47,6 +47,8 @@ Variables that Provide Information
    /variable/CMAKE_JOB_POOL_COMPILE
    /variable/CMAKE_JOB_POOL_LINK
    /variable/CMAKE_LINK_LIBRARY_SUFFIX
+   /variable/CMAKE_LINK_SEARCH_END_STATIC
+   /variable/CMAKE_LINK_SEARCH_START_STATIC
    /variable/CMAKE_MAJOR_VERSION
    /variable/CMAKE_MAKE_PROGRAM
    /variable/CMAKE_MATCH_COUNT
@@ -80,6 +82,7 @@ Variables that Provide Information
    /variable/CMAKE_VS_NsightTegra_VERSION
    /variable/CMAKE_VS_PLATFORM_NAME
    /variable/CMAKE_VS_PLATFORM_TOOLSET
+   /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
    /variable/CMAKE_XCODE_PLATFORM_TOOLSET
    /variable/PROJECT_BINARY_DIR
    /variable/PROJECT-NAME_BINARY_DIR
@@ -117,6 +120,8 @@ Variables that Change Behavior
    /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
    /variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY
    /variable/CMAKE_SYSROOT
+   /variable/CMAKE_FIND_APPBUNDLE
+   /variable/CMAKE_FIND_FRAMEWORK
    /variable/CMAKE_FIND_LIBRARY_PREFIXES
    /variable/CMAKE_FIND_LIBRARY_SUFFIXES
    /variable/CMAKE_FIND_NO_INSTALL_PREFIX
@@ -147,6 +152,8 @@ Variables that Change Behavior
    /variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE
    /variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
    /variable/CMAKE_STAGING_PREFIX
+   /variable/CMAKE_SYSTEM_APPBUNDLE_PATH
+   /variable/CMAKE_SYSTEM_FRAMEWORK_PATH
    /variable/CMAKE_SYSTEM_IGNORE_PATH
    /variable/CMAKE_SYSTEM_INCLUDE_PATH
    /variable/CMAKE_SYSTEM_LIBRARY_PATH
@@ -209,9 +216,23 @@ Variables that Control the Build
 .. toctree::
    :maxdepth: 1
 
+   /variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
    /variable/CMAKE_ANDROID_API
    /variable/CMAKE_ANDROID_API_MIN
+   /variable/CMAKE_ANDROID_ARCH
+   /variable/CMAKE_ANDROID_ASSETS_DIRECTORIES
    /variable/CMAKE_ANDROID_GUI
+   /variable/CMAKE_ANDROID_JAR_DEPENDENCIES
+   /variable/CMAKE_ANDROID_JAR_DIRECTORIES
+   /variable/CMAKE_ANDROID_JAVA_SOURCE_DIR
+   /variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES
+   /variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES
+   /variable/CMAKE_ANDROID_PROCESS_MAX
+   /variable/CMAKE_ANDROID_PROGUARD
+   /variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH
+   /variable/CMAKE_ANDROID_SECURE_PROPS_PATH
+   /variable/CMAKE_ANDROID_SKIP_ANT_STEP
+   /variable/CMAKE_ANDROID_STL_TYPE
    /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY
    /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG
    /variable/CMAKE_AUTOMOC_MOC_OPTIONS
@@ -225,6 +246,7 @@ Variables that Control the Build
    /variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG
    /variable/CMAKE_CONFIG_POSTFIX
    /variable/CMAKE_DEBUG_POSTFIX
+   /variable/CMAKE_ENABLE_EXPORTS
    /variable/CMAKE_EXE_LINKER_FLAGS_CONFIG
    /variable/CMAKE_EXE_LINKER_FLAGS
    /variable/CMAKE_Fortran_FORMAT
@@ -235,6 +257,7 @@ Variables that Control the Build
    /variable/CMAKE_INSTALL_NAME_DIR
    /variable/CMAKE_INSTALL_RPATH
    /variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
+   /variable/CMAKE_LANG_COMPILER_LAUNCHER
    /variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
    /variable/CMAKE_LANG_VISIBILITY_PRESET
    /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY
@@ -270,6 +293,7 @@ Variables that Control the Build
    /variable/CMAKE_USE_RELATIVE_PATHS
    /variable/CMAKE_VISIBILITY_INLINES_HIDDEN
    /variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
+   /variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
    /variable/CMAKE_WIN32_EXECUTABLE
    /variable/CMAKE_XCODE_ATTRIBUTE_an-attribute
    /variable/EXECUTABLE_OUTPUT_PATH
@@ -345,12 +369,30 @@ Variables for CTest
    /variable/CTEST_BUILD_NAME
    /variable/CTEST_BZR_COMMAND
    /variable/CTEST_BZR_UPDATE_OPTIONS
+   /variable/CTEST_CHANGE_ID
    /variable/CTEST_CHECKOUT_COMMAND
    /variable/CTEST_CONFIGURATION_TYPE
    /variable/CTEST_CONFIGURE_COMMAND
    /variable/CTEST_COVERAGE_COMMAND
    /variable/CTEST_COVERAGE_EXTRA_FLAGS
    /variable/CTEST_CURL_OPTIONS
+   /variable/CTEST_CUSTOM_COVERAGE_EXCLUDE
+   /variable/CTEST_CUSTOM_ERROR_EXCEPTION
+   /variable/CTEST_CUSTOM_ERROR_MATCH
+   /variable/CTEST_CUSTOM_ERROR_POST_CONTEXT
+   /variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT
+   /variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE
+   /variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
+   /variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
+   /variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
+   /variable/CTEST_CUSTOM_MEMCHECK_IGNORE
+   /variable/CTEST_CUSTOM_POST_MEMCHECK
+   /variable/CTEST_CUSTOM_POST_TEST
+   /variable/CTEST_CUSTOM_PRE_MEMCHECK
+   /variable/CTEST_CUSTOM_PRE_TEST
+   /variable/CTEST_CUSTOM_TEST_IGNORE
+   /variable/CTEST_CUSTOM_WARNING_EXCEPTION
+   /variable/CTEST_CUSTOM_WARNING_MATCH
    /variable/CTEST_CVS_CHECKOUT
    /variable/CTEST_CVS_COMMAND
    /variable/CTEST_CVS_UPDATE_OPTIONS
@@ -360,6 +402,7 @@ Variables for CTest
    /variable/CTEST_DROP_SITE_CDASH
    /variable/CTEST_DROP_SITE_PASSWORD
    /variable/CTEST_DROP_SITE_USER
+   /variable/CTEST_EXTRA_COVERAGE_GLOB
    /variable/CTEST_GIT_COMMAND
    /variable/CTEST_GIT_UPDATE_CUSTOM
    /variable/CTEST_GIT_UPDATE_OPTIONS
@@ -381,6 +424,7 @@ Variables for CTest
    /variable/CTEST_SVN_COMMAND
    /variable/CTEST_SVN_OPTIONS
    /variable/CTEST_SVN_UPDATE_OPTIONS
+   /variable/CTEST_TEST_LOAD
    /variable/CTEST_TEST_TIMEOUT
    /variable/CTEST_TRIGGER_SITE
    /variable/CTEST_UPDATE_COMMAND
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 4bd5a5e..dac16bf 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -27,6 +27,8 @@ in each directory of a source tree with the name CMakeLists.txt.
 Users build a project by using CMake to generate a build system for a
 native tool on their platform.
 
+.. _`CMake Options`:
+
 Options
 =======
 
@@ -113,14 +115,18 @@ Options
 ``--debug-output``
  Put cmake in a debug mode.
 
- Print extra stuff during the cmake run like stack traces with
+ Print extra information during the cmake run like stack traces with
  message(send_error ) calls.
 
 ``--trace``
  Put cmake in trace mode.
 
- Print a trace of all calls made and from where with
- message(send_error ) calls.
+ Print a trace of all calls made and from where.
+
+``--trace-expand``
+ Put cmake in trace mode.
+
+ Like ``--trace``, but with variables expanded.
 
 ``--warn-uninitialized``
  Warn about uninitialized values.
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index c91321b..2fdf7f3 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -66,6 +66,13 @@ Options
  number of jobs.  This option can also be set by setting the
  environment variable ``CTEST_PARALLEL_LEVEL``.
 
+``--test-load <level>``
+ While running tests in parallel (e.g. with ``-j``), try not to start
+ tests when they may cause the CPU load to pass above a given threshold.
+
+ When ``ctest`` is run as a `Dashboard Client`_ this sets the
+ ``TestLoad`` option of the `CTest Test Step`_.
+
 ``-Q,--quiet``
  Make ctest quiet.
 
@@ -295,6 +302,12 @@ Options
 ``--test-command``
  The test to run with the --build-and-test option.
 
+``--test-output-size-passed <size>``
+ Limit the output for passed tests to <size> bytes.
+
+``--test-output-size-failed <size>``
+ Limit the output for failed tests to <size> bytes.
+
 ``--test-timeout``
  The time limit in seconds, internal use only.
 
@@ -776,6 +789,13 @@ Arguments to the command may specify some of the step settings.
 
 Configuration settings include:
 
+``TestLoad``
+  While running tests in parallel (e.g. with ``-j``), try not to start
+  tests when they may cause the CPU load to pass above a given threshold.
+
+  * `CTest Script`_ variable: :variable:`CTEST_TEST_LOAD`
+  * :module:`CTest` module variable: ``CTEST_TEST_LOAD``
+
 ``TimeOut``
   The default timeout for each test if not specified by the
   :prop_test:`TIMEOUT` test property.
diff --git a/Help/policy/CMP0064.rst b/Help/policy/CMP0064.rst
new file mode 100644
index 0000000..e9a061b
--- /dev/null
+++ b/Help/policy/CMP0064.rst
@@ -0,0 +1,17 @@
+CMP0064
+-------
+
+Recognize ``TEST`` as a operator for the :command:`if` command.
+
+The ``TEST`` operator was added to the :command:`if` command to determine if a
+given test name was created by the :command:`add_test` command.
+
+The ``OLD`` behavior for this policy is to ignore the ``TEST`` operator.
+The ``NEW`` behavior is to interpret the ``TEST`` operator.
+
+This policy was introduced in CMake version 3.4.  CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.  Use
+the :command:`cmake_policy()` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0065.rst b/Help/policy/CMP0065.rst
new file mode 100644
index 0000000..2ed775d
--- /dev/null
+++ b/Help/policy/CMP0065.rst
@@ -0,0 +1,27 @@
+CMP0065
+-------
+
+Do not add flags to export symbols from executables without
+the :prop_tgt:`ENABLE_EXPORTS` target property.
+
+CMake 3.3 and below, for historical reasons, always linked executables
+on some platforms with flags like ``-rdynamic`` to export symbols from
+the executables for use by any plugins they may load via ``dlopen``.
+CMake 3.4 and above prefer to do this only for executables that are
+explicitly marked with the :prop_tgt:`ENABLE_EXPORTS` target property.
+
+The ``OLD`` behavior of this policy is to always use the additional link
+flags when linking executables regardless of the value of the
+:prop_tgt:`ENABLE_EXPORTS` target property.
+
+The ``NEW`` behavior of this policy is to only use the additional link
+flags when linking executables if the :prop_tgt:`ENABLE_EXPORTS` target
+property is set to ``True``.
+
+This policy was introduced in CMake version 3.4.  Unlike most policies,
+CMake version |release| does *not* warn by default when this policy
+is not set and simply uses OLD behavior.  See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0065 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_dir/INCLUDE_REGULAR_EXPRESSION.rst b/Help/prop_dir/INCLUDE_REGULAR_EXPRESSION.rst
index befafa5..bb90c61 100644
--- a/Help/prop_dir/INCLUDE_REGULAR_EXPRESSION.rst
+++ b/Help/prop_dir/INCLUDE_REGULAR_EXPRESSION.rst
@@ -3,6 +3,7 @@ INCLUDE_REGULAR_EXPRESSION
 
 Include file scanning regular expression.
 
-This read-only property specifies the regular expression used during
+This property specifies the regular expression used during
 dependency scanning to match include files that should be followed.
-See the include_regular_expression command.
+See the :command:`include_regular_expression` command for a high-level
+interface to set this property.
diff --git a/Help/prop_gbl/RULE_LAUNCH_COMPILE.rst b/Help/prop_gbl/RULE_LAUNCH_COMPILE.rst
index 980843b..e0df878 100644
--- a/Help/prop_gbl/RULE_LAUNCH_COMPILE.rst
+++ b/Help/prop_gbl/RULE_LAUNCH_COMPILE.rst
@@ -3,7 +3,9 @@ RULE_LAUNCH_COMPILE
 
 Specify a launcher for compile rules.
 
-Makefile generators prefix compiler commands with the given launcher
-command line.  This is intended to allow launchers to intercept build
-problems with high granularity.  Non-Makefile generators currently
-ignore this property.
+:ref:`Makefile Generators` and the :generator:`Ninja` generator prefix
+compiler commands with the given launcher command line.
+This is intended to allow launchers to intercept build problems
+with high granularity.  Other generators ignore this property
+because their underlying build systems provide no hook to wrap
+individual commands with a launcher.
diff --git a/Help/prop_gbl/RULE_LAUNCH_CUSTOM.rst b/Help/prop_gbl/RULE_LAUNCH_CUSTOM.rst
index 9d4a25c..b20c59b 100644
--- a/Help/prop_gbl/RULE_LAUNCH_CUSTOM.rst
+++ b/Help/prop_gbl/RULE_LAUNCH_CUSTOM.rst
@@ -3,7 +3,9 @@ RULE_LAUNCH_CUSTOM
 
 Specify a launcher for custom rules.
 
-Makefile generators prefix custom commands with the given launcher
-command line.  This is intended to allow launchers to intercept build
-problems with high granularity.  Non-Makefile generators currently
-ignore this property.
+:ref:`Makefile Generators` and the :generator:`Ninja` generator prefix
+custom commands with the given launcher command line.
+This is intended to allow launchers to intercept build problems
+with high granularity.  Other generators ignore this property
+because their underlying build systems provide no hook to wrap
+individual commands with a launcher.
diff --git a/Help/prop_gbl/RULE_LAUNCH_LINK.rst b/Help/prop_gbl/RULE_LAUNCH_LINK.rst
index 191f1d5..567bb68 100644
--- a/Help/prop_gbl/RULE_LAUNCH_LINK.rst
+++ b/Help/prop_gbl/RULE_LAUNCH_LINK.rst
@@ -3,7 +3,9 @@ RULE_LAUNCH_LINK
 
 Specify a launcher for link rules.
 
-Makefile generators prefix link and archive commands with the given
-launcher command line.  This is intended to allow launchers to
-intercept build problems with high granularity.  Non-Makefile
-generators currently ignore this property.
+:ref:`Makefile Generators` and the :generator:`Ninja` generator prefix
+link and archive commands with the given launcher command line.
+This is intended to allow launchers to intercept build problems
+with high granularity.  Other generators ignore this property
+because their underlying build systems provide no hook to wrap
+individual commands with a launcher.
diff --git a/Help/prop_gbl/TARGET_MESSAGES.rst b/Help/prop_gbl/TARGET_MESSAGES.rst
new file mode 100644
index 0000000..275b074
--- /dev/null
+++ b/Help/prop_gbl/TARGET_MESSAGES.rst
@@ -0,0 +1,20 @@
+TARGET_MESSAGES
+---------------
+
+Specify whether to report the completion of each target.
+
+This property specifies whether :ref:`Makefile Generators` should
+add a progress message describing that each target has been completed.
+If the property is not set the default is ``ON``.  Set the property
+to ``OFF`` to disable target completion messages.
+
+This option is intended to reduce build output when little or no
+work needs to be done to bring the build tree up to date.
+
+If a ``CMAKE_TARGET_MESSAGES`` cache entry exists its value
+initializes the value of this property.
+
+Non-Makefile generators currently ignore this property.
+
+See the counterpart property :prop_gbl:`RULE_MESSAGES` to disable
+everything except for target completion messages.
diff --git a/Help/prop_sf/OBJECT_DEPENDS.rst b/Help/prop_sf/OBJECT_DEPENDS.rst
index 18022de..1d24960 100644
--- a/Help/prop_sf/OBJECT_DEPENDS.rst
+++ b/Help/prop_sf/OBJECT_DEPENDS.rst
@@ -3,9 +3,12 @@ OBJECT_DEPENDS
 
 Additional files on which a compiled object file depends.
 
-Specifies a semicolon-separated list of full-paths to files on which
-any object files compiled from this source file depend.  An object
-file will be recompiled if any of the named files is newer than it.
+Specifies a :ref:`;-list <CMake Language Lists>` of full-paths to
+files on which any object files compiled from this source file depend.
+On :ref:`Makefile Generators` and the :generator:`Ninja` generator an
+object file will be recompiled if any of the named files is newer than it.
+:ref:`Visual Studio Generators` and the :generator:`Xcode` generator
+cannot implement such compilation dependencies.
 
 This property need not be used to specify the dependency of a source
 file on a generated header file that it includes.  Although the
@@ -14,5 +17,5 @@ necessary.  If the generated header file is created by a custom
 command in the same target as the source file, the automatic
 dependency scanning process will recognize the dependency.  If the
 generated header file is created by another target, an inter-target
-dependency should be created with the add_dependencies command (if one
-does not already exist due to linking relationships).
+dependency should be created with the :command:`add_dependencies`
+command (if one does not already exist due to linking relationships).
diff --git a/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst b/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
new file mode 100644
index 0000000..af6b405
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
@@ -0,0 +1,8 @@
+ANDROID_ANT_ADDITIONAL_OPTIONS
+------------------------------
+
+Set the additional options for Android Ant build system. This is
+a string value containing all command line options for the Ant build.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS` variable if it is
+set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_ARCH.rst b/Help/prop_tgt/ANDROID_ARCH.rst
new file mode 100644
index 0000000..5477fb5
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_ARCH.rst
@@ -0,0 +1,17 @@
+ANDROID_ARCH
+------------
+
+Set the Android target architecture.
+
+This is a string property that could be set to the one of
+the following values:
+
+* ``armv7-a``: "ARMv7-A (armv7-a)"
+* ``armv7-a-hard``: "ARMv7-A, hard-float ABI (armv7-a)"
+* ``arm64-v8a``: "ARMv8-A, 64bit (arm64-v8a)"
+* ``x86``: "x86 (x86)"
+* ``x86_64``: "x86_64 (x86_64)"
+
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_ARCH` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
new file mode 100644
index 0000000..764a582
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
@@ -0,0 +1,9 @@
+ANDROID_ASSETS_DIRECTORIES
+--------------------------
+
+Set the Android assets directories to copy into the main assets
+folder before build. This a string property that contains the
+directory paths separated by semicolon.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_ASSETS_DIRECTORIES` variable if it is set when
+a target is created.
diff --git a/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst b/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
new file mode 100644
index 0000000..42937c1
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
@@ -0,0 +1,7 @@
+ANDROID_JAR_DEPENDENCIES
+------------------------
+
+Set the Android property that specifies JAR dependencies.
+This is a string value property. This property is initialized
+by the value of the :variable:`CMAKE_ANDROID_JAR_DEPENDENCIES`
+variable if it is set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
new file mode 100644
index 0000000..54f0a8f
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
@@ -0,0 +1,14 @@
+ANDROID_JAR_DIRECTORIES
+-----------------------
+
+Set the Android property that specifies directories to search for
+the JAR libraries.
+
+This a string property that contains the directory paths separated by
+semicolons. This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_JAR_DIRECTORIES` variable if it is set when
+a target is created.
+
+Contents of ``ANDROID_JAR_DIRECTORIES`` may use "generator expressions"
+with the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions.
diff --git a/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst b/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
new file mode 100644
index 0000000..90ef1ce
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
@@ -0,0 +1,8 @@
+ANDROID_JAVA_SOURCE_DIR
+-----------------------
+
+Set the Android property that defines the Java source code root directories.
+This a string property that contains the directory paths separated by semicolon.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_JAVA_SOURCE_DIR` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst b/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
new file mode 100644
index 0000000..759a37b
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
@@ -0,0 +1,14 @@
+ANDROID_NATIVE_LIB_DEPENDENCIES
+-------------------------------
+
+Set the Android property that specifies the .so dependencies.
+This is a string property.
+
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES` variable if it is set
+when a target is created.
+
+Contents of ``ANDROID_NATIVE_LIB_DEPENDENCIES`` may use
+"generator expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for
+available expressions.
diff --git a/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
new file mode 100644
index 0000000..bc67380
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
@@ -0,0 +1,16 @@
+ANDROID_NATIVE_LIB_DIRECTORIES
+------------------------------
+
+Set the Android property that specifies directories to search for the
+.so libraries.
+
+This a string property that contains the directory paths separated
+by semicolons.
+
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES` variable if it is set when a
+target is created.
+
+Contents of ``ANDROID_NATIVE_LIB_DIRECTORIES`` may use "generator expressions"
+with the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions.
diff --git a/Help/prop_tgt/ANDROID_PROCESS_MAX.rst b/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
new file mode 100644
index 0000000..847acae
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
@@ -0,0 +1,8 @@
+ANDROID_PROCESS_MAX
+-------------------
+
+Set the Android property that defines the maximum number of a
+parallel Android NDK compiler processes (e.g. ``4``).
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_PROCESS_MAX` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_PROGUARD.rst b/Help/prop_tgt/ANDROID_PROGUARD.rst
new file mode 100644
index 0000000..dafc51e
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_PROGUARD.rst
@@ -0,0 +1,9 @@
+ANDROID_PROGUARD
+----------------
+
+When this property is set to true that enables the ProGuard tool to shrink,
+optimize, and obfuscate the code by removing unused code and renaming
+classes, fields, and methods with semantically obscure names.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_PROGUARD` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst b/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
new file mode 100644
index 0000000..0e929d1
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
@@ -0,0 +1,9 @@
+ANDROID_PROGUARD_CONFIG_PATH
+----------------------------
+
+Set the Android property that specifies the location of the ProGuard
+config file. Leave empty to use the default one.
+This a string property that contains the path to ProGuard config file.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_PROGUARD_CONFIG_PATH` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst b/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
new file mode 100644
index 0000000..9533f1a
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
@@ -0,0 +1,8 @@
+ANDROID_SECURE_PROPS_PATH
+-------------------------
+
+Set the Android property that states the location of the secure properties file.
+This is a string property that contains the file path.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_SECURE_PROPS_PATH` variable
+if it is set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst b/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
new file mode 100644
index 0000000..6361896
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
@@ -0,0 +1,6 @@
+ANDROID_SKIP_ANT_STEP
+---------------------
+
+Set the Android property that defines whether or not to skip the Ant build step.
+This is a boolean property initialized by the value of the
+:variable:`CMAKE_ANDROID_SKIP_ANT_STEP` variable if it is set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_STL_TYPE.rst b/Help/prop_tgt/ANDROID_STL_TYPE.rst
new file mode 100644
index 0000000..7256e26
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_STL_TYPE.rst
@@ -0,0 +1,15 @@
+ANDROID_STL_TYPE
+----------------
+
+Set the Android property that defines the type of STL support for the project.
+This is a string property that could set to the one of the following values:
+``none``           e.g. "No C++ Support"
+``system``         e.g. "Minimal C++ without STL"
+``gabi++_static``  e.g. "GAbi++ Static"
+``gabi++_shared``  e.g. "GAbi++ Shared"
+``gnustl_static``  e.g. "GNU libstdc++ Static"
+``gnustl_shared``  e.g. "GNU libstdc++ Shared"
+``stlport_static`` e.g. "STLport Static"
+``stlport_shared`` e.g. "STLport Shared"
+This property is initialized by the value of the
+variable:`CMAKE_ANDROID_STL_TYPE` variable if it is set when a target is created.
diff --git a/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
index 29991eb..12f8bb7 100644
--- a/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
@@ -11,3 +11,6 @@ per-configuration subdirectory to the specified directory.  This
 property is initialized by the value of the
 :variable:`CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>` variable if
 it is set when a target is created.
+
+Contents of ``ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>`` may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/BINARY_DIR.rst b/Help/prop_tgt/BINARY_DIR.rst
new file mode 100644
index 0000000..246f7e6
--- /dev/null
+++ b/Help/prop_tgt/BINARY_DIR.rst
@@ -0,0 +1,6 @@
+BINARY_DIR
+----------
+
+This read-only property reports the value of the
+:variable:`CMAKE_CURRENT_BINARY_DIR` variable in the directory in which
+the target was defined.
diff --git a/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst b/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst
index f2c875e..a61c702 100644
--- a/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst
+++ b/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst
@@ -2,6 +2,7 @@
 --------------------
 
 Old per-configuration target file base name.
+Use :prop_tgt:`OUTPUT_NAME_<CONFIG>` instead.
 
-This is a configuration-specific version of OUTPUT_NAME.  Use
-OUTPUT_NAME_<CONFIG> instead.
+This is a configuration-specific version of the :prop_tgt:`OUTPUT_NAME`
+target property.
diff --git a/Help/prop_tgt/ENABLE_EXPORTS.rst b/Help/prop_tgt/ENABLE_EXPORTS.rst
index 283f5a8..dfd4af7 100644
--- a/Help/prop_tgt/ENABLE_EXPORTS.rst
+++ b/Help/prop_tgt/ENABLE_EXPORTS.rst
@@ -7,7 +7,7 @@ Normally an executable does not export any symbols because it is the
 final program.  It is possible for an executable to export symbols to
 be used by loadable modules.  When this property is set to true CMake
 will allow other targets to "link" to the executable with the
-TARGET_LINK_LIBRARIES command.  On all platforms a target-level
+:command:`TARGET_LINK_LIBRARIES` command.  On all platforms a target-level
 dependency on the executable is created for targets that link to it.
 For DLL platforms an import library will be created for the exported
 symbols and then used for linking.  All Windows-based systems
@@ -17,3 +17,6 @@ module will "link" to the executable using a flag like
 "-bundle_loader".  For other non-DLL platforms the link rule is simply
 ignored since the dynamic loader will automatically bind symbols when
 the module is loaded.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_ENABLE_EXPORTS` if it is set when a target is created.
diff --git a/Help/prop_tgt/FRAMEWORK.rst b/Help/prop_tgt/FRAMEWORK.rst
index 9f472c0..dcb6d3b 100644
--- a/Help/prop_tgt/FRAMEWORK.rst
+++ b/Help/prop_tgt/FRAMEWORK.rst
@@ -6,4 +6,6 @@ This target is a framework on the Mac.
 If a shared library target has this property set to true it will be
 built as a framework when built on the mac.  It will have the
 directory structure required for a framework and will be suitable to
-be used with the -framework option
+be used with the ``-framework`` option
+
+See also the :prop_tgt:`FRAMEWORK_VERSION` target property.
diff --git a/Help/prop_tgt/FRAMEWORK_VERSION.rst b/Help/prop_tgt/FRAMEWORK_VERSION.rst
new file mode 100644
index 0000000..bf650a7
--- /dev/null
+++ b/Help/prop_tgt/FRAMEWORK_VERSION.rst
@@ -0,0 +1,5 @@
+FRAMEWORK_VERSION
+-----------------
+
+Version of a framework created using the :prop_tgt:`FRAMEWORK` target
+property (e.g. ``A``).
diff --git a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
new file mode 100644
index 0000000..0fe0b31
--- /dev/null
+++ b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
@@ -0,0 +1,13 @@
+<LANG>_COMPILER_LAUNCHER
+------------------------
+
+This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
+
+Specify a :ref:`;-list <CMake Language Lists>` containing a command line
+for a compiler launching tool. The :ref:`Makefile Generators` and the
+:generator:`Ninja` generator will run this tool and pass the compiler and
+its arguments to the tool. Some example tools are distcc and ccache.
+
+This property is initialized by the value of
+the :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
index 6fc0142..28dd404 100644
--- a/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
@@ -11,3 +11,6 @@ per-configuration subdirectory to the specified directory.  This
 property is initialized by the value of the
 :variable:`CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>` variable if
 it is set when a target is created.
+
+Contents of ``LIBRARY_OUTPUT_DIRECTORY_<CONFIG>`` may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/LINK_SEARCH_END_STATIC.rst b/Help/prop_tgt/LINK_SEARCH_END_STATIC.rst
index fe105bd..cf9c871 100644
--- a/Help/prop_tgt/LINK_SEARCH_END_STATIC.rst
+++ b/Help/prop_tgt/LINK_SEARCH_END_STATIC.rst
@@ -10,5 +10,9 @@ paths are not known or (in some cases) are in implicit link
 directories for the platform.  By default CMake adds an option at the
 end of the library list (if necessary) to set the linker search type
 back to its starting type.  This property switches the final linker
-search type to -Bstatic regardless of how it started.  See also
-LINK_SEARCH_START_STATIC.
+search type to -Bstatic regardless of how it started.
+
+This property is initialized by the value of the variable
+CMAKE_LINK_SEARCH_END_STATIC if it is set when a target is created.
+
+See also LINK_SEARCH_START_STATIC.
diff --git a/Help/prop_tgt/LINK_SEARCH_START_STATIC.rst b/Help/prop_tgt/LINK_SEARCH_START_STATIC.rst
index ca899fe..2e0f9bd 100644
--- a/Help/prop_tgt/LINK_SEARCH_START_STATIC.rst
+++ b/Help/prop_tgt/LINK_SEARCH_START_STATIC.rst
@@ -11,4 +11,9 @@ directories for the platform.  By default the linker search type is
 assumed to be -Bdynamic at the beginning of the library list.  This
 property switches the assumption to -Bstatic.  It is intended for use
 when linking an executable statically (e.g.  with the GNU -static
-option).  See also LINK_SEARCH_END_STATIC.
+option).
+
+This property is initialized by the value of the variable
+CMAKE_LINK_SEARCH_START_STATIC if it is set when a target is created.
+
+See also LINK_SEARCH_END_STATIC.
diff --git a/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst b/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst
index 097cce1..07a933f 100644
--- a/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst
+++ b/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst
@@ -1,29 +1,35 @@
 MACOSX_BUNDLE_INFO_PLIST
 ------------------------
 
-Specify a custom Info.plist template for a Mac OS X App Bundle.
+Specify a custom ``Info.plist`` template for a Mac OS X App Bundle.
 
-An executable target with MACOSX_BUNDLE enabled will be built as an
-application bundle on Mac OS X.  By default its Info.plist file is
-created by configuring a template called MacOSXBundleInfo.plist.in
-located in the CMAKE_MODULE_PATH.  This property specifies an
-alternative template file name which may be a full path.
+An executable target with :prop_tgt:`MACOSX_BUNDLE` enabled will be built as an
+application bundle on Mac OS X.  By default its ``Info.plist`` file is created
+by configuring a template called ``MacOSXBundleInfo.plist.in`` located in the
+:variable:`CMAKE_MODULE_PATH`.  This property specifies an alternative template
+file name which may be a full path.
 
 The following target properties may be set to specify content to be
 configured into the file:
 
-::
-
-  MACOSX_BUNDLE_INFO_STRING
-  MACOSX_BUNDLE_ICON_FILE
-  MACOSX_BUNDLE_GUI_IDENTIFIER
-  MACOSX_BUNDLE_LONG_VERSION_STRING
-  MACOSX_BUNDLE_BUNDLE_NAME
-  MACOSX_BUNDLE_SHORT_VERSION_STRING
-  MACOSX_BUNDLE_BUNDLE_VERSION
-  MACOSX_BUNDLE_COPYRIGHT
+``MACOSX_BUNDLE_BUNDLE_NAME``
+  Sets ``CFBundleName``.
+``MACOSX_BUNDLE_BUNDLE_VERSION``
+  Sets ``CFBundleVersion``.
+``MACOSX_BUNDLE_COPYRIGHT``
+  Sets ``NSHumanReadableCopyright``.
+``MACOSX_BUNDLE_GUI_IDENTIFIER``
+  Sets ``CFBundleIdentifier``.
+``MACOSX_BUNDLE_ICON_FILE``
+  Sets ``CFBundleIconFile``.
+``MACOSX_BUNDLE_INFO_STRING``
+  Sets ``CFBundleGetInfoString``.
+``MACOSX_BUNDLE_LONG_VERSION_STRING``
+  Sets ``CFBundleLongVersionString``.
+``MACOSX_BUNDLE_SHORT_VERSION_STRING``
+  Sets ``CFBundleShortVersionString``.
 
 CMake variables of the same name may be set to affect all targets in a
 directory that do not have each specific property set.  If a custom
-Info.plist is specified by this property it may of course hard-code
+``Info.plist`` is specified by this property it may of course hard-code
 all the settings instead of using the target properties.
diff --git a/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst b/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst
index 729d929..548c3ac 100644
--- a/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst
+++ b/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst
@@ -1,25 +1,27 @@
 MACOSX_FRAMEWORK_INFO_PLIST
 ---------------------------
 
-Specify a custom Info.plist template for a Mac OS X Framework.
+Specify a custom ``Info.plist`` template for a Mac OS X Framework.
 
-A library target with FRAMEWORK enabled will be built as a framework
-on Mac OS X.  By default its Info.plist file is created by configuring
-a template called MacOSXFrameworkInfo.plist.in located in the
-CMAKE_MODULE_PATH.  This property specifies an alternative template
+A library target with :prop_tgt:`FRAMEWORK` enabled will be built as a
+framework on Mac OS X.  By default its ``Info.plist`` file is created by
+configuring a template called ``MacOSXFrameworkInfo.plist.in`` located in the
+:variable:`CMAKE_MODULE_PATH`.  This property specifies an alternative template
 file name which may be a full path.
 
 The following target properties may be set to specify content to be
 configured into the file:
 
-::
-
-  MACOSX_FRAMEWORK_ICON_FILE
-  MACOSX_FRAMEWORK_IDENTIFIER
-  MACOSX_FRAMEWORK_SHORT_VERSION_STRING
-  MACOSX_FRAMEWORK_BUNDLE_VERSION
+``MACOSX_FRAMEWORK_BUNDLE_VERSION``
+  Sets ``CFBundleVersion``.
+``MACOSX_FRAMEWORK_ICON_FILE``
+  Sets ``CFBundleIconFile``.
+``MACOSX_FRAMEWORK_IDENTIFIER``
+  Sets ``CFBundleIdentifier``.
+``MACOSX_FRAMEWORK_SHORT_VERSION_STRING``
+  Sets ``CFBundleShortVersionString``.
 
 CMake variables of the same name may be set to affect all targets in a
 directory that do not have each specific property set.  If a custom
-Info.plist is specified by this property it may of course hard-code
+``Info.plist`` is specified by this property it may of course hard-code
 all the settings instead of using the target properties.
diff --git a/Help/prop_tgt/NO_SONAME.rst b/Help/prop_tgt/NO_SONAME.rst
index fc668b5..ee45ed8 100644
--- a/Help/prop_tgt/NO_SONAME.rst
+++ b/Help/prop_tgt/NO_SONAME.rst
@@ -1,11 +1,11 @@
 NO_SONAME
 ---------
 
-Whether to set "soname" when linking a shared library or module.
+Whether to set "soname" when linking a shared library.
 
-Enable this boolean property if a generated shared library or module
+Enable this boolean property if a generated shared library
 should not have "soname" set.  Default is to set "soname" on all
-shared libraries and modules as long as the platform supports it.
+shared libraries as long as the platform supports it.
 Generally, use this property only for leaf private libraries or
 plugins.  If you use it on normal shared libraries which other targets
 link against, on some platforms a linker will insert a full path to
diff --git a/Help/prop_tgt/OUTPUT_NAME.rst b/Help/prop_tgt/OUTPUT_NAME.rst
index 97bf010..f1bdb7c 100644
--- a/Help/prop_tgt/OUTPUT_NAME.rst
+++ b/Help/prop_tgt/OUTPUT_NAME.rst
@@ -6,3 +6,16 @@ Output name for target files.
 This sets the base name for output files created for an executable or
 library target.  If not set, the logical target name is used by
 default.
+
+Contents of ``OUTPUT_NAME`` and the variants listed below may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+See also the variants:
+
+* :prop_tgt:`OUTPUT_NAME_<CONFIG>`
+* :prop_tgt:`ARCHIVE_OUTPUT_NAME_<CONFIG>`
+* :prop_tgt:`ARCHIVE_OUTPUT_NAME`
+* :prop_tgt:`LIBRARY_OUTPUT_NAME_<CONFIG>`
+* :prop_tgt:`LIBRARY_OUTPUT_NAME`
+* :prop_tgt:`RUNTIME_OUTPUT_NAME_<CONFIG>`
+* :prop_tgt:`RUNTIME_OUTPUT_NAME`
diff --git a/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst b/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst
index 7bfbcbc..41b782f 100644
--- a/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst
+++ b/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst
@@ -3,4 +3,5 @@ OUTPUT_NAME_<CONFIG>
 
 Per-configuration target file base name.
 
-This is the configuration-specific version of OUTPUT_NAME.
+This is the configuration-specific version of the :prop_tgt:`OUTPUT_NAME`
+target property.
diff --git a/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
index c100346..94fb277 100644
--- a/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
@@ -11,3 +11,6 @@ per-configuration subdirectory to the specified directory.  This
 property is initialized by the value of the
 :variable:`CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>` variable if
 it is set when a target is created.
+
+Contents of ``RUNTIME_OUTPUT_DIRECTORY_<CONFIG>`` may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/SOURCE_DIR.rst b/Help/prop_tgt/SOURCE_DIR.rst
new file mode 100644
index 0000000..b25813b
--- /dev/null
+++ b/Help/prop_tgt/SOURCE_DIR.rst
@@ -0,0 +1,6 @@
+SOURCE_DIR
+----------
+
+This read-only property reports the value of the
+:variable:`CMAKE_CURRENT_SOURCE_DIR` variable in the directory in which
+the target was defined.
diff --git a/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
new file mode 100644
index 0000000..19d1620
--- /dev/null
+++ b/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
@@ -0,0 +1,10 @@
+VS_DESKTOP_EXTENSIONS_VERSION
+-----------------------------
+
+Visual Studio Windows 10 Desktop Extensions Version
+
+Specifies the version of the Desktop Extensions that should be included in the
+target. For example ``10.0.10240.0``. If the value is not specified, the Desktop
+Extensions will not be included. To use the same version of the extensions as
+the Windows 10 SDK that is being used, you can use the
+:variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` variable.
diff --git a/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
new file mode 100644
index 0000000..27c8a3d
--- /dev/null
+++ b/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
@@ -0,0 +1,10 @@
+VS_IOT_EXTENSIONS_VERSION
+-------------------------
+
+Visual Studio Windows 10 IoT Extensions Version
+
+Specifies the version of the IoT Extensions that should be included in the
+target. For example ``10.0.10240.0``. If the value is not specified, the IoT
+Extensions will not be included. To use the same version of the extensions as
+the Windows 10 SDK that is being used, you can use the
+:variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` variable.
diff --git a/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst b/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
new file mode 100644
index 0000000..add50cb
--- /dev/null
+++ b/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
@@ -0,0 +1,6 @@
+VS_IOT_STARTUP_TASK
+-------------------
+
+Visual Studio Windows 10 IoT Continuous Background Task
+
+Specifies that the target should be compiled as a Continuous Background Task library.
diff --git a/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
new file mode 100644
index 0000000..be3c9a0
--- /dev/null
+++ b/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
@@ -0,0 +1,10 @@
+VS_MOBILE_EXTENSIONS_VERSION
+----------------------------
+
+Visual Studio Windows 10 Mobile Extensions Version
+
+Specifies the version of the Mobile Extensions that should be included in the
+target. For example ``10.0.10240.0``. If the value is not specified, the Mobile
+Extensions will not be included. To use the same version of the extensions as
+the Windows 10 SDK that is being used, you can use the
+:variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` variable.
diff --git a/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst b/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
new file mode 100644
index 0000000..1ad7a71
--- /dev/null
+++ b/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
@@ -0,0 +1,10 @@
+VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
+--------------------------------------
+
+Visual Studio Windows Target Platform Minimum Version
+
+For Windows 10. Specifies the minimum version of the OS that is being
+targeted. For example ``10.0.10240.0``. If the value is not specified, the
+value of :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` will be used on
+WindowsStore projects otherwise the target platform minimum version will not
+be specified for the project.
diff --git a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..3f48af8
--- /dev/null
+++ b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,18 @@
+WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------
+
+This property is implemented only for MS-compatible tools on Windows.
+
+Enable this boolean property to automatically create a module definition
+(``.def``) file with all global symbols found in the input ``.obj`` files
+for a ``SHARED`` library on Windows.  The module definition file will be
+passed to the linker causing all symbols to be exported from the ``.dll``.
+For global *data* symbols, ``__declspec(dllimport)`` must still be used when
+compiling against the code in the ``.dll``.  All other function symbols will
+be automatically exported and imported by callers.  This simplifies porting
+projects to Windows by reducing the need for explicit ``dllexport`` markup,
+even in ``C++`` classes.
+
+This property is initialized by the value of
+the :variable:`CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/XXX_OUTPUT_DIRECTORY.txt b/Help/prop_tgt/XXX_OUTPUT_DIRECTORY.txt
index 0b3d31c..3ae5448 100644
--- a/Help/prop_tgt/XXX_OUTPUT_DIRECTORY.txt
+++ b/Help/prop_tgt/XXX_OUTPUT_DIRECTORY.txt
@@ -1,8 +1,11 @@
 Output directory in which to build |XXX| target files.
 
 This property specifies the directory into which |xxx| target files
-should be built.  Multi-configuration generators (VS, Xcode) append a
-per-configuration subdirectory to the specified directory.
+should be built.  The property value may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+Multi-configuration generators (VS, Xcode) append a per-configuration
+subdirectory to the specified directory unless a generator expression
+is used.
 
 This property is initialized by the value of the variable
 |CMAKE_XXX_OUTPUT_DIRECTORY| if it is set when a target is created.
diff --git a/Help/release/3.4.rst b/Help/release/3.4.rst
new file mode 100644
index 0000000..89c5561
--- /dev/null
+++ b/Help/release/3.4.rst
@@ -0,0 +1,273 @@
+CMake 3.4 Release Notes
+***********************
+
+.. only:: html
+
+  .. contents::
+
+Changes made since CMake 3.3 include the following.
+
+New Features
+============
+
+Generators
+----------
+
+* The :generator:`Visual Studio 14 2015` generator learned to select
+  a Windows 10 SDK based on the value of the :variable:`CMAKE_SYSTEM_VERSION`
+  variable and the SDKs available on the host.
+
+* CMake learned rudimentary support for the Apple Swift language.  When using
+  the :generator:`Xcode` generator with Xcode 6.1 or higher, one may enable
+  the ``Swift`` language with the :command:`enable_language` command or the
+  :command:`project` command (this is an error with other generators or when
+  Xcode is too old).  Then one may list ``.swift`` source files in targets
+  for compilation.
+
+Commands
+--------
+
+* The :command:`find_program` command learned a ``NAMES_PER_DIR``
+  option to consider all given ``NAMES`` in each directory before
+  moving on to the next directory.
+
+* The :command:`get_filename_component` command learned a new ``BASE_DIR``
+  subcommand.  This is used to specify a base directory when calculating an
+  absolute path from a relative path.
+
+* The :command:`if` command learned a new ``TEST`` operator that evaluates
+  to true if a given test name has been defined by the :command:`add_test`
+  command.  See policy :policy:`CMP0064`.
+
+* The :command:`install(DIRECTORY)` command ``DESTINATION`` option learned to
+  support :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* The :command:`install(FILES)` command ``DESTINATION`` option learned to
+  support :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* The :command:`string` command learned a new ``APPEND`` subcommand.
+
+Variables
+---------
+
+* The :ref:`Makefile Generators` and the :generator:`Ninja` generator
+  learned to add compiler launcher tools like distcc and ccache along
+  with the compiler for ``C`` and ``CXX`` languages.  See the
+  :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable and
+  :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property for details.
+
+* New :variable:`CMAKE_LINK_SEARCH_START_STATIC` and
+  :variable:`CMAKE_LINK_SEARCH_END_STATIC` variables were
+  introduced to initialize the
+  :prop_tgt:`LINK_SEARCH_START_STATIC` and
+  :prop_tgt:`LINK_SEARCH_END_STATIC` target properties,
+  respectively.
+
+Properties
+----------
+
+* :ref:`Visual Studio Generators` learned to support additonal
+  target properties to customize projects for NVIDIA Nsight
+  Tegra Visual Studio Edition:
+
+  * :prop_tgt:`ANDROID_ANT_ADDITIONAL_OPTIONS`
+  * :prop_tgt:`ANDROID_ARCH`
+  * :prop_tgt:`ANDROID_ASSETS_DIRECTORIES`
+  * :prop_tgt:`ANDROID_JAR_DEPENDENCIES`
+  * :prop_tgt:`ANDROID_JAR_DIRECTORIES`
+  * :prop_tgt:`ANDROID_JAVA_SOURCE_DIR`
+  * :prop_tgt:`ANDROID_NATIVE_LIB_DEPENDENCIES`
+  * :prop_tgt:`ANDROID_NATIVE_LIB_DIRECTORIES`
+  * :prop_tgt:`ANDROID_PROCESS_MAX`
+  * :prop_tgt:`ANDROID_PROGUARD`
+  * :prop_tgt:`ANDROID_PROGUARD_CONFIG_PATH`
+  * :prop_tgt:`ANDROID_SECURE_PROPS_PATH`
+  * :prop_tgt:`ANDROID_SKIP_ANT_STEP`
+  * :prop_tgt:`ANDROID_STL_TYPE`
+
+* The :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY`,
+  :prop_tgt:`LIBRARY_OUTPUT_DIRECTORY`, and
+  :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` target properties learned to
+  support :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* The :prop_tgt:`SOURCE_DIR` and :prop_tgt:`BINARY_DIR` target properties
+  were introduced to allow project code to query where a target is defined.
+
+* The :prop_tgt:`OUTPUT_NAME` target property and its variants learned to
+  support :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* A :prop_gbl:`TARGET_MESSAGES` global property was added to tell the
+  :ref:`Makefile Generators` whether to generate commands to print output
+  after each target is completed.
+
+* On Windows with MS-compatible tools, CMake learned to optionally
+  generate a module definition (``.def``) file for ``SHARED`` libraries.
+  See the :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
+
+Modules
+-------
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add`
+  function ``GIT_SUBMODULES`` option now also limits the set of
+  submodules that are initialized in addition to the prior behavior
+  of limiting the set of submodules that are updated.
+
+* The :module:`ExternalProject` module learned new ``USES_TERMINAL``
+  arguments for giving steps exclusive terminal access.  This is
+  useful with the :generator:`Ninja` generator to monitor CMake
+  superbuild progress and prevent CPU oversubscription.
+
+* The :module:`FindBISON` module ``BISON_TARGET`` macro learned a
+  new ``DEFINES_FILE`` option to specify a custom output header
+  to be generated.
+
+* The :module:`FindHDF5` module learend a new ``HDF5_PREFER_PARALLEL``
+  option allowing users to specify that a parallel HDF5 tool is
+  preferred if both are available.
+
+* The :module:`FindIce` module now provides imported targets.
+
+* The :module:`FindJava` module learned to optionally find
+  the ``idlj`` and ``jarsigner`` tools.
+
+* The :module:`FindOpenSSL` module now provides imported targets.
+
+* The :module:`FindOpenSSL` module learned a new ``OPENSSL_USE_STATIC_LIBS``
+  option to search only for static libraries.
+
+* The :module:`FindPkgConfig` learned a new :command:`pkg_get_variable`
+  command which may be used to query for arbitrary variables from a package
+  (such as for related tools or data and plugin install paths).
+
+* The :module:`FindProtobuf` module gained a new
+  :command:`protobuf_generate_python` function to generate python
+  sources from ``.proto`` files.
+
+* The :module:`FindTIFF` module learned to search separately for
+  debug and release variants.
+
+* The :module:`FindwxWidgets` module learned to support version requests.
+
+* The :module:`FindXercesC` module learned to search separately for
+  debug and release variants.
+
+* The :module:`FindZLIB` module learned to search separately for
+  debug and release variants.
+
+* The :module:`GNUInstallDirs` module learned special default values
+  for certain installation prefixes according to the `GNU Coding
+  Standards`_ and the `Filesystem Hierarchy Standard`_.
+
+* The :module:`UseJava` module ``add_jar`` function learned
+  to support response files (e.g. ``@srcs.txt``) for source
+  specification.
+
+* The :module:`UseJava` module ``install_jar`` function learned
+  new ``DESTINATION`` and ``COMPONENT`` options to specify
+  the corresponding :command:`install` command options.
+
+* The :module:`UseJava` module gained a new ``create_javah``
+  function to create C headers from Java classes.
+
+.. _`GNU Coding Standards`: https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+.. _`Filesystem Hierarchy Standard`: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
+
+Generator Expressions
+---------------------
+
+* A new ``$<SHELL_PATH:...>``
+  :manual:`generator expression <cmake-generator-expressions(7)>`
+  has been added.
+
+CTest
+-----
+
+* CTest learned to optionally measure the CPU load during parallel
+  testing and avoid starting tests that may cause the load to exceed
+  a given threshold.  See the :manual:`ctest(1)` command ``--test-load``
+  option, the ``TestLoad`` setting of the :ref:`CTest Test Step`,
+  the :variable:`CTEST_TEST_LOAD` variable, and the ``TEST_LOAD``
+  option of the :command:`ctest_test` command.
+
+* :manual:`ctest(1)` learned options
+  ``--test-output-size-passed`` and ``--test-output-size-failed``
+  to customize the limit on test output size submitted when
+  running as a :ref:`Dashboard Client`.
+
+CPack
+-----
+
+* The :module:`CPackDeb` module learned to set package dependencies
+  per component.  See variables:
+
+  * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_BREAKS`
+  * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONFLICTS`
+  * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_ENHANCES`
+  * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_PREDEPENDS`
+  * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_PROVIDES`
+  * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_RECOMMENDS`
+  * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_REPLACES`
+  * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_SUGGESTS`
+
+* The :module:`CPack` module learned to package empty directories.
+
+* The :module:`CPack` module gained a new setting, ``CPACK_VERBATIM_VARIABLES``,
+  which can be used to ensure the cpack program receives the settings' values
+  exactly as they were set, even if they contain CMake-special characters.
+  For compatibility, it's off by default.
+
+Other
+-----
+
+* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
+  is now aware of features supported by GNU C compilers on Windows.
+
+* CMake learned to honor ``*.manifest`` source files with MSVC tools.
+  Manifest files named as sources of ``.exe`` and ``.dll`` targets
+  will be merged with linker-generated manifests and embedded in the
+  binary.
+
+* The `Concurrent Fortran 77 <https://ccur.com>`__ compiler is now supported.
+  Its :variable:`compiler id <CMAKE_<LANG>_COMPILER_ID>` is ``CCur``.
+
+* :manual:`cmake(1)` gained a new ``--trace-expand`` command line option
+  that is like ``--trace`` but expands variable references in the output.
+
+Deprecated and Removed Features
+===============================
+
+* The :module:`CMakeExpandImportedTargets` module is now documented
+  as deprecated.  See module documentation for an explanation.
+
+* The :variable:`CMAKE_USE_RELATIVE_PATHS` variable no longer has any
+  effect.  Previously it was partially implemented and unreliable.
+
+Other Changes
+=============
+
+* The :module:`CheckFunctionExists`, :module:`CheckLibraryExists`,
+  :module:`CheckSymbolExists`, and :module:`FindThreads` modules learned to
+  work in environments where only CXX is enabled.
+
+* The :module:`CPackDeb` module now correctly excludes symlinks during package
+  checksum calculation.
+
+* The :module:`CPackDeb` no longer uses fakeroot and system tar program for
+  packaging.
+
+* The :module:`CPack` module no longer mangles settings with CMake-special
+  characters when they're used as defaults for other settings. The macro
+  ``cpack_set_if_not_set``, which was responsible for this, is now deprecated.
+
+* CMake no longer links executables with flags to export symbols
+  unless the :prop_tgt:`ENABLE_EXPORTS` target property is set.
+  See policy :policy:`CMP0065`.
+
+* The ``SONAME`` field is no longer set for ``MODULE`` libraries
+  created with the :command:`add_library` command.  ``MODULE``
+  libraries are meant for explicit dynamic loading at runtime.
+  They cannot be linked so ``SONAME`` is not useful.
+
+* The internal :variable:`CMAKE_<LANG>_COMPILE_OBJECT` rule variable now
+  substitutes compiler include flags in a separate ``<INCLUDES>`` placeholder
+  instead of the main ``<FLAGS>`` placeholder.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 6b98e48..5d1a3f7 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -11,6 +11,7 @@ Releases
 .. toctree::
    :maxdepth: 1
 
+   3.4 <3.4>
    3.3 <3.3>
    3.2 <3.2>
    3.1 <3.1>
diff --git a/Help/variable/APPLE.rst b/Help/variable/APPLE.rst
index 3afdee8..a8d2429 100644
--- a/Help/variable/APPLE.rst
+++ b/Help/variable/APPLE.rst
@@ -1,6 +1,6 @@
 APPLE
 -----
 
-True if running on Mac OS X.
+``True`` if running on Mac OS X.
 
-Set to true on Mac OS X.
+Set to ``true`` on Mac OS X.
diff --git a/Help/variable/BORLAND.rst b/Help/variable/BORLAND.rst
index 4af6085..badb733 100644
--- a/Help/variable/BORLAND.rst
+++ b/Help/variable/BORLAND.rst
@@ -1,6 +1,6 @@
 BORLAND
 -------
 
-True if the Borland compiler is being used.
+``True`` if the Borland compiler is being used.
 
-This is set to true if the Borland compiler is being used.
+This is set to ``true`` if the Borland compiler is being used.
diff --git a/Help/variable/BUILD_SHARED_LIBS.rst b/Help/variable/BUILD_SHARED_LIBS.rst
index 6f30efb..53087b2 100644
--- a/Help/variable/BUILD_SHARED_LIBS.rst
+++ b/Help/variable/BUILD_SHARED_LIBS.rst
@@ -1,10 +1,10 @@
 BUILD_SHARED_LIBS
 -----------------
 
-Global flag to cause add_library to create shared libraries if on.
+Global flag to cause :command:`add_library` to create shared libraries if on.
 
 If present and true, this will cause all libraries to be built shared
 unless the library was explicitly added as a static library.  This
-variable is often added to projects as an OPTION so that each user of
-a project can decide if they want to build the project using shared or
+variable is often added to projects as an :command:`option` so that each user
+of a project can decide if they want to build the project using shared or
 static libraries.
diff --git a/Help/variable/CMAKE_ABSOLUTE_DESTINATION_FILES.rst b/Help/variable/CMAKE_ABSOLUTE_DESTINATION_FILES.rst
index 3691453..b6d0054 100644
--- a/Help/variable/CMAKE_ABSOLUTE_DESTINATION_FILES.rst
+++ b/Help/variable/CMAKE_ABSOLUTE_DESTINATION_FILES.rst
@@ -1,9 +1,9 @@
 CMAKE_ABSOLUTE_DESTINATION_FILES
 --------------------------------
 
-List of files which have been installed using  an ABSOLUTE DESTINATION path.
+List of files which have been installed using an ``ABSOLUTE DESTINATION`` path.
 
-This variable is defined by CMake-generated cmake_install.cmake
+This variable is defined by CMake-generated ``cmake_install.cmake``
 scripts.  It can be used (read-only) by programs or scripts that
 source those install scripts.  This is used by some CPack generators
 (e.g.  RPM).
diff --git a/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst b/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
new file mode 100644
index 0000000..8862ba9
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
+------------------------------------
+
+Default value for the :prop_tgt:`ANDROID_ANT_ADDITIONAL_OPTIONS` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_ARCH.rst b/Help/variable/CMAKE_ANDROID_ARCH.rst
new file mode 100644
index 0000000..8fbb46d
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_ARCH.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_ARCH
+------------------
+
+Default value for the :prop_tgt:`ANDROID_ARCH` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
new file mode 100644
index 0000000..c372fe4
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_ASSETS_DIRECTORIES
+--------------------------------
+
+Default value for the :prop_tgt:`ANDROID_ASSETS_DIRECTORIES` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst b/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
new file mode 100644
index 0000000..451a929
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_JAR_DEPENDENCIES
+------------------------------
+
+Default value for the :prop_tgt:`ANDROID_JAR_DEPENDENCIES` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
new file mode 100644
index 0000000..af83e34
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_JAR_DIRECTORIES
+-----------------------------
+
+Default value for the :prop_tgt:`ANDROID_JAR_DIRECTORIES` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst b/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
new file mode 100644
index 0000000..3dc05e0
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_JAVA_SOURCE_DIR
+-----------------------------
+
+Default value for the :prop_tgt:`ANDROID_JAVA_SOURCE_DIR` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
new file mode 100644
index 0000000..4191907
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES
+-------------------------------------
+
+Default value for the :prop_tgt:`ANDROID_NATIVE_LIB_DEPENDENCIES` target
+property.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
new file mode 100644
index 0000000..7cb9527
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES
+------------------------------------
+
+Default value for the :prop_tgt:`ANDROID_NATIVE_LIB_DIRECTORIES` target
+property.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst b/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
new file mode 100644
index 0000000..19fb527
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_PROCESS_MAX
+-------------------------
+
+Default value for the :prop_tgt:`ANDROID_PROCESS_MAX` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROGUARD.rst b/Help/variable/CMAKE_ANDROID_PROGUARD.rst
new file mode 100644
index 0000000..b8fdd46
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_PROGUARD.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_PROGUARD
+----------------------
+
+Default value for the :prop_tgt:`ANDROID_PROGUARD` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst b/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
new file mode 100644
index 0000000..8dea009
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_PROGUARD_CONFIG_PATH
+----------------------------------
+
+Default value for the :prop_tgt:`ANDROID_PROGUARD_CONFIG_PATH` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst b/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
new file mode 100644
index 0000000..69a4d0b
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_SECURE_PROPS_PATH
+-------------------------------
+
+Default value for the :prop_tgt:`ANDROID_SECURE_PROPS_PATH` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst b/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
new file mode 100644
index 0000000..0a96df9
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_SKIP_ANT_STEP
+---------------------------
+
+Default value for the :prop_tgt:`ANDROID_SKIP_ANT_STEP` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_STL_TYPE.rst b/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
new file mode 100644
index 0000000..766b2c8
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_STL_TYPE
+----------------------
+
+Default value for the :prop_tgt:`ANDROID_STL_TYPE` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ARGC.rst b/Help/variable/CMAKE_ARGC.rst
index be120b8..aec9711 100644
--- a/Help/variable/CMAKE_ARGC.rst
+++ b/Help/variable/CMAKE_ARGC.rst
@@ -3,5 +3,6 @@ CMAKE_ARGC
 
 Number of command line arguments passed to CMake in script mode.
 
-When run in -P script mode, CMake sets this variable to the number of
-command line arguments.  See also CMAKE_ARGV0, 1, 2 ...
+When run in :ref:`-P <CMake Options>` script mode, CMake sets this variable to
+the number of command line arguments.  See also :variable:`CMAKE_ARGV0`,
+``1``, ``2`` ...
diff --git a/Help/variable/CMAKE_ARGV0.rst b/Help/variable/CMAKE_ARGV0.rst
index e5ed419..8b1ecb7 100644
--- a/Help/variable/CMAKE_ARGV0.rst
+++ b/Help/variable/CMAKE_ARGV0.rst
@@ -3,7 +3,7 @@ CMAKE_ARGV0
 
 Command line argument passed to CMake in script mode.
 
-When run in -P script mode, CMake sets this variable to the first
-command line argument.  It then also sets CMAKE_ARGV1, CMAKE_ARGV2,
-...  and so on, up to the number of command line arguments given.  See
-also CMAKE_ARGC.
+When run in :ref:`-P <CMake Options>` script mode, CMake sets this variable to
+the first command line argument.  It then also sets ``CMAKE_ARGV1``,
+``CMAKE_ARGV2``, ... and so on, up to the number of command line arguments
+given.  See also :variable:`CMAKE_ARGC`.
diff --git a/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst b/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst
index a814d40..addc62d 100644
--- a/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst
+++ b/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst
@@ -3,11 +3,11 @@ CMAKE_AUTOMOC_RELAXED_MODE
 
 Switch between strict and relaxed automoc mode.
 
-By default, :prop_tgt:`AUTOMOC` behaves exactly as described in the documentation
-of the :prop_tgt:`AUTOMOC` target property.  When set to ``TRUE``, it accepts more
-input and tries to find the correct input file for ``moc`` even if it
-differs from the documented behaviour.  In this mode it e.g.  also
-checks whether a header file is intended to be processed by moc when a
-``"foo.moc"`` file has been included.
+By default, :prop_tgt:`AUTOMOC` behaves exactly as described in the
+documentation of the :prop_tgt:`AUTOMOC` target property.  When set to
+``TRUE``, it accepts more input and tries to find the correct input file for
+``moc`` even if it differs from the documented behaviour.  In this mode it
+e.g.  also checks whether a header file is intended to be processed by moc
+when a ``"foo.moc"`` file has been included.
 
 Relaxed mode has to be enabled for KDE4 compatibility.
diff --git a/Help/variable/CMAKE_AUTORCC.rst b/Help/variable/CMAKE_AUTORCC.rst
index 067f766..7426105 100644
--- a/Help/variable/CMAKE_AUTORCC.rst
+++ b/Help/variable/CMAKE_AUTORCC.rst
@@ -3,5 +3,5 @@ CMAKE_AUTORCC
 
 Whether to handle ``rcc`` automatically for Qt targets.
 
-This variable is used to initialize the :prop_tgt:`AUTORCC` property on all the targets.
-See that target property for additional information.
+This variable is used to initialize the :prop_tgt:`AUTORCC` property on all
+the targets.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_AUTOUIC.rst b/Help/variable/CMAKE_AUTOUIC.rst
index 0beb555..5abefaa 100644
--- a/Help/variable/CMAKE_AUTOUIC.rst
+++ b/Help/variable/CMAKE_AUTOUIC.rst
@@ -3,5 +3,5 @@ CMAKE_AUTOUIC
 
 Whether to handle ``uic`` automatically for Qt targets.
 
-This variable is used to initialize the :prop_tgt:`AUTOUIC` property on all the targets.
-See that target property for additional information.
+This variable is used to initialize the :prop_tgt:`AUTOUIC` property on all
+the targets.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_BINARY_DIR.rst b/Help/variable/CMAKE_BINARY_DIR.rst
index 703bb58..f8dd8ab 100644
--- a/Help/variable/CMAKE_BINARY_DIR.rst
+++ b/Help/variable/CMAKE_BINARY_DIR.rst
@@ -5,4 +5,4 @@ The path to the top level of the build tree.
 
 This is the full path to the top level of the current CMake build
 tree.  For an in-source build, this would be the same as
-CMAKE_SOURCE_DIR.
+:variable:`CMAKE_SOURCE_DIR`.
diff --git a/Help/variable/CMAKE_BUILD_TYPE.rst b/Help/variable/CMAKE_BUILD_TYPE.rst
index 68f08ba..2d54d60 100644
--- a/Help/variable/CMAKE_BUILD_TYPE.rst
+++ b/Help/variable/CMAKE_BUILD_TYPE.rst
@@ -4,16 +4,17 @@ CMAKE_BUILD_TYPE
 Specifies the build type on single-configuration generators.
 
 This statically specifies what build type (configuration) will be
-built in this build tree.  Possible values are empty, Debug, Release,
-RelWithDebInfo and MinSizeRel.  This variable is only meaningful to
-single-configuration generators (such as make and Ninja) i.e.  those
-which choose a single configuration when CMake runs to generate a
-build tree as opposed to multi-configuration generators which offer
-selection of the build configuration within the generated build
+built in this build tree.  Possible values are empty, ``Debug``, ``Release``,
+``RelWithDebInfo`` and ``MinSizeRel``.  This variable is only meaningful to
+single-configuration generators (such as :ref:`Makefile Generators` and
+:generator:`Ninja`) i.e.  those which choose a single configuration when CMake
+runs to generate a build tree as opposed to multi-configuration generators
+which offer selection of the build configuration within the generated build
 environment.  There are many per-config properties and variables
-(usually following clean SOME_VAR_<CONFIG> order conventions), such as
-CMAKE_C_FLAGS_<CONFIG>, specified as uppercase:
-CMAKE_C_FLAGS_[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL].  For example,
-in a build tree configured to build type Debug, CMake will see to
-having CMAKE_C_FLAGS_DEBUG settings get added to the CMAKE_C_FLAGS
-settings.  See also CMAKE_CONFIGURATION_TYPES.
+(usually following clean ``SOME_VAR_<CONFIG>`` order conventions), such as
+``CMAKE_C_FLAGS_<CONFIG>``, specified as uppercase:
+``CMAKE_C_FLAGS_[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL]``.  For example,
+in a build tree configured to build type ``Debug``, CMake will see to
+having :variable:`CMAKE_C_FLAGS_DEBUG <CMAKE_<LANG>_FLAGS_DEBUG>` settings get
+added to the :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>` settings.  See
+also :variable:`CMAKE_CONFIGURATION_TYPES`.
diff --git a/Help/variable/CMAKE_BUILD_WITH_INSTALL_RPATH.rst b/Help/variable/CMAKE_BUILD_WITH_INSTALL_RPATH.rst
index 6875da6..5b59a6e 100644
--- a/Help/variable/CMAKE_BUILD_WITH_INSTALL_RPATH.rst
+++ b/Help/variable/CMAKE_BUILD_WITH_INSTALL_RPATH.rst
@@ -1,11 +1,11 @@
 CMAKE_BUILD_WITH_INSTALL_RPATH
 ------------------------------
 
-Use the install path for the RPATH
+Use the install path for the ``RPATH``.
 
-Normally CMake uses the build tree for the RPATH when building
-executables etc on systems that use RPATH.  When the software is
+Normally CMake uses the build tree for the ``RPATH`` when building
+executables etc on systems that use ``RPATH``.  When the software is
 installed the executables etc are relinked by CMake to have the
-install RPATH.  If this variable is set to true then the software is
-always built with the install path for the RPATH and does not need to
+install ``RPATH``.  If this variable is set to true then the software is
+always built with the install path for the ``RPATH`` and does not need to
 be relinked when installed.
diff --git a/Help/variable/CMAKE_CACHEFILE_DIR.rst b/Help/variable/CMAKE_CACHEFILE_DIR.rst
index 78c7d93..8604d0e 100644
--- a/Help/variable/CMAKE_CACHEFILE_DIR.rst
+++ b/Help/variable/CMAKE_CACHEFILE_DIR.rst
@@ -1,7 +1,7 @@
 CMAKE_CACHEFILE_DIR
 -------------------
 
-The directory with the CMakeCache.txt file.
+The directory with the ``CMakeCache.txt`` file.
 
-This is the full path to the directory that has the CMakeCache.txt
-file in it.  This is the same as CMAKE_BINARY_DIR.
+This is the full path to the directory that has the ``CMakeCache.txt``
+file in it.  This is the same as :variable:`CMAKE_BINARY_DIR`.
diff --git a/Help/variable/CMAKE_CACHE_MAJOR_VERSION.rst b/Help/variable/CMAKE_CACHE_MAJOR_VERSION.rst
index e6887d9..1e53ed6 100644
--- a/Help/variable/CMAKE_CACHE_MAJOR_VERSION.rst
+++ b/Help/variable/CMAKE_CACHE_MAJOR_VERSION.rst
@@ -1,7 +1,7 @@
 CMAKE_CACHE_MAJOR_VERSION
 -------------------------
 
-Major version of CMake used to create the CMakeCache.txt file
+Major version of CMake used to create the ``CMakeCache.txt`` file
 
 This stores the major version of CMake used to write a CMake cache
 file.  It is only different when a different version of CMake is run
diff --git a/Help/variable/CMAKE_CACHE_MINOR_VERSION.rst b/Help/variable/CMAKE_CACHE_MINOR_VERSION.rst
index 799f0a9..5d174a3 100644
--- a/Help/variable/CMAKE_CACHE_MINOR_VERSION.rst
+++ b/Help/variable/CMAKE_CACHE_MINOR_VERSION.rst
@@ -1,7 +1,7 @@
 CMAKE_CACHE_MINOR_VERSION
 -------------------------
 
-Minor version of CMake used to create the CMakeCache.txt file
+Minor version of CMake used to create the ``CMakeCache.txt`` file
 
 This stores the minor version of CMake used to write a CMake cache
 file.  It is only different when a different version of CMake is run
diff --git a/Help/variable/CMAKE_CACHE_PATCH_VERSION.rst b/Help/variable/CMAKE_CACHE_PATCH_VERSION.rst
index e67d544..22d267c 100644
--- a/Help/variable/CMAKE_CACHE_PATCH_VERSION.rst
+++ b/Help/variable/CMAKE_CACHE_PATCH_VERSION.rst
@@ -1,7 +1,7 @@
 CMAKE_CACHE_PATCH_VERSION
 -------------------------
 
-Patch version of CMake used to create the CMakeCache.txt file
+Patch version of CMake used to create the ``CMakeCache.txt`` file
 
 This stores the patch version of CMake used to write a CMake cache
 file.  It is only different when a different version of CMake is run
diff --git a/Help/variable/CMAKE_CFG_INTDIR.rst b/Help/variable/CMAKE_CFG_INTDIR.rst
index 55f7b01..dcc1aed 100644
--- a/Help/variable/CMAKE_CFG_INTDIR.rst
+++ b/Help/variable/CMAKE_CFG_INTDIR.rst
@@ -4,11 +4,11 @@ CMAKE_CFG_INTDIR
 Build-time reference to per-configuration output subdirectory.
 
 For native build systems supporting multiple configurations in the
-build tree (such as Visual Studio and Xcode), the value is a reference
-to a build-time variable specifying the name of the per-configuration
-output subdirectory.  On Makefile generators this evaluates to "."
-because there is only one configuration in a build tree.  Example
-values:
+build tree (such as :ref:`Visual Studio Generators` and :generator:`Xcode`),
+the value is a reference to a build-time variable specifying the name
+of the per-configuration output subdirectory.  On :ref:`Makefile Generators`
+this evaluates to `.` because there is only one configuration in a build tree.
+Example values:
 
 ::
 
@@ -33,13 +33,14 @@ evaluated at build time.  Example of intended usage:
     )
   add_custom_target(drive ALL DEPENDS out.txt)
 
-Note that CMAKE_CFG_INTDIR is no longer necessary for this purpose but
+Note that ``CMAKE_CFG_INTDIR`` is no longer necessary for this purpose but
 has been left for compatibility with existing projects.  Instead
-add_custom_command() recognizes executable target names in its COMMAND
-option, so "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mytool"
-can be replaced by just "mytool".
+:command:`add_custom_command` recognizes executable target names in its
+``COMMAND`` option, so
+``${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mytool`` can be replaced
+by just ``mytool``.
 
 This variable is read-only.  Setting it is undefined behavior.  In
 multi-configuration build systems the value of this variable is passed
-as the value of preprocessor symbol "CMAKE_INTDIR" to the compilation
+as the value of preprocessor symbol ``CMAKE_INTDIR`` to the compilation
 of all source files.
diff --git a/Help/variable/CMAKE_CL_64.rst b/Help/variable/CMAKE_CL_64.rst
index 5096829..a1e86a5 100644
--- a/Help/variable/CMAKE_CL_64.rst
+++ b/Help/variable/CMAKE_CL_64.rst
@@ -1,6 +1,6 @@
 CMAKE_CL_64
 -----------
 
-Using the 64 bit compiler from Microsoft
+Using the 64-bit compiler from Microsoft
 
-Set to true when using the 64 bit cl compiler from Microsoft.
+Set to ``true`` when using the 64-bit ``cl`` compiler from Microsoft.
diff --git a/Help/variable/CMAKE_COLOR_MAKEFILE.rst b/Help/variable/CMAKE_COLOR_MAKEFILE.rst
index 170baf3..bb86ecc 100644
--- a/Help/variable/CMAKE_COLOR_MAKEFILE.rst
+++ b/Help/variable/CMAKE_COLOR_MAKEFILE.rst
@@ -1,7 +1,7 @@
 CMAKE_COLOR_MAKEFILE
 --------------------
 
-Enables color output when using the Makefile generator.
+Enables color output when using the :ref:`Makefile Generators`.
 
 When enabled, the generated Makefiles will produce colored output.
-Default is ON.
+Default is ``ON``.
diff --git a/Help/variable/CMAKE_COMMAND.rst b/Help/variable/CMAKE_COMMAND.rst
index f4e5f1e..f80b46c 100644
--- a/Help/variable/CMAKE_COMMAND.rst
+++ b/Help/variable/CMAKE_COMMAND.rst
@@ -1,8 +1,8 @@
 CMAKE_COMMAND
 -------------
 
-The full path to the cmake executable.
+The full path to the :manual:`cmake(1)` executable.
 
-This is the full path to the CMake executable cmake which is useful
-from custom commands that want to use the cmake -E option for portable
-system commands.  (e.g.  /usr/local/bin/cmake
+This is the full path to the CMake executable :manual:`cmake(1)` which is
+useful from custom commands that want to use the ``cmake -E`` option for
+portable system commands.  (e.g.  ``/usr/local/bin/cmake``)
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst b/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst
index bc5652f..4b652c0 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst
@@ -3,10 +3,10 @@ CMAKE_COMPILER_IS_GNU<LANG>
 
 True if the compiler is GNU.
 
-If the selected <LANG> compiler is the GNU compiler then this is TRUE,
-if not it is FALSE.  Unlike the other per-language variables, this
+If the selected ``<LANG>`` compiler is the GNU compiler then this is ``TRUE``,
+if not it is ``FALSE``.  Unlike the other per-language variables, this
 uses the GNU syntax for identifying languages instead of the CMake
-syntax.  Recognized values of the <LANG> suffix are:
+syntax.  Recognized values of the ``<LANG>`` suffix are:
 
 ::
 
diff --git a/Help/variable/CMAKE_CONFIGURATION_TYPES.rst b/Help/variable/CMAKE_CONFIGURATION_TYPES.rst
index 986b969..34e99eb 100644
--- a/Help/variable/CMAKE_CONFIGURATION_TYPES.rst
+++ b/Help/variable/CMAKE_CONFIGURATION_TYPES.rst
@@ -4,7 +4,7 @@ CMAKE_CONFIGURATION_TYPES
 Specifies the available build types on multi-config generators.
 
 This specifies what build types (configurations) will be available
-such as Debug, Release, RelWithDebInfo etc.  This has reasonable
+such as ``Debug``, ``Release``, ``RelWithDebInfo`` etc.  This has reasonable
 defaults on most platforms, but can be extended to provide other build
-types.  See also CMAKE_BUILD_TYPE for details of managing
-configuration data, and CMAKE_CFG_INTDIR.
+types.  See also :variable:`CMAKE_BUILD_TYPE` for details of managing
+configuration data, and :variable:`CMAKE_CFG_INTDIR`.
diff --git a/Help/variable/CMAKE_CONFIG_POSTFIX.rst b/Help/variable/CMAKE_CONFIG_POSTFIX.rst
index af38bed..e686a43 100644
--- a/Help/variable/CMAKE_CONFIG_POSTFIX.rst
+++ b/Help/variable/CMAKE_CONFIG_POSTFIX.rst
@@ -1,7 +1,7 @@
 CMAKE_<CONFIG>_POSTFIX
 ----------------------
 
-Default filename postfix for libraries under configuration <CONFIG>.
+Default filename postfix for libraries under configuration ``<CONFIG>``.
 
-When a non-executable target is created its <CONFIG>_POSTFIX target
-property is initialized with the value of this variable if it is set.
+When a non-executable target is created its :prop_tgt:`<CONFIG>_POSTFIX`
+target property is initialized with the value of this variable if it is set.
diff --git a/Help/variable/CMAKE_CTEST_COMMAND.rst b/Help/variable/CMAKE_CTEST_COMMAND.rst
index d5dd2c3..b2942e2 100644
--- a/Help/variable/CMAKE_CTEST_COMMAND.rst
+++ b/Help/variable/CMAKE_CTEST_COMMAND.rst
@@ -1,8 +1,8 @@
 CMAKE_CTEST_COMMAND
 -------------------
 
-Full path to ctest command installed with cmake.
+Full path to :manual:`ctest(1)` command installed with CMake.
 
-This is the full path to the CTest executable ctest which is useful
-from custom commands that want to use the cmake -E option for portable
-system commands.
+This is the full path to the CTest executable :manual:`ctest(1)` which is
+useful from custom commands that want to use the :manual:`cmake(1)` ``-E``
+option for portable system commands.
diff --git a/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
index fb55a11..cc3b639 100644
--- a/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
@@ -4,7 +4,7 @@ CMAKE_CURRENT_BINARY_DIR
 The path to the binary directory currently being processed.
 
 This the full path to the build directory that is currently being
-processed by cmake.  Each directory added by add_subdirectory will
+processed by cmake.  Each directory added by :command:`add_subdirectory` will
 create a binary directory in the build tree, and as it is being
 processed this variable will be set.  For in-source builds this is the
 current source directory being processed.
diff --git a/Help/variable/CMAKE_CURRENT_LIST_DIR.rst b/Help/variable/CMAKE_CURRENT_LIST_DIR.rst
index b816821..ebc3ab9 100644
--- a/Help/variable/CMAKE_CURRENT_LIST_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_LIST_DIR.rst
@@ -5,8 +5,8 @@ Full directory of the listfile currently being processed.
 
 As CMake processes the listfiles in your project this variable will
 always be set to the directory where the listfile which is currently
-being processed (CMAKE_CURRENT_LIST_FILE) is located.  The value has
-dynamic scope.  When CMake starts processing commands in a source file
+being processed (:variable:`CMAKE_CURRENT_LIST_FILE`) is located.  The value
+has dynamic scope.  When CMake starts processing commands in a source file
 it sets this variable to the directory where this file is located.
 When CMake finishes processing commands from the file it restores the
 previous value.  Therefore the value of the variable inside a macro or
@@ -14,4 +14,4 @@ function is the directory of the file invoking the bottom-most entry
 on the call stack, not the directory of the file containing the macro
 or function definition.
 
-See also CMAKE_CURRENT_LIST_FILE.
+See also :variable:`CMAKE_CURRENT_LIST_FILE`.
diff --git a/Help/variable/CMAKE_CURRENT_LIST_FILE.rst b/Help/variable/CMAKE_CURRENT_LIST_FILE.rst
index 910d7b4..84b0eee 100644
--- a/Help/variable/CMAKE_CURRENT_LIST_FILE.rst
+++ b/Help/variable/CMAKE_CURRENT_LIST_FILE.rst
@@ -12,4 +12,4 @@ value.  Therefore the value of the variable inside a macro or function
 is the file invoking the bottom-most entry on the call stack, not the
 file containing the macro or function definition.
 
-See also CMAKE_PARENT_LIST_FILE.
+See also :variable:`CMAKE_PARENT_LIST_FILE`.
diff --git a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
index f003227..5c59f95 100644
--- a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
@@ -4,8 +4,8 @@ CMAKE_CXX_COMPILE_FEATURES
 List of features known to the C++ compiler
 
 These features are known to be available for use with the C++ compiler. This
-list is a subset of the features listed in the :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES`
-global property.
+list is a subset of the features listed in the
+:prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global property.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_CXX_EXTENSIONS.rst b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
index b14d753..4a92425 100644
--- a/Help/variable/CMAKE_CXX_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
@@ -1,7 +1,7 @@
 CMAKE_CXX_EXTENSIONS
 --------------------
 
-Default value for ``CXX_EXTENSIONS`` property of targets.
+Default value for :prop_tgt:`CXX_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CXX_EXTENSIONS`
 property on all targets.  See that target property for additional
diff --git a/Help/variable/CMAKE_CXX_STANDARD.rst b/Help/variable/CMAKE_CXX_STANDARD.rst
index 2bc4525..8a8bdff 100644
--- a/Help/variable/CMAKE_CXX_STANDARD.rst
+++ b/Help/variable/CMAKE_CXX_STANDARD.rst
@@ -1,7 +1,7 @@
 CMAKE_CXX_STANDARD
 ------------------
 
-Default value for ``CXX_STANDARD`` property of targets.
+Default value for :prop_tgt:`CXX_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CXX_STANDARD`
 property on all targets.  See that target property for additional
diff --git a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
index 14ffcd1..4c71058 100644
--- a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
@@ -1,7 +1,7 @@
 CMAKE_CXX_STANDARD_REQUIRED
 ---------------------------
 
-Default value for ``CXX_STANDARD_REQUIRED`` property of targets.
+Default value for :prop_tgt:`CXX_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CXX_STANDARD_REQUIRED`
 property on all targets.  See that target property for additional
diff --git a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
index df66eae..8d1eca0 100644
--- a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
@@ -4,8 +4,8 @@ CMAKE_C_COMPILE_FEATURES
 List of features known to the C compiler
 
 These features are known to be available for use with the C compiler. This
-list is a subset of the features listed in the :prop_gbl:`CMAKE_C_KNOWN_FEATURES`
-global property.
+list is a subset of the features listed in the
+:prop_gbl:`CMAKE_C_KNOWN_FEATURES` global property.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_C_EXTENSIONS.rst b/Help/variable/CMAKE_C_EXTENSIONS.rst
index 25bec12..fa510d4 100644
--- a/Help/variable/CMAKE_C_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_C_EXTENSIONS.rst
@@ -1,7 +1,7 @@
 CMAKE_C_EXTENSIONS
 ------------------
 
-Default value for ``C_EXTENSIONS`` property of targets.
+Default value for :prop_tgt:`C_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`C_EXTENSIONS`
 property on all targets.  See that target property for additional
diff --git a/Help/variable/CMAKE_C_STANDARD.rst b/Help/variable/CMAKE_C_STANDARD.rst
index 2eb4e43..b55e00c 100644
--- a/Help/variable/CMAKE_C_STANDARD.rst
+++ b/Help/variable/CMAKE_C_STANDARD.rst
@@ -1,7 +1,7 @@
 CMAKE_C_STANDARD
 ----------------
 
-Default value for ``C_STANDARD`` property of targets.
+Default value for :prop_tgt:`C_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`C_STANDARD`
 property on all targets.  See that target property for additional
diff --git a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
index 5e415da..7f70f6e 100644
--- a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
@@ -1,7 +1,7 @@
 CMAKE_C_STANDARD_REQUIRED
 -------------------------
 
-Default value for ``C_STANDARD_REQUIRED`` property of targets.
+Default value for :prop_tgt:`C_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`C_STANDARD_REQUIRED`
 property on all targets.  See that target property for additional
diff --git a/Help/variable/CMAKE_DEBUG_POSTFIX.rst b/Help/variable/CMAKE_DEBUG_POSTFIX.rst
index fde24b2..08577a5 100644
--- a/Help/variable/CMAKE_DEBUG_POSTFIX.rst
+++ b/Help/variable/CMAKE_DEBUG_POSTFIX.rst
@@ -1,7 +1,7 @@
 CMAKE_DEBUG_POSTFIX
 -------------------
 
-See variable CMAKE_<CONFIG>_POSTFIX.
+See variable :variable:`CMAKE_<CONFIG>_POSTFIX`.
 
 This variable is a special case of the more-general
-CMAKE_<CONFIG>_POSTFIX variable for the DEBUG configuration.
+:variable:`CMAKE_<CONFIG>_POSTFIX` variable for the `DEBUG` configuration.
diff --git a/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
index e200b86..513276e 100644
--- a/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
+++ b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
@@ -9,6 +9,6 @@ only be used when evaluating the :prop_tgt:`INCLUDE_DIRECTORIES`,
 :prop_tgt:`COMPILE_DEFINITIONS`, :prop_tgt:`COMPILE_OPTIONS`,
 :prop_tgt:`AUTOUIC_OPTIONS`, :prop_tgt:`SOURCES`, :prop_tgt:`COMPILE_FEATURES`,
 :prop_tgt:`POSITION_INDEPENDENT_CODE` target properties and any other property
-listed in :prop_tgt:`COMPATIBLE_INTERFACE_STRING` and other ``COMPATIBLE_INTERFACE_``
-properties.  It outputs an origin for each entry in the target property.
-Default is unset.
+listed in :prop_tgt:`COMPATIBLE_INTERFACE_STRING` and other
+``COMPATIBLE_INTERFACE_`` properties.  It outputs an origin for each entry in
+the target property.  Default is unset.
diff --git a/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst b/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst
index bcb277c..ed60020 100644
--- a/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst
+++ b/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst
@@ -1,10 +1,11 @@
 CMAKE_DISABLE_FIND_PACKAGE_<PackageName>
 ----------------------------------------
 
-Variable for disabling find_package() calls.
+Variable for disabling :command:`find_package` calls.
 
-Every non-REQUIRED find_package() call in a project can be disabled by
-setting the variable CMAKE_DISABLE_FIND_PACKAGE_<PackageName> to TRUE.
+Every non-``REQUIRED`` :command:`find_package` call in a project can be
+disabled by setting the variable
+``CMAKE_DISABLE_FIND_PACKAGE_<PackageName>`` to ``TRUE``.
 This can be used to build a project without an optional package,
 although that package is installed.
 
@@ -12,4 +13,4 @@ This switch should be used during the initial CMake run.  Otherwise if
 the package has already been found in a previous CMake run, the
 variables which have been stored in the cache will still be there.  In
 that case it is recommended to remove the cache variables for this
-package from the cache using the cache editor or cmake -U
+package from the cache using the cache editor or :manual:`cmake(1)` ``-U``
diff --git a/Help/variable/CMAKE_DL_LIBS.rst b/Help/variable/CMAKE_DL_LIBS.rst
index cae4565..1fe7641 100644
--- a/Help/variable/CMAKE_DL_LIBS.rst
+++ b/Help/variable/CMAKE_DL_LIBS.rst
@@ -1,7 +1,7 @@
 CMAKE_DL_LIBS
 -------------
 
-Name of library containing dlopen and dlcose.
+Name of library containing ``dlopen`` and ``dlcose``.
 
-The name of the library that has dlopen and dlclose in it, usually
--ldl on most UNIX machines.
+The name of the library that has ``dlopen`` and ``dlclose`` in it, usually
+``-ldl`` on most UNIX machines.
diff --git a/Help/variable/CMAKE_EDIT_COMMAND.rst b/Help/variable/CMAKE_EDIT_COMMAND.rst
index 562aa0b..2f4ab1f 100644
--- a/Help/variable/CMAKE_EDIT_COMMAND.rst
+++ b/Help/variable/CMAKE_EDIT_COMMAND.rst
@@ -1,8 +1,8 @@
 CMAKE_EDIT_COMMAND
 ------------------
 
-Full path to cmake-gui or ccmake.  Defined only for Makefile generators
-when not using an "extra" generator for an IDE.
+Full path to :manual:`cmake-gui(1)` or :manual:`ccmake(1)`.  Defined only for
+:ref:`Makefile Generators` when not using an "extra" generator for an IDE.
 
 This is the full path to the CMake executable that can graphically
-edit the cache.  For example, cmake-gui or ccmake.
+edit the cache.  For example, :manual:`cmake-gui(1)` or :manual:`ccmake(1)`.
diff --git a/Help/variable/CMAKE_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
new file mode 100644
index 0000000..1f9ba6f
--- /dev/null
+++ b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
@@ -0,0 +1,22 @@
+CMAKE_ENABLE_EXPORTS
+--------------------
+
+Specify whether an executable exports symbols for loadable modules.
+
+Normally an executable does not export any symbols because it is the
+final program.  It is possible for an executable to export symbols to
+be used by loadable modules.  When this property is set to true CMake
+will allow other targets to "link" to the executable with the
+:command:`TARGET_LINK_LIBRARIES` command.  On all platforms a target-level
+dependency on the executable is created for targets that link to it.
+For DLL platforms an import library will be created for the exported
+symbols and then used for linking.  All Windows-based systems
+including Cygwin are DLL platforms.  For non-DLL platforms that
+require all symbols to be resolved at link time, such as Mac OS X, the
+module will "link" to the executable using a flag like
+"-bundle_loader".  For other non-DLL platforms the link rule is simply
+ignored since the dynamic loader will automatically bind symbols when
+the module is loaded.
+
+This variable is used to initialize the target property
+:prop_tgt:`ENABLE_EXPORTS` for executable targets.
diff --git a/Help/variable/CMAKE_ERROR_DEPRECATED.rst b/Help/variable/CMAKE_ERROR_DEPRECATED.rst
index 43ab282..277a4cc 100644
--- a/Help/variable/CMAKE_ERROR_DEPRECATED.rst
+++ b/Help/variable/CMAKE_ERROR_DEPRECATED.rst
@@ -3,6 +3,6 @@ CMAKE_ERROR_DEPRECATED
 
 Whether to issue deprecation errors for macros and functions.
 
-If TRUE, this can be used by macros and functions to issue fatal
+If ``TRUE``, this can be used by macros and functions to issue fatal
 errors when deprecated macros or functions are used.  This variable is
-FALSE by default.
+``FALSE`` by default.
diff --git a/Help/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst b/Help/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
index 651d68d..38e9b7b 100644
--- a/Help/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
+++ b/Help/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
@@ -1,9 +1,10 @@
 CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
 -------------------------------------------
 
-Ask cmake_install.cmake script to error out as soon as a file with absolute INSTALL DESTINATION is encountered.
+Ask ``cmake_install.cmake`` script to error out as soon as a file with
+absolute ``INSTALL DESTINATION`` is encountered.
 
 The fatal error is emitted before the installation of the offending
 file takes place.  This variable is used by CMake-generated
-cmake_install.cmake scripts.  If one sets this variable to ON while
+``cmake_install.cmake`` scripts.  If one sets this variable to ``ON`` while
 running the script, it may get fatal error messages from the script.
diff --git a/Help/variable/CMAKE_EXECUTABLE_SUFFIX.rst b/Help/variable/CMAKE_EXECUTABLE_SUFFIX.rst
index 45c313c..356590f 100644
--- a/Help/variable/CMAKE_EXECUTABLE_SUFFIX.rst
+++ b/Help/variable/CMAKE_EXECUTABLE_SUFFIX.rst
@@ -3,7 +3,7 @@ CMAKE_EXECUTABLE_SUFFIX
 
 The suffix for executables on this platform.
 
-The suffix to use for the end of an executable filename if any, .exe
+The suffix to use for the end of an executable filename if any, ``.exe``
 on Windows.
 
-CMAKE_EXECUTABLE_SUFFIX_<LANG> overrides this for language <LANG>.
+``CMAKE_EXECUTABLE_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst
index dcaf300..0cd8113 100644
--- a/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst
+++ b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst
@@ -3,5 +3,5 @@ CMAKE_EXE_LINKER_FLAGS_<CONFIG>
 
 Flags to be used when linking an executable.
 
-Same as CMAKE_C_FLAGS_* but used by the linker when creating
+Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating
 executables.
diff --git a/Help/variable/CMAKE_EXTRA_GENERATOR.rst b/Help/variable/CMAKE_EXTRA_GENERATOR.rst
index 71aec92..4d513e4 100644
--- a/Help/variable/CMAKE_EXTRA_GENERATOR.rst
+++ b/Help/variable/CMAKE_EXTRA_GENERATOR.rst
@@ -1,9 +1,10 @@
 CMAKE_EXTRA_GENERATOR
 ---------------------
 
-The extra generator used to build the project.
+The extra generator used to build the project.  See
+:manual:`cmake-generators(7)`.
 
 When using the Eclipse, CodeBlocks or KDevelop generators, CMake
-generates Makefiles (CMAKE_GENERATOR) and additionally project files
-for the respective IDE.  This IDE project file generator is stored in
-CMAKE_EXTRA_GENERATOR (e.g.  "Eclipse CDT4").
+generates Makefiles (:variable:`CMAKE_GENERATOR`) and additionally project
+files for the respective IDE.  This IDE project file generator is stored in
+``CMAKE_EXTRA_GENERATOR`` (e.g.  ``Eclipse CDT4``).
diff --git a/Help/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES.rst b/Help/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES.rst
index 6187a7a..a130adb 100644
--- a/Help/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES.rst
+++ b/Help/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES.rst
@@ -4,6 +4,6 @@ CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
 Additional suffixes for shared libraries.
 
 Extensions for shared libraries other than that specified by
-CMAKE_SHARED_LIBRARY_SUFFIX, if any.  CMake uses this to recognize
+:variable:`CMAKE_SHARED_LIBRARY_SUFFIX`, if any.  CMake uses this to recognize
 external shared library files during analysis of libraries linked by a
 target.
diff --git a/Help/variable/CMAKE_FIND_APPBUNDLE.rst b/Help/variable/CMAKE_FIND_APPBUNDLE.rst
new file mode 100644
index 0000000..e0727b5
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_APPBUNDLE.rst
@@ -0,0 +1,22 @@
+CMAKE_FIND_APPBUNDLE
+--------------------
+
+This variable affects how ``find_*`` commands choose between
+OS X Application Bundles and unix-style package components.
+
+On Darwin or systems supporting OS X Application Bundles, the
+``CMAKE_FIND_APPBUNDLE`` variable can be set to empty or
+one of the following:
+
+``FIRST``
+  Try to find application bundles before standard programs.
+  This is the default on Darwin.
+
+``LAST``
+  Try to find application bundles after standard programs.
+
+``ONLY``
+  Only try to find application bundles.
+
+``NEVER``
+  Never try to find application bundles.
diff --git a/Help/variable/CMAKE_FIND_FRAMEWORK.rst b/Help/variable/CMAKE_FIND_FRAMEWORK.rst
new file mode 100644
index 0000000..790694a
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_FRAMEWORK.rst
@@ -0,0 +1,22 @@
+CMAKE_FIND_FRAMEWORK
+--------------------
+
+This variable affects how ``find_*`` commands choose between
+OS X Frameworks and unix-style package components.
+
+On Darwin or systems supporting OS X Frameworks, the
+``CMAKE_FIND_FRAMEWORK`` variable can be set to empty or
+one of the following:
+
+``FIRST``
+  Try to find frameworks before standard libraries or headers.
+  This is the default on Darwin.
+
+``LAST``
+  Try to find frameworks after standard libraries or headers.
+
+``ONLY``
+  Only try to find frameworks.
+
+``NEVER``
+  Never try to find frameworks.
diff --git a/Help/variable/CMAKE_FIND_LIBRARY_PREFIXES.rst b/Help/variable/CMAKE_FIND_LIBRARY_PREFIXES.rst
index 1a9e7ce..58354b2 100644
--- a/Help/variable/CMAKE_FIND_LIBRARY_PREFIXES.rst
+++ b/Help/variable/CMAKE_FIND_LIBRARY_PREFIXES.rst
@@ -4,6 +4,6 @@ CMAKE_FIND_LIBRARY_PREFIXES
 Prefixes to prepend when looking for libraries.
 
 This specifies what prefixes to add to library names when the
-find_library command looks for libraries.  On UNIX systems this is
-typically lib, meaning that when trying to find the foo library it
-will look for libfoo.
+:command:`find_library` command looks for libraries.  On UNIX systems this is
+typically ``lib``, meaning that when trying to find the ``foo`` library it
+will look for ``libfoo``.
diff --git a/Help/variable/CMAKE_FIND_LIBRARY_SUFFIXES.rst b/Help/variable/CMAKE_FIND_LIBRARY_SUFFIXES.rst
index c533909..4a64e33 100644
--- a/Help/variable/CMAKE_FIND_LIBRARY_SUFFIXES.rst
+++ b/Help/variable/CMAKE_FIND_LIBRARY_SUFFIXES.rst
@@ -4,6 +4,6 @@ CMAKE_FIND_LIBRARY_SUFFIXES
 Suffixes to append when looking for libraries.
 
 This specifies what suffixes to add to library names when the
-find_library command looks for libraries.  On Windows systems this is
-typically .lib and .dll, meaning that when trying to find the foo
-library it will look for foo.dll etc.
+:command:`find_library` command looks for libraries.  On Windows systems this
+is typically ``.lib`` and ``.dll``, meaning that when trying to find the
+``foo`` library it will look for ``foo.dll`` etc.
diff --git a/Help/variable/CMAKE_FIND_NO_INSTALL_PREFIX.rst b/Help/variable/CMAKE_FIND_NO_INSTALL_PREFIX.rst
index 70d920b..c49d264 100644
--- a/Help/variable/CMAKE_FIND_NO_INSTALL_PREFIX.rst
+++ b/Help/variable/CMAKE_FIND_NO_INSTALL_PREFIX.rst
@@ -8,8 +8,8 @@ CMake adds the :variable:`CMAKE_INSTALL_PREFIX` and the
 :variable:`CMAKE_SYSTEM_PREFIX_PATH` by default. This variable may be set
 on the command line to control that behavior.
 
-Set :variable:`CMAKE_FIND_NO_INSTALL_PREFIX` to TRUE to tell find_package not
-to search in the :variable:`CMAKE_INSTALL_PREFIX` or
-:variable:`CMAKE_STAGING_PREFIX` by default.  Note that the
+Set ``CMAKE_FIND_NO_INSTALL_PREFIX`` to ``TRUE`` to tell
+:command:`find_package` not to search in the :variable:`CMAKE_INSTALL_PREFIX`
+or :variable:`CMAKE_STAGING_PREFIX` by default.  Note that the
 prefix may still be searched for other reasons, such as being the same prefix
 as the CMake installation, or for being a built-in system prefix.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst b/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst
index 5d7599c..f1116bb 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst
@@ -1,19 +1,19 @@
 CMAKE_FIND_PACKAGE_WARN_NO_MODULE
 ---------------------------------
 
-Tell find_package to warn if called without an explicit mode.
+Tell :command:`find_package` to warn if called without an explicit mode.
 
-If find_package is called without an explicit mode option (MODULE,
-CONFIG or NO_MODULE) and no Find<pkg>.cmake module is in
-CMAKE_MODULE_PATH then CMake implicitly assumes that the caller
-intends to search for a package configuration file.  If no package
+If :command:`find_package` is called without an explicit mode option
+(``MODULE``, ``CONFIG``, or ``NO_MODULE``) and no ``Find<pkg>.cmake`` module
+is in :variable:`CMAKE_MODULE_PATH` then CMake implicitly assumes that the
+caller intends to search for a package configuration file.  If no package
 configuration file is found then the wording of the failure message
 must account for both the case that the package is really missing and
 the case that the project has a bug and failed to provide the intended
 Find module.  If instead the caller specifies an explicit mode option
 then the failure message can be more specific.
 
-Set CMAKE_FIND_PACKAGE_WARN_NO_MODULE to TRUE to tell find_package to
-warn when it implicitly assumes Config mode.  This helps developers
-enforce use of an explicit mode in all calls to find_package within a
-project.
+Set ``CMAKE_FIND_PACKAGE_WARN_NO_MODULE`` to ``TRUE`` to tell
+:command:`find_package` to warn when it implicitly assumes Config mode.  This
+helps developers enforce use of an explicit mode in all calls to
+:command:`find_package` within a project.
diff --git a/Help/variable/CMAKE_FIND_ROOT_PATH.rst b/Help/variable/CMAKE_FIND_ROOT_PATH.rst
index ccf5234..ba2cf31 100644
--- a/Help/variable/CMAKE_FIND_ROOT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_ROOT_PATH.rst
@@ -4,5 +4,5 @@ CMAKE_FIND_ROOT_PATH
 :ref:`;-list <CMake Language Lists>` of root paths to search on the filesystem.
 
 This variable is most useful when cross-compiling. CMake uses the paths in
-this list as alternative roots to find filesystem items with :command:`find_package`,
-:command:`find_library` etc.
+this list as alternative roots to find filesystem items with
+:command:`find_package`, :command:`find_library` etc.
diff --git a/Help/variable/CMAKE_Fortran_FORMAT.rst b/Help/variable/CMAKE_Fortran_FORMAT.rst
index c0e971c..1406e59 100644
--- a/Help/variable/CMAKE_Fortran_FORMAT.rst
+++ b/Help/variable/CMAKE_Fortran_FORMAT.rst
@@ -1,7 +1,7 @@
 CMAKE_Fortran_FORMAT
 --------------------
 
-Set to FIXED or FREE to indicate the Fortran source layout.
+Set to ``FIXED`` or ``FREE`` to indicate the Fortran source layout.
 
-This variable is used to initialize the Fortran_FORMAT property on all
-the targets.  See that target property for additional information.
+This variable is used to initialize the :prop_tgt:`Fortran_FORMAT` property on
+all the targets.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_Fortran_MODDIR_DEFAULT.rst b/Help/variable/CMAKE_Fortran_MODDIR_DEFAULT.rst
index a8dfcdf..5aeab07 100644
--- a/Help/variable/CMAKE_Fortran_MODDIR_DEFAULT.rst
+++ b/Help/variable/CMAKE_Fortran_MODDIR_DEFAULT.rst
@@ -3,6 +3,6 @@ CMAKE_Fortran_MODDIR_DEFAULT
 
 Fortran default module output directory.
 
-Most Fortran compilers write .mod files to the current working
-directory.  For those that do not, this is set to "." and used when
-the Fortran_MODULE_DIRECTORY target property is not set.
+Most Fortran compilers write ``.mod`` files to the current working
+directory.  For those that do not, this is set to ``.`` and used when
+the :prop_tgt:`Fortran_MODULE_DIRECTORY` target property is not set.
diff --git a/Help/variable/CMAKE_Fortran_MODDIR_FLAG.rst b/Help/variable/CMAKE_Fortran_MODDIR_FLAG.rst
index 4b32df3..1da55ca 100644
--- a/Help/variable/CMAKE_Fortran_MODDIR_FLAG.rst
+++ b/Help/variable/CMAKE_Fortran_MODDIR_FLAG.rst
@@ -4,4 +4,4 @@ CMAKE_Fortran_MODDIR_FLAG
 Fortran flag for module output directory.
 
 This stores the flag needed to pass the value of the
-Fortran_MODULE_DIRECTORY target property to the compiler.
+:prop_tgt:`Fortran_MODULE_DIRECTORY` target property to the compiler.
diff --git a/Help/variable/CMAKE_Fortran_MODOUT_FLAG.rst b/Help/variable/CMAKE_Fortran_MODOUT_FLAG.rst
index a232213..2f83880 100644
--- a/Help/variable/CMAKE_Fortran_MODOUT_FLAG.rst
+++ b/Help/variable/CMAKE_Fortran_MODOUT_FLAG.rst
@@ -3,5 +3,5 @@ CMAKE_Fortran_MODOUT_FLAG
 
 Fortran flag to enable module output.
 
-Most Fortran compilers write .mod files out by default.  For others,
+Most Fortran compilers write ``.mod`` files out by default.  For others,
 this stores the flag needed to enable module output.
diff --git a/Help/variable/CMAKE_Fortran_MODULE_DIRECTORY.rst b/Help/variable/CMAKE_Fortran_MODULE_DIRECTORY.rst
index b1d49d8..3c7edc1 100644
--- a/Help/variable/CMAKE_Fortran_MODULE_DIRECTORY.rst
+++ b/Help/variable/CMAKE_Fortran_MODULE_DIRECTORY.rst
@@ -3,6 +3,6 @@ CMAKE_Fortran_MODULE_DIRECTORY
 
 Fortran module output directory.
 
-This variable is used to initialize the Fortran_MODULE_DIRECTORY
+This variable is used to initialize the :prop_tgt:`Fortran_MODULE_DIRECTORY`
 property on all the targets.  See that target property for additional
 information.
diff --git a/Help/variable/CMAKE_GENERATOR.rst b/Help/variable/CMAKE_GENERATOR.rst
index a4e70a5..3f6ebc1 100644
--- a/Help/variable/CMAKE_GENERATOR.rst
+++ b/Help/variable/CMAKE_GENERATOR.rst
@@ -1,7 +1,7 @@
 CMAKE_GENERATOR
 ---------------
 
-The generator used to build the project.
+The generator used to build the project.  See :manual:`cmake-generators(7)`.
 
 The name of the generator that is being used to generate the build
-files.  (e.g.  "Unix Makefiles", "Visual Studio 6", etc.)
+files.  (e.g.  ``Unix Makefiles``, ``Visual Studio 6``, etc.)
diff --git a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
index 5559eb7..a5c284a 100644
--- a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
+++ b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
@@ -5,8 +5,8 @@ Generator-specific target platform name specified by user.
 
 Some CMake generators support a target platform name to be given
 to the native build system to choose a compiler toolchain.
-If the user specifies a platform name (e.g. via the cmake -A option)
-the value will be available in this variable.
+If the user specifies a platform name (e.g. via the :manual:`cmake(1)` ``-A``
+option) the value will be available in this variable.
 
 The value of this variable should never be modified by project code.
 A toolchain file specified by the :variable:`CMAKE_TOOLCHAIN_FILE`
diff --git a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
index 9ccc8b3..89abe54 100644
--- a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
+++ b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
@@ -5,8 +5,8 @@ Native build system toolset name specified by user.
 
 Some CMake generators support a toolset name to be given to the native
 build system to choose a compiler.  If the user specifies a toolset
-name (e.g.  via the cmake -T option) the value will be available in
-this variable.
+name (e.g.  via the :manual:`cmake(1)` ``-T`` option) the value will be
+available in this variable.
 
 The value of this variable should never be modified by project code.
 A toolchain file specified by the :variable:`CMAKE_TOOLCHAIN_FILE`
diff --git a/Help/variable/CMAKE_GNUtoMS.rst b/Help/variable/CMAKE_GNUtoMS.rst
index e253f59..9c0f59e 100644
--- a/Help/variable/CMAKE_GNUtoMS.rst
+++ b/Help/variable/CMAKE_GNUtoMS.rst
@@ -1,8 +1,8 @@
 CMAKE_GNUtoMS
 -------------
 
-Convert GNU import libraries (.dll.a) to MS format (.lib).
+Convert GNU import libraries (``.dll.a``) to MS format (``.lib``).
 
-This variable is used to initialize the GNUtoMS property on targets
-when they are created.  See that target property for additional
+This variable is used to initialize the :prop_tgt:`GNUtoMS` property on
+targets when they are created.  See that target property for additional
 information.
diff --git a/Help/variable/CMAKE_HOST_APPLE.rst b/Help/variable/CMAKE_HOST_APPLE.rst
index d4b8483..ac7b030 100644
--- a/Help/variable/CMAKE_HOST_APPLE.rst
+++ b/Help/variable/CMAKE_HOST_APPLE.rst
@@ -1,6 +1,6 @@
 CMAKE_HOST_APPLE
 ----------------
 
-True for Apple OS X operating systems.
+``True`` for Apple OS X operating systems.
 
-Set to true when the host system is Apple OS X.
+Set to ``true`` when the host system is Apple OS X.
diff --git a/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst b/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst
index a221de9..e5e6f67 100644
--- a/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst
+++ b/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst
@@ -4,5 +4,5 @@ CMAKE_HOST_SYSTEM_NAME
 Name of the OS CMake is running on.
 
 On systems that have the uname command, this variable is set to the
-output of uname -s.  ``Linux``, ``Windows``, and ``Darwin`` for Mac OS X
+output of ``uname -s``.  ``Linux``, ``Windows``, and ``Darwin`` for Mac OS X
 are the values found on the big three operating systems.
diff --git a/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst b/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst
index 790565a..ba8a850 100644
--- a/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst
+++ b/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst
@@ -3,6 +3,6 @@ CMAKE_HOST_SYSTEM_PROCESSOR
 
 The name of the CPU CMake is running on.
 
-On systems that support uname, this variable is set to the output of
-uname -p, on windows it is set to the value of the environment variable
+On systems that support ``uname``, this variable is set to the output of
+``uname -p``.  On Windows it is set to the value of the environment variable
 ``PROCESSOR_ARCHITECTURE``.
diff --git a/Help/variable/CMAKE_HOST_SYSTEM_VERSION.rst b/Help/variable/CMAKE_HOST_SYSTEM_VERSION.rst
index e7e0052..ed23070 100644
--- a/Help/variable/CMAKE_HOST_SYSTEM_VERSION.rst
+++ b/Help/variable/CMAKE_HOST_SYSTEM_VERSION.rst
@@ -4,5 +4,5 @@ CMAKE_HOST_SYSTEM_VERSION
 The OS version CMake is running on.
 
 A numeric version string for the system.  On systems that support
-uname, this variable is set to the output of uname -r. On other
+``uname``, this variable is set to the output of ``uname -r``. On other
 systems this is set to major-minor version numbers.
diff --git a/Help/variable/CMAKE_HOST_UNIX.rst b/Help/variable/CMAKE_HOST_UNIX.rst
index bbefba7..817a957 100644
--- a/Help/variable/CMAKE_HOST_UNIX.rst
+++ b/Help/variable/CMAKE_HOST_UNIX.rst
@@ -1,7 +1,7 @@
 CMAKE_HOST_UNIX
 ---------------
 
-True for UNIX and UNIX like operating systems.
+``True`` for UNIX and UNIX like operating systems.
 
-Set to true when the host system is UNIX or UNIX like (i.e.  APPLE and
+Set to ``true`` when the host system is UNIX or UNIX like (i.e.  APPLE and
 CYGWIN).
diff --git a/Help/variable/CMAKE_HOST_WIN32.rst b/Help/variable/CMAKE_HOST_WIN32.rst
index 92ee456..0e4c891 100644
--- a/Help/variable/CMAKE_HOST_WIN32.rst
+++ b/Help/variable/CMAKE_HOST_WIN32.rst
@@ -1,6 +1,6 @@
 CMAKE_HOST_WIN32
 ----------------
 
-True on windows systems, including win64.
+``True`` on Windows systems, including Win64.
 
-Set to true when the host system is Windows and on Cygwin.
+Set to ``true`` when the host system is Windows and on Cygwin.
diff --git a/Help/variable/CMAKE_IMPORT_LIBRARY_PREFIX.rst b/Help/variable/CMAKE_IMPORT_LIBRARY_PREFIX.rst
index 1d16a37..1561a1d 100644
--- a/Help/variable/CMAKE_IMPORT_LIBRARY_PREFIX.rst
+++ b/Help/variable/CMAKE_IMPORT_LIBRARY_PREFIX.rst
@@ -6,4 +6,4 @@ The prefix for import libraries that you link to.
 The prefix to use for the name of an import library if used on this
 platform.
 
-CMAKE_IMPORT_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>.
+``CMAKE_IMPORT_LIBRARY_PREFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_IMPORT_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_IMPORT_LIBRARY_SUFFIX.rst
index c16825e..11aeab7 100644
--- a/Help/variable/CMAKE_IMPORT_LIBRARY_SUFFIX.rst
+++ b/Help/variable/CMAKE_IMPORT_LIBRARY_SUFFIX.rst
@@ -6,4 +6,4 @@ The suffix for import libraries that you link to.
 The suffix to use for the end of an import library filename if used on
 this platform.
 
-CMAKE_IMPORT_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>.
+``CMAKE_IMPORT_LIBRARY_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_INCLUDE_CURRENT_DIR.rst b/Help/variable/CMAKE_INCLUDE_CURRENT_DIR.rst
index 79f3952..6eea322 100644
--- a/Help/variable/CMAKE_INCLUDE_CURRENT_DIR.rst
+++ b/Help/variable/CMAKE_INCLUDE_CURRENT_DIR.rst
@@ -3,11 +3,11 @@ CMAKE_INCLUDE_CURRENT_DIR
 
 Automatically add the current source- and build directories to the include path.
 
-If this variable is enabled, CMake automatically adds in each
-directory ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR}
-to the include path for this directory.  These additional include
+If this variable is enabled, CMake automatically adds
+:variable:`CMAKE_CURRENT_SOURCE_DIR` and :variable:`CMAKE_CURRENT_BINARY_DIR`
+to the include path for each directory.  These additional include
 directories do not propagate down to subdirectories.  This is useful
 mainly for out-of-source builds, where files generated into the build
 tree are included by files located in the source tree.
 
-By default CMAKE_INCLUDE_CURRENT_DIR is OFF.
+By default ``CMAKE_INCLUDE_CURRENT_DIR`` is ``OFF``.
diff --git a/Help/variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.rst b/Help/variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.rst
index 948db50..5fc95f0 100644
--- a/Help/variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.rst
+++ b/Help/variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.rst
@@ -1,10 +1,12 @@
 CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE
 --------------------------------------
 
-Automatically add the current source- and build directories to the INTERFACE_INCLUDE_DIRECTORIES.
+Automatically add the current source- and build directories to the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property.
 
 If this variable is enabled, CMake automatically adds for each shared
 library target, static library target, module target and executable
-target, ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} to
-the INTERFACE_INCLUDE_DIRECTORIES.By default
-CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE is OFF.
+target, :variable:`CMAKE_CURRENT_SOURCE_DIR` and
+:variable:`CMAKE_CURRENT_BINARY_DIR` to
+the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property.  By default
+``CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE`` is ``OFF``.
diff --git a/Help/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE.rst b/Help/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE.rst
index 3c1fbcf..e0f2a2e 100644
--- a/Help/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE.rst
+++ b/Help/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE.rst
@@ -1,8 +1,9 @@
 CMAKE_INCLUDE_DIRECTORIES_BEFORE
 --------------------------------
 
-Whether to append or prepend directories by default in :command:`include_directories`.
+Whether to append or prepend directories by default in
+:command:`include_directories`.
 
 This variable affects the default behavior of the :command:`include_directories`
-command. Setting this variable to 'ON' is equivalent to using the BEFORE option
-in all uses of that command.
+command.  Setting this variable to ``ON`` is equivalent to using the ``BEFORE``
+option in all uses of that command.
diff --git a/Help/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE.rst b/Help/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE.rst
index cbd04d7..37d0a3d 100644
--- a/Help/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE.rst
+++ b/Help/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE.rst
@@ -4,5 +4,5 @@ CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
 Whether to force prepending of project include directories.
 
 This variable affects the order of include directories generated in compiler
-command lines.  If set to 'ON', it causes the :variable:`CMAKE_SOURCE_DIR` and
-the :variable:`CMAKE_BINARY_DIR` to appear first.
+command lines.  If set to ``ON``, it causes the :variable:`CMAKE_SOURCE_DIR`
+and the :variable:`CMAKE_BINARY_DIR` to appear first.
diff --git a/Help/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME.rst b/Help/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME.rst
index 2ad0689..57160f1 100644
--- a/Help/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME.rst
+++ b/Help/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME.rst
@@ -1,9 +1,9 @@
 CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
 ------------------------------------
 
-Default component used in install() commands.
+Default component used in :command:`install` commands.
 
-If an install() command is used without the COMPONENT argument, these
-files will be grouped into a default component.  The name of this
+If an :command:`install` command is used without the ``COMPONENT`` argument,
+these files will be grouped into a default component.  The name of this
 default install component will be taken from this variable.  It
-defaults to "Unspecified".
+defaults to ``Unspecified``.
diff --git a/Help/variable/CMAKE_INSTALL_NAME_DIR.rst b/Help/variable/CMAKE_INSTALL_NAME_DIR.rst
index 540df6b..961d712 100644
--- a/Help/variable/CMAKE_INSTALL_NAME_DIR.rst
+++ b/Help/variable/CMAKE_INSTALL_NAME_DIR.rst
@@ -3,6 +3,6 @@ CMAKE_INSTALL_NAME_DIR
 
 Mac OS X directory name for installed targets.
 
-CMAKE_INSTALL_NAME_DIR is used to initialize the INSTALL_NAME_DIR
-property on all targets.  See that target property for more
-information.
+``CMAKE_INSTALL_NAME_DIR`` is used to initialize the
+:prop_tgt:`INSTALL_NAME_DIR` property on all targets.  See that target
+property for more information.
diff --git a/Help/variable/CMAKE_INSTALL_PREFIX.rst b/Help/variable/CMAKE_INSTALL_PREFIX.rst
index ee9b615..3f3347f 100644
--- a/Help/variable/CMAKE_INSTALL_PREFIX.rst
+++ b/Help/variable/CMAKE_INSTALL_PREFIX.rst
@@ -1,14 +1,14 @@
 CMAKE_INSTALL_PREFIX
 --------------------
 
-Install directory used by install.
+Install directory used by :command:`install`.
 
-If "make install" is invoked or INSTALL is built, this directory is
+If ``make install`` is invoked or ``INSTALL`` is built, this directory is
 prepended onto all install directories.  This variable defaults to
-/usr/local on UNIX and c:/Program Files on Windows.
+``/usr/local`` on UNIX and ``c:/Program Files`` on Windows.
 
-On UNIX one can use the DESTDIR mechanism in order to relocate the
-whole installation.  DESTDIR means DESTination DIRectory.  It is
+On UNIX one can use the ``DESTDIR`` mechanism in order to relocate the
+whole installation.  ``DESTDIR`` means DESTination DIRectory.  It is
 commonly used by makefile users in order to install software at
 non-default location.  It is usually invoked like this:
 
@@ -17,16 +17,17 @@ non-default location.  It is usually invoked like this:
  make DESTDIR=/home/john install
 
 which will install the concerned software using the installation
-prefix, e.g.  "/usr/local" prepended with the DESTDIR value which
-finally gives "/home/john/usr/local".
+prefix, e.g.  ``/usr/local`` prepended with the ``DESTDIR`` value which
+finally gives ``/home/john/usr/local``.
 
-WARNING: DESTDIR may not be used on Windows because installation
-prefix usually contains a drive letter like in "C:/Program Files"
+WARNING: ``DESTDIR`` may not be used on Windows because installation
+prefix usually contains a drive letter like in ``C:/Program Files``
 which cannot be prepended with some other prefix.
 
-The installation prefix is also added to CMAKE_SYSTEM_PREFIX_PATH so
-that find_package, find_program, find_library, find_path, and
-find_file will search the prefix for other software.
+The installation prefix is also added to :variable:`CMAKE_SYSTEM_PREFIX_PATH`
+so that :command:`find_package`, :command:`find_program`,
+:command:`find_library`, :command:`find_path`, and :command:`find_file`
+will search the prefix for other software.
 
 .. note::
 
diff --git a/Help/variable/CMAKE_INSTALL_RPATH.rst b/Help/variable/CMAKE_INSTALL_RPATH.rst
index 0992d57..813d1e0 100644
--- a/Help/variable/CMAKE_INSTALL_RPATH.rst
+++ b/Help/variable/CMAKE_INSTALL_RPATH.rst
@@ -5,4 +5,4 @@ The rpath to use for installed targets.
 
 A semicolon-separated list specifying the rpath to use in installed
 targets (for platforms that support it).  This is used to initialize
-the target property INSTALL_RPATH for all targets.
+the target property :prop_tgt:`INSTALL_RPATH` for all targets.
diff --git a/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst b/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst
index 9277a3b..78148d5 100644
--- a/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst
+++ b/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst
@@ -3,7 +3,7 @@ CMAKE_INSTALL_RPATH_USE_LINK_PATH
 
 Add paths to linker search and installed rpath.
 
-CMAKE_INSTALL_RPATH_USE_LINK_PATH is a boolean that if set to true
+``CMAKE_INSTALL_RPATH_USE_LINK_PATH`` is a boolean that if set to ``true``
 will append directories in the linker search path and outside the
-project to the INSTALL_RPATH.  This is used to initialize the target
-property INSTALL_RPATH_USE_LINK_PATH for all targets.
+project to the :prop_tgt:`INSTALL_RPATH`.  This is used to initialize the
+target property :prop_tgt:`INSTALL_RPATH_USE_LINK_PATH` for all targets.
diff --git a/Help/variable/CMAKE_LANG_ARCHIVE_APPEND.rst b/Help/variable/CMAKE_LANG_ARCHIVE_APPEND.rst
index 2c3abae..ab4ad71 100644
--- a/Help/variable/CMAKE_LANG_ARCHIVE_APPEND.rst
+++ b/Help/variable/CMAKE_LANG_ARCHIVE_APPEND.rst
@@ -4,6 +4,7 @@ CMAKE_<LANG>_ARCHIVE_APPEND
 Rule variable to append to a static archive.
 
 This is a rule variable that tells CMake how to append to a static
-archive.  It is used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY on
-some platforms in order to support large object counts.  See also
-CMAKE_<LANG>_ARCHIVE_CREATE and CMAKE_<LANG>_ARCHIVE_FINISH.
+archive.  It is used in place of :variable:`CMAKE_<LANG>_CREATE_STATIC_LIBRARY`
+on some platforms in order to support large object counts.  See also
+:variable:`CMAKE_<LANG>_ARCHIVE_CREATE` and
+:variable:`CMAKE_<LANG>_ARCHIVE_FINISH`.
diff --git a/Help/variable/CMAKE_LANG_ARCHIVE_CREATE.rst b/Help/variable/CMAKE_LANG_ARCHIVE_CREATE.rst
index f93dd11..fc295af 100644
--- a/Help/variable/CMAKE_LANG_ARCHIVE_CREATE.rst
+++ b/Help/variable/CMAKE_LANG_ARCHIVE_CREATE.rst
@@ -4,6 +4,7 @@ CMAKE_<LANG>_ARCHIVE_CREATE
 Rule variable to create a new static archive.
 
 This is a rule variable that tells CMake how to create a static
-archive.  It is used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY on
-some platforms in order to support large object counts.  See also
-CMAKE_<LANG>_ARCHIVE_APPEND and CMAKE_<LANG>_ARCHIVE_FINISH.
+archive.  It is used in place of :variable:`CMAKE_<LANG>_CREATE_STATIC_LIBRARY`
+on some platforms in order to support large object counts.  See also
+:variable:`CMAKE_<LANG>_ARCHIVE_APPEND` and
+:variable:`CMAKE_<LANG>_ARCHIVE_FINISH`.
diff --git a/Help/variable/CMAKE_LANG_ARCHIVE_FINISH.rst b/Help/variable/CMAKE_LANG_ARCHIVE_FINISH.rst
index fff4128..1bb5d65 100644
--- a/Help/variable/CMAKE_LANG_ARCHIVE_FINISH.rst
+++ b/Help/variable/CMAKE_LANG_ARCHIVE_FINISH.rst
@@ -4,6 +4,7 @@ CMAKE_<LANG>_ARCHIVE_FINISH
 Rule variable to finish an existing static archive.
 
 This is a rule variable that tells CMake how to finish a static
-archive.  It is used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY on
-some platforms in order to support large object counts.  See also
-CMAKE_<LANG>_ARCHIVE_CREATE and CMAKE_<LANG>_ARCHIVE_APPEND.
+archive.  It is used in place of :variable:`CMAKE_<LANG>_CREATE_STATIC_LIBRARY`
+on some platforms in order to support large object counts.  See also
+:variable:`CMAKE_<LANG>_ARCHIVE_CREATE` and
+:variable:`CMAKE_<LANG>_ARCHIVE_APPEND`.
diff --git a/Help/variable/CMAKE_LANG_COMPILER.rst b/Help/variable/CMAKE_LANG_COMPILER.rst
index fffc347..89df495 100644
--- a/Help/variable/CMAKE_LANG_COMPILER.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_COMPILER
 ---------------------
 
-The full path to the compiler for LANG.
+The full path to the compiler for ``LANG``.
 
-This is the command that will be used as the <LANG> compiler.  Once
+This is the command that will be used as the ``<LANG>`` compiler.  Once
 set, you can not change this variable.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst b/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst
index 033998d..8bb7cc0 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst
@@ -5,9 +5,9 @@ The external toolchain for cross-compiling, if supported.
 
 Some compiler toolchains do not ship their own auxilliary utilities such as
 archivers and linkers.  The compiler driver may support a command-line argument
-to specify the location of such tools.  CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN
-may be set to a path to a path to the external toolchain and will be passed
-to the compiler driver if supported.
+to specify the location of such tools.
+``CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN`` may be set to a path to a path to
+the external toolchain and will be passed to the compiler driver if supported.
 
 This variable may only be set in a toolchain file specified by
 the :variable:`CMAKE_TOOLCHAIN_FILE` variable.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
index f554f4e..1c3b134 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_ID.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
@@ -11,6 +11,7 @@ include:
   Absoft = Absoft Fortran (absoft.com)
   ADSP = Analog VisualDSP++ (analog.com)
   AppleClang = Apple Clang (apple.com)
+  CCur = Concurrent Fortran (ccur.com)
   Clang = LLVM Clang (clang.llvm.org)
   Cray = Cray Compiler (cray.com)
   Embarcadero, Borland = Embarcadero (embarcadero.com)
diff --git a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
new file mode 100644
index 0000000..7961f60
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_COMPILER_LAUNCHER
+------------------------------
+
+Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property.
+This variable is used to initialize the property on each target as it is
+created.  This is done only when ``<LANG>`` is ``C`` or ``CXX``.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_LOADED.rst b/Help/variable/CMAKE_LANG_COMPILER_LOADED.rst
index 3b8e9aa..9308878 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_LOADED.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_LOADED.rst
@@ -3,5 +3,5 @@ CMAKE_<LANG>_COMPILER_LOADED
 
 Defined to true if the language is enabled.
 
-When language <LANG> is enabled by project() or enable_language() this
-variable is defined to 1.
+When language ``<LANG>`` is enabled by :command:`project` or
+:command:`enable_language` this variable is defined to ``1``.
diff --git a/Help/variable/CMAKE_LANG_COMPILE_OBJECT.rst b/Help/variable/CMAKE_LANG_COMPILE_OBJECT.rst
index f43ed6d..ba59cad 100644
--- a/Help/variable/CMAKE_LANG_COMPILE_OBJECT.rst
+++ b/Help/variable/CMAKE_LANG_COMPILE_OBJECT.rst
@@ -4,4 +4,4 @@ CMAKE_<LANG>_COMPILE_OBJECT
 Rule variable to compile a single object file.
 
 This is a rule variable that tells CMake how to compile a single
-object file for the language <LANG>.
+object file for the language ``<LANG>``.
diff --git a/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY.rst b/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY.rst
index adf1624..be89f85 100644
--- a/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY.rst
+++ b/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY.rst
@@ -4,4 +4,4 @@ CMAKE_<LANG>_CREATE_SHARED_LIBRARY
 Rule variable to create a shared library.
 
 This is a rule variable that tells CMake how to create a shared
-library for the language <LANG>.
+library for the language ``<LANG>``.
diff --git a/Help/variable/CMAKE_LANG_CREATE_SHARED_MODULE.rst b/Help/variable/CMAKE_LANG_CREATE_SHARED_MODULE.rst
index 406b4da..ae5f69d 100644
--- a/Help/variable/CMAKE_LANG_CREATE_SHARED_MODULE.rst
+++ b/Help/variable/CMAKE_LANG_CREATE_SHARED_MODULE.rst
@@ -4,4 +4,4 @@ CMAKE_<LANG>_CREATE_SHARED_MODULE
 Rule variable to create a shared module.
 
 This is a rule variable that tells CMake how to create a shared
-library for the language <LANG>.
+library for the language ``<LANG>``.
diff --git a/Help/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY.rst b/Help/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY.rst
index 8114432..0cff200 100644
--- a/Help/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY.rst
+++ b/Help/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY.rst
@@ -4,4 +4,4 @@ CMAKE_<LANG>_CREATE_STATIC_LIBRARY
 Rule variable to create a static library.
 
 This is a rule variable that tells CMake how to create a static
-library for the language <LANG>.
+library for the language ``<LANG>``.
diff --git a/Help/variable/CMAKE_LANG_FLAGS.rst b/Help/variable/CMAKE_LANG_FLAGS.rst
index 6aa0a3e..c57d92c 100644
--- a/Help/variable/CMAKE_LANG_FLAGS.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS.rst
@@ -3,4 +3,4 @@ CMAKE_<LANG>_FLAGS
 
 Flags for all build types.
 
-<LANG> flags used regardless of the value of CMAKE_BUILD_TYPE.
+``<LANG>`` flags used regardless of the value of :variable:`CMAKE_BUILD_TYPE`.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_DEBUG.rst b/Help/variable/CMAKE_LANG_FLAGS_DEBUG.rst
index a727641..a233d4a 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_DEBUG.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_DEBUG.rst
@@ -1,6 +1,6 @@
 CMAKE_<LANG>_FLAGS_DEBUG
 ------------------------
 
-Flags for Debug build type or configuration.
+Flags for ``Debug`` build type or configuration.
 
-<LANG> flags used when CMAKE_BUILD_TYPE is Debug.
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``Debug``.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL.rst b/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL.rst
index fbb8516..a9436c1 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_FLAGS_MINSIZEREL
 -----------------------------
 
-Flags for MinSizeRel build type or configuration.
+Flags for ``MinSizeRel`` build type or configuration.
 
-<LANG> flags used when CMAKE_BUILD_TYPE is MinSizeRel.Short for
-minimum size release.
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``MinSizeRel``
+(short for minimum size release).
diff --git a/Help/variable/CMAKE_LANG_FLAGS_RELEASE.rst b/Help/variable/CMAKE_LANG_FLAGS_RELEASE.rst
index 4b2c926..ffc5d79 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_RELEASE.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_RELEASE.rst
@@ -1,6 +1,6 @@
 CMAKE_<LANG>_FLAGS_RELEASE
 --------------------------
 
-Flags for Release build type or configuration.
+Flags for ``Release`` build type or configuration.
 
-<LANG> flags used when CMAKE_BUILD_TYPE is Release
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``Release``.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO.rst b/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO.rst
index 16bd4e9..962768e 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_FLAGS_RELWITHDEBINFO
 ---------------------------------
 
-Flags for RelWithDebInfo type or configuration.
+Flags for ``RelWithDebInfo`` type or configuration.
 
-<LANG> flags used when CMAKE_BUILD_TYPE is RelWithDebInfo.  Short for
-Release With Debug Information.
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``RelWithDebInfo``
+(short for Release With Debug Information).
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst
index c5915c3..1f639a3 100644
--- a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst
@@ -1,6 +1,6 @@
 CMAKE_<LANG>_GHS_KERNEL_FLAGS_DEBUG
 -----------------------------------
 
-GHS kernel flags for Debug build type or configuration.
+GHS kernel flags for ``Debug`` build type or configuration.
 
-<LANG> flags used when CMAKE_BUILD_TYPE is Debug.
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``Debug``.
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst
index f80e785..94e2115 100644
--- a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_GHS_KERNEL_FLAGS_MINSIZEREL
 ----------------------------------------
 
-GHS kernel flags for MinSizeRel build type or configuration.
+GHS kernel flags for ``MinSizeRel`` build type or configuration.
 
-<LANG> flags used when CMAKE_BUILD_TYPE is MinSizeRel.Short for
-minimum size release.
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``MinSizeRel``
+(short for minimum size release).
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst
index fe02bc3..74566ef 100644
--- a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst
@@ -1,6 +1,6 @@
 CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELEASE
 -------------------------------------
 
-GHS kernel flags for Release build type or configuration.
+GHS kernel flags for ``Release`` build type or configuration.
 
-<LANG> flags used when CMAKE_BUILD_TYPE is Release
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``Release``.
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst
index 220f7f9..d148193 100644
--- a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELWITHDEBINFO
 --------------------------------------------
 
-GHS kernel flags for RelWithDebInfo type or configuration.
+GHS kernel flags for ``RelWithDebInfo`` type or configuration.
 
-<LANG> flags used when CMAKE_BUILD_TYPE is RelWithDebInfo.  Short for
-Release With Debug Information.
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``RelWithDebInfo``
+(short for Release With Debug Information).
diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst
index c60e18c..cc80851 100644
--- a/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst
@@ -4,6 +4,6 @@ CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES
 Directories implicitly searched by the compiler for header files.
 
 CMake does not explicitly specify these directories on compiler
-command lines for language <LANG>.  This prevents system include
+command lines for language ``<LANG>``.  This prevents system include
 directories from being treated as user include directories on some
 compilers.
diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst
index 568950c..a0bd830 100644
--- a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES
 --------------------------------------
 
-Implicit linker search path detected for language <LANG>.
+Implicit linker search path detected for language ``<LANG>``.
 
 Compilers typically pass directories containing language runtime
 libraries and default library search paths when they invoke a linker.
@@ -10,8 +10,8 @@ language.  CMake automatically detects these directories for each
 language and reports the results in this variable.
 
 When a library in one of these directories is given by full path to
-target_link_libraries() CMake will generate the -l<name> form on link
-lines to ensure the linker searches its implicit directories for the
+:command:`target_link_libraries` CMake will generate the ``-l<name>`` form on
+link lines to ensure the linker searches its implicit directories for the
 library.  Note that some toolchains read implicit directories from an
-environment variable such as LIBRARY_PATH so keep its value consistent
+environment variable such as ``LIBRARY_PATH`` so keep its value consistent
 when operating in a given build tree.
diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES.rst
index 05e6ddb..61ccc5a 100644
--- a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
 ------------------------------------------------
 
-Implicit linker framework search path detected for language <LANG>.
+Implicit linker framework search path detected for language ``<LANG>``.
 
 These paths are implicit linker framework search directories for the
 compiler's language.  CMake automatically detects these directories
diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES.rst
index fddfed8..ec16477 100644
--- a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES.rst
+++ b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES
 ------------------------------------
 
-Implicit link libraries and flags detected for language <LANG>.
+Implicit link libraries and flags detected for language ``<LANG>``.
 
 Compilers typically pass language runtime library names and other
 flags when they invoke a linker.  These flags are implicit link
diff --git a/Help/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE.rst b/Help/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE.rst
index 4f31494..7f888ee 100644
--- a/Help/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE.rst
+++ b/Help/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE.rst
@@ -1,8 +1,8 @@
 CMAKE_<LANG>_LIBRARY_ARCHITECTURE
 ---------------------------------
 
-Target architecture library directory name detected for <lang>.
+Target architecture library directory name detected for ``<LANG>``.
 
-If the <lang> compiler passes to the linker an architecture-specific
-system library search directory such as <prefix>/lib/<arch> this
-variable contains the <arch> name if/as detected by CMake.
+If the ``<LANG>`` compiler passes to the linker an architecture-specific
+system library search directory such as ``<prefix>/lib/<arch>`` this
+variable contains the ``<arch>`` name if/as detected by CMake.
diff --git a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst
index af7ee60..ff82f8b 100644
--- a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst
+++ b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst
@@ -5,7 +5,7 @@ Preference value for linker language selection.
 
 The "linker language" for executable, shared library, and module
 targets is the language whose compiler will invoke the linker.  The
-LINKER_LANGUAGE target property sets the language explicitly.
+:prop_tgt:`LINKER_LANGUAGE` target property sets the language explicitly.
 Otherwise, the linker language is that whose linker preference value
 is highest among languages compiled and linked into the target.  See
-also the CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES variable.
+also the :variable:`CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES` variable.
diff --git a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst
index d513767..dbbeb0a 100644
--- a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst
+++ b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES
 -----------------------------------------
 
-True if CMAKE_<LANG>_LINKER_PREFERENCE propagates across targets.
+True if :variable:`CMAKE_<LANG>_LINKER_PREFERENCE` propagates across targets.
 
 This is used when CMake selects a linker language for a target.
 Languages compiled directly into the target are always considered.  A
diff --git a/Help/variable/CMAKE_LANG_OUTPUT_EXTENSION.rst b/Help/variable/CMAKE_LANG_OUTPUT_EXTENSION.rst
index 22fac29..0fbc566 100644
--- a/Help/variable/CMAKE_LANG_OUTPUT_EXTENSION.rst
+++ b/Help/variable/CMAKE_LANG_OUTPUT_EXTENSION.rst
@@ -3,5 +3,5 @@ CMAKE_<LANG>_OUTPUT_EXTENSION
 
 Extension for the output of a compile for a single file.
 
-This is the extension for an object file for the given <LANG>.  For
-example .obj for C on Windows.
+This is the extension for an object file for the given ``<LANG>``.  For
+example ``.obj`` for C on Windows.
diff --git a/Help/variable/CMAKE_LANG_SIMULATE_ID.rst b/Help/variable/CMAKE_LANG_SIMULATE_ID.rst
index 646c0db..15c87a1 100644
--- a/Help/variable/CMAKE_LANG_SIMULATE_ID.rst
+++ b/Help/variable/CMAKE_LANG_SIMULATE_ID.rst
@@ -5,5 +5,5 @@ Identification string of "simulated" compiler.
 
 Some compilers simulate other compilers to serve as drop-in
 replacements.  When CMake detects such a compiler it sets this
-variable to what would have been the CMAKE_<LANG>_COMPILER_ID for the
-simulated compiler.
+variable to what would have been the :variable:`CMAKE_<LANG>_COMPILER_ID` for
+the simulated compiler.
diff --git a/Help/variable/CMAKE_LANG_SIMULATE_VERSION.rst b/Help/variable/CMAKE_LANG_SIMULATE_VERSION.rst
index 982053d..d6325e0 100644
--- a/Help/variable/CMAKE_LANG_SIMULATE_VERSION.rst
+++ b/Help/variable/CMAKE_LANG_SIMULATE_VERSION.rst
@@ -5,5 +5,5 @@ Version string of "simulated" compiler.
 
 Some compilers simulate other compilers to serve as drop-in
 replacements.  When CMake detects such a compiler it sets this
-variable to what would have been the CMAKE_<LANG>_COMPILER_VERSION for
-the simulated compiler.
+variable to what would have been the :variable:`CMAKE_<LANG>_COMPILER_VERSION`
+for the simulated compiler.
diff --git a/Help/variable/CMAKE_LANG_SIZEOF_DATA_PTR.rst b/Help/variable/CMAKE_LANG_SIZEOF_DATA_PTR.rst
index c85b5e0..7465923 100644
--- a/Help/variable/CMAKE_LANG_SIZEOF_DATA_PTR.rst
+++ b/Help/variable/CMAKE_LANG_SIZEOF_DATA_PTR.rst
@@ -1,7 +1,7 @@
 CMAKE_<LANG>_SIZEOF_DATA_PTR
 ----------------------------
 
-Size of pointer-to-data types for language <LANG>.
+Size of pointer-to-data types for language ``<LANG>``.
 
 This holds the size (in bytes) of pointer-to-data types in the target
-platform ABI.  It is defined for languages C and CXX (C++).
+platform ABI.  It is defined for languages ``C`` and ``CXX`` (C++).
diff --git a/Help/variable/CMAKE_LIBRARY_ARCHITECTURE.rst b/Help/variable/CMAKE_LIBRARY_ARCHITECTURE.rst
index c9a15f3..8a7dcbd 100644
--- a/Help/variable/CMAKE_LIBRARY_ARCHITECTURE.rst
+++ b/Help/variable/CMAKE_LIBRARY_ARCHITECTURE.rst
@@ -3,5 +3,5 @@ CMAKE_LIBRARY_ARCHITECTURE
 
 Target architecture library directory name, if detected.
 
-This is the value of CMAKE_<lang>_LIBRARY_ARCHITECTURE as detected for
-one of the enabled languages.
+This is the value of :variable:`CMAKE_<LANG>_LIBRARY_ARCHITECTURE` as detected
+for one of the enabled languages.
diff --git a/Help/variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX.rst b/Help/variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX.rst
index 6c41269..1eb2ac2 100644
--- a/Help/variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX.rst
+++ b/Help/variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX.rst
@@ -3,5 +3,5 @@ CMAKE_LIBRARY_ARCHITECTURE_REGEX
 
 Regex matching possible target architecture library directory names.
 
-This is used to detect CMAKE_<lang>_LIBRARY_ARCHITECTURE from the
-implicit linker search path by matching the <arch> name.
+This is used to detect :variable:`CMAKE_<LANG>_LIBRARY_ARCHITECTURE` from the
+implicit linker search path by matching the ``<arch>`` name.
diff --git a/Help/variable/CMAKE_LIBRARY_PATH_FLAG.rst b/Help/variable/CMAKE_LIBRARY_PATH_FLAG.rst
index ede39e9..ebe5fda 100644
--- a/Help/variable/CMAKE_LIBRARY_PATH_FLAG.rst
+++ b/Help/variable/CMAKE_LIBRARY_PATH_FLAG.rst
@@ -4,4 +4,4 @@ CMAKE_LIBRARY_PATH_FLAG
 The flag to be used to add a library search path to a compiler.
 
 The flag will be used to specify a library directory to the compiler.
-On most compilers this is "-L".
+On most compilers this is ``-L``.
diff --git a/Help/variable/CMAKE_LINK_DEF_FILE_FLAG.rst b/Help/variable/CMAKE_LINK_DEF_FILE_FLAG.rst
index 382447c..fa09f9f 100644
--- a/Help/variable/CMAKE_LINK_DEF_FILE_FLAG.rst
+++ b/Help/variable/CMAKE_LINK_DEF_FILE_FLAG.rst
@@ -1,7 +1,7 @@
 CMAKE_LINK_DEF_FILE_FLAG
 ------------------------
 
-Linker flag to be used to specify a .def file for dll creation.
+Linker flag to be used to specify a ``.def`` file for dll creation.
 
-The flag will be used to add a .def file when creating a dll on
+The flag will be used to add a ``.def`` file when creating a dll on
 Windows; this is only defined on Windows.
diff --git a/Help/variable/CMAKE_LINK_DEPENDS_NO_SHARED.rst b/Help/variable/CMAKE_LINK_DEPENDS_NO_SHARED.rst
index 6ae7df6..cec7906 100644
--- a/Help/variable/CMAKE_LINK_DEPENDS_NO_SHARED.rst
+++ b/Help/variable/CMAKE_LINK_DEPENDS_NO_SHARED.rst
@@ -3,6 +3,6 @@ CMAKE_LINK_DEPENDS_NO_SHARED
 
 Whether to skip link dependencies on shared library files.
 
-This variable initializes the LINK_DEPENDS_NO_SHARED property on
+This variable initializes the :prop_tgt:`LINK_DEPENDS_NO_SHARED` property on
 targets when they are created.  See that target property for
 additional information.
diff --git a/Help/variable/CMAKE_LINK_INTERFACE_LIBRARIES.rst b/Help/variable/CMAKE_LINK_INTERFACE_LIBRARIES.rst
index efe6fd7..33865da 100644
--- a/Help/variable/CMAKE_LINK_INTERFACE_LIBRARIES.rst
+++ b/Help/variable/CMAKE_LINK_INTERFACE_LIBRARIES.rst
@@ -1,8 +1,8 @@
 CMAKE_LINK_INTERFACE_LIBRARIES
 ------------------------------
 
-Default value for LINK_INTERFACE_LIBRARIES of targets.
+Default value for :prop_tgt:`LINK_INTERFACE_LIBRARIES` of targets.
 
-This variable is used to initialize the LINK_INTERFACE_LIBRARIES
+This variable is used to initialize the :prop_tgt:`LINK_INTERFACE_LIBRARIES`
 property on all the targets.  See that target property for additional
 information.
diff --git a/Help/variable/CMAKE_LINK_LIBRARY_FLAG.rst b/Help/variable/CMAKE_LINK_LIBRARY_FLAG.rst
index c3e02d7..b5197e4 100644
--- a/Help/variable/CMAKE_LINK_LIBRARY_FLAG.rst
+++ b/Help/variable/CMAKE_LINK_LIBRARY_FLAG.rst
@@ -4,4 +4,4 @@ CMAKE_LINK_LIBRARY_FLAG
 Flag to be used to link a library into an executable.
 
 The flag will be used to specify a library to link to an executable.
-On most compilers this is "-l".
+On most compilers this is ``-l``.
diff --git a/Help/variable/CMAKE_LINK_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_LINK_LIBRARY_SUFFIX.rst
index 390298d..0ddafe8 100644
--- a/Help/variable/CMAKE_LINK_LIBRARY_SUFFIX.rst
+++ b/Help/variable/CMAKE_LINK_LIBRARY_SUFFIX.rst
@@ -3,4 +3,4 @@ CMAKE_LINK_LIBRARY_SUFFIX
 
 The suffix for libraries that you link to.
 
-The suffix to use for the end of a library filename, .lib on Windows.
+The suffix to use for the end of a library filename, ``.lib`` on Windows.
diff --git a/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst b/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
new file mode 100644
index 0000000..54cdaaa
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
@@ -0,0 +1,19 @@
+CMAKE_LINK_SEARCH_END_STATIC
+----------------------------
+
+End a link line such that static system libraries are used.
+
+Some linkers support switches such as ``-Bstatic`` and ``-Bdynamic`` to
+determine whether to use static or shared libraries for ``-lXXX`` options.
+CMake uses these options to set the link type for libraries whose full
+paths are not known or (in some cases) are in implicit link
+directories for the platform.  By default CMake adds an option at the
+end of the library list (if necessary) to set the linker search type
+back to its starting type.  This property switches the final linker
+search type to ``-Bstatic`` regardless of how it started.
+
+This variable is used to initialize the target property
+:prop_tgt:`LINK_SEARCH_END_STATIC` for all targets. If set, it's
+value is also used by the :command:`try_compile` command.
+
+See also :variable:`CMAKE_LINK_SEARCH_START_STATIC`.
diff --git a/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst b/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
new file mode 100644
index 0000000..0d52a31
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
@@ -0,0 +1,20 @@
+CMAKE_LINK_SEARCH_START_STATIC
+------------------------------
+
+Assume the linker looks for static libraries by default.
+
+Some linkers support switches such as ``-Bstatic`` and ``-Bdynamic`` to
+determine whether to use static or shared libraries for ``-lXXX`` options.
+CMake uses these options to set the link type for libraries whose full
+paths are not known or (in some cases) are in implicit link
+directories for the platform.  By default the linker search type is
+assumed to be ``-Bdynamic`` at the beginning of the library list.  This
+property switches the assumption to ``-Bstatic``.  It is intended for use
+when linking an executable statically (e.g.  with the GNU ``-static``
+option).
+
+This variable is used to initialize the target property
+:prop_tgt:`LINK_SEARCH_START_STATIC` for all targets.  If set, it's
+value is also used by the :command:`try_compile` command.
+
+See also :variable:`CMAKE_LINK_SEARCH_END_STATIC`.
diff --git a/Help/variable/CMAKE_MACOSX_BUNDLE.rst b/Help/variable/CMAKE_MACOSX_BUNDLE.rst
index e4768f3..0badaf0 100644
--- a/Help/variable/CMAKE_MACOSX_BUNDLE.rst
+++ b/Help/variable/CMAKE_MACOSX_BUNDLE.rst
@@ -1,7 +1,7 @@
 CMAKE_MACOSX_BUNDLE
 -------------------
 
-Default value for MACOSX_BUNDLE of targets.
+Default value for :prop_tgt:`MACOSX_BUNDLE` of targets.
 
-This variable is used to initialize the MACOSX_BUNDLE property on all
-the targets.  See that target property for additional information.
+This variable is used to initialize the :prop_tgt:`MACOSX_BUNDLE` property on
+all the targets.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_MAKE_PROGRAM.rst b/Help/variable/CMAKE_MAKE_PROGRAM.rst
index 85b098b..edf2732 100644
--- a/Help/variable/CMAKE_MAKE_PROGRAM.rst
+++ b/Help/variable/CMAKE_MAKE_PROGRAM.rst
@@ -8,18 +8,18 @@ name if it is expected to be in the ``PATH``.
 The tool selected depends on the :variable:`CMAKE_GENERATOR` used
 to configure the project:
 
-* The Makefile generators set this to ``make``, ``gmake``, or
-  a generator-specific tool (e.g. ``nmake`` for "NMake Makefiles").
+* The :ref:`Makefile Generators` set this to ``make``, ``gmake``, or
+  a generator-specific tool (e.g. ``nmake`` for :generator:`NMake Makefiles`).
 
   These generators store ``CMAKE_MAKE_PROGRAM`` in the CMake cache
   so that it may be edited by the user.
 
-* The Ninja generator sets this to ``ninja``.
+* The :generator:`Ninja` generator sets this to ``ninja``.
 
   This generator stores ``CMAKE_MAKE_PROGRAM`` in the CMake cache
   so that it may be edited by the user.
 
-* The Xcode generator sets this to ``xcodebuild`` (or possibly an
+* The :generator:`Xcode` generator sets this to ``xcodebuild`` (or possibly an
   otherwise undocumented ``cmakexbuild`` wrapper implementing some
   workarounds).
 
@@ -33,7 +33,7 @@ to configure the project:
   a user or project explicitly adds ``CMAKE_MAKE_PROGRAM`` to
   the CMake cache then CMake will use the specified value.
 
-* The Visual Studio generators set this to the full path to
+* The :ref:`Visual Studio Generators` set this to the full path to
   ``MSBuild.exe`` (VS >= 10), ``devenv.com`` (VS 7,8,9),
   ``VCExpress.exe`` (VS Express 8,9), or ``msdev.exe`` (VS 6).
   (See also variables
diff --git a/Help/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG.rst b/Help/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG.rst
index 41ccde1..ed29afe 100644
--- a/Help/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG.rst
+++ b/Help/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG.rst
@@ -1,8 +1,8 @@
 CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>
 ----------------------------------
 
-Default value for MAP_IMPORTED_CONFIG_<CONFIG> of targets.
+Default value for :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` of targets.
 
-This variable is used to initialize the MAP_IMPORTED_CONFIG_<CONFIG>
-property on all the targets.  See that target property for additional
-information.
+This variable is used to initialize the
+:prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` property on all the targets.  See
+that target property for additional information.
diff --git a/Help/variable/CMAKE_MFC_FLAG.rst b/Help/variable/CMAKE_MFC_FLAG.rst
index 221d26e..f60e7a5 100644
--- a/Help/variable/CMAKE_MFC_FLAG.rst
+++ b/Help/variable/CMAKE_MFC_FLAG.rst
@@ -3,10 +3,10 @@ CMAKE_MFC_FLAG
 
 Tell cmake to use MFC for an executable or dll.
 
-This can be set in a CMakeLists.txt file and will enable MFC in the
-application.  It should be set to 1 for the static MFC library, and 2
+This can be set in a ``CMakeLists.txt`` file and will enable MFC in the
+application.  It should be set to ``1`` for the static MFC library, and ``2``
 for the shared MFC library.  This is used in Visual Studio 6 and 7
-project files.  The CMakeSetup dialog used MFC and the CMakeLists.txt
+project files.  The CMakeSetup dialog used MFC and the ``CMakeLists.txt``
 looks like this:
 
 ::
diff --git a/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst b/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst
index 351de44..5a51634 100644
--- a/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst
+++ b/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst
@@ -1,7 +1,7 @@
 CMAKE_MINIMUM_REQUIRED_VERSION
 ------------------------------
 
-Version specified to cmake_minimum_required command
+Version specified to :command:`cmake_minimum_required` command
 
-Variable containing the VERSION component specified in the
-cmake_minimum_required command.
+Variable containing the ``VERSION`` component specified in the
+:command:`cmake_minimum_required` command.
diff --git a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst
index 87a1901..393263e 100644
--- a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst
+++ b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst
@@ -3,4 +3,4 @@ CMAKE_MODULE_LINKER_FLAGS_<CONFIG>
 
 Flags to be used when linking a module.
 
-Same as CMAKE_C_FLAGS_* but used by the linker when creating modules.
+Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating modules.
diff --git a/Help/variable/CMAKE_NOT_USING_CONFIG_FLAGS.rst b/Help/variable/CMAKE_NOT_USING_CONFIG_FLAGS.rst
index cbe0350..98960c5 100644
--- a/Help/variable/CMAKE_NOT_USING_CONFIG_FLAGS.rst
+++ b/Help/variable/CMAKE_NOT_USING_CONFIG_FLAGS.rst
@@ -1,7 +1,7 @@
 CMAKE_NOT_USING_CONFIG_FLAGS
 ----------------------------
 
-Skip _BUILD_TYPE flags if true.
+Skip ``_BUILD_TYPE`` flags if true.
 
 This is an internal flag used by the generators in CMake to tell CMake
-to skip the _BUILD_TYPE flags.
+to skip the ``_BUILD_TYPE`` flags.
diff --git a/Help/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED.rst b/Help/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED.rst
index c1919af..61e04b4 100644
--- a/Help/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED.rst
+++ b/Help/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED.rst
@@ -1,8 +1,8 @@
 CMAKE_NO_SYSTEM_FROM_IMPORTED
 -----------------------------
 
-Default value for NO_SYSTEM_FROM_IMPORTED of targets.
+Default value for :prop_tgt:`NO_SYSTEM_FROM_IMPORTED` of targets.
 
-This variable is used to initialize the NO_SYSTEM_FROM_IMPORTED
+This variable is used to initialize the :prop_tgt:`NO_SYSTEM_FROM_IMPORTED`
 property on all the targets.  See that target property for additional
 information.
diff --git a/Help/variable/CMAKE_PARENT_LIST_FILE.rst b/Help/variable/CMAKE_PARENT_LIST_FILE.rst
index 5566a72..cfd8608 100644
--- a/Help/variable/CMAKE_PARENT_LIST_FILE.rst
+++ b/Help/variable/CMAKE_PARENT_LIST_FILE.rst
@@ -3,7 +3,7 @@ CMAKE_PARENT_LIST_FILE
 
 Full path to the CMake file that included the current one.
 
-While processing a CMake file loaded by include() or find_package()
-this variable contains the full path to the file including it.  The
-top of the include stack is always the CMakeLists.txt for the current
-directory.  See also CMAKE_CURRENT_LIST_FILE.
+While processing a CMake file loaded by :command:`include` or
+:command:`find_package` this variable contains the full path to the file
+including it.  The top of the include stack is always the ``CMakeLists.txt``
+for the current directory.  See also :variable:`CMAKE_CURRENT_LIST_FILE`.
diff --git a/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst
index e401aa5..43582be 100644
--- a/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst
@@ -1,16 +1,17 @@
 CMAKE_POLICY_DEFAULT_CMP<NNNN>
 ------------------------------
 
-Default for CMake Policy CMP<NNNN> when it is otherwise left unset.
+Default for CMake Policy ``CMP<NNNN>`` when it is otherwise left unset.
 
-Commands cmake_minimum_required(VERSION) and cmake_policy(VERSION) by
-default leave policies introduced after the given version unset.  Set
-CMAKE_POLICY_DEFAULT_CMP<NNNN> to OLD or NEW to specify the default
-for policy CMP<NNNN>, where <NNNN> is the policy number.
+Commands :command:`cmake_minimum_required(VERSION)` and
+:command:`cmake_policy(VERSION)` by default leave policies introduced after
+the given version unset.  Set ``CMAKE_POLICY_DEFAULT_CMP<NNNN>`` to ``OLD``
+or ``NEW`` to specify the default for policy ``CMP<NNNN>``, where ``<NNNN>``
+is the policy number.
 
 This variable should not be set by a project in CMake code; use
-cmake_policy(SET) instead.  Users running CMake may set this variable
-in the cache (e.g.  -DCMAKE_POLICY_DEFAULT_CMP<NNNN>=<OLD|NEW>) to set
-a policy not otherwise set by the project.  Set to OLD to quiet a
-policy warning while using old behavior or to NEW to try building the
+:command:`cmake_policy(SET)` instead.  Users running CMake may set this
+variable in the cache (e.g. ``-DCMAKE_POLICY_DEFAULT_CMP<NNNN>=<OLD|NEW>``)
+to set a policy not otherwise set by the project.  Set to ``OLD`` to quiet a
+policy warning while using old behavior or to ``NEW`` to try building the
 project with new behavior.
diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
index 092fe3e..582f9e4 100644
--- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
@@ -13,9 +13,11 @@ warn by default:
   policy :policy:`CMP0056`.
 * ``CMAKE_POLICY_WARNING_CMP0060`` controls the warning for
   policy :policy:`CMP0060`.
+* ``CMAKE_POLICY_WARNING_CMP0065`` controls the warning for
+  policy :policy:`CMP0065`.
 
 This variable should not be set by a project in CMake code.  Project
 developers running CMake may set this variable in their cache to
 enable the warning (e.g. ``-DCMAKE_POLICY_WARNING_CMP<NNNN>=ON``).
-Alternatively, running :manual:`cmake(1)` with the ``--debug-output``
-or ``--trace`` option will also enable the warning.
+Alternatively, running :manual:`cmake(1)` with the ``--debug-output``,
+``--trace``, or ``--trace-expand`` option will also enable the warning.
diff --git a/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst b/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst
index 5e71665..43b1397 100644
--- a/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst
+++ b/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst
@@ -1,8 +1,9 @@
 CMAKE_POSITION_INDEPENDENT_CODE
 -------------------------------
 
-Default value for POSITION_INDEPENDENT_CODE of targets.
+Default value for :prop_tgt:`POSITION_INDEPENDENT_CODE` of targets.
 
-This variable is used to initialize the POSITION_INDEPENDENT_CODE
-property on all the targets.  See that target property for additional
-information.
+This variable is used to initialize the
+:prop_tgt:`POSITION_INDEPENDENT_CODE` property on all the targets.
+See that target property for additional information.  If set, it's
+value is also used by the :command:`try_compile` command.
diff --git a/Help/variable/CMAKE_PROJECT_NAME.rst b/Help/variable/CMAKE_PROJECT_NAME.rst
index 4734705..431e9f3 100644
--- a/Help/variable/CMAKE_PROJECT_NAME.rst
+++ b/Help/variable/CMAKE_PROJECT_NAME.rst
@@ -4,4 +4,4 @@ CMAKE_PROJECT_NAME
 The name of the current project.
 
 This specifies name of the current project from the closest inherited
-PROJECT command.
+:command:`project` command.
diff --git a/Help/variable/CMAKE_ROOT.rst b/Help/variable/CMAKE_ROOT.rst
index f963a7f..1d0a8af 100644
--- a/Help/variable/CMAKE_ROOT.rst
+++ b/Help/variable/CMAKE_ROOT.rst
@@ -3,6 +3,6 @@ CMAKE_ROOT
 
 Install directory for running cmake.
 
-This is the install root for the running CMake and the Modules
+This is the install root for the running CMake and the ``Modules``
 directory can be found here.  This is commonly used in this format:
-${CMAKE_ROOT}/Modules
+``${CMAKE_ROOT}/Modules``
diff --git a/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst b/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst
index ad73cc0..981af60 100644
--- a/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst
+++ b/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst
@@ -1,8 +1,9 @@
 CMAKE_SCRIPT_MODE_FILE
 ----------------------
 
-Full path to the -P script file currently being processed.
+Full path to the :manual:`cmake(1)` ``-P`` script file currently being
+processed.
 
-When run in -P script mode, CMake sets this variable to the full path
-of the script file.  When run to configure a CMakeLists.txt file, this
-variable is not set.
+When run in :manual:`cmake(1)` ``-P`` script mode, CMake sets this variable to
+the full path of the script file.  When run to configure a ``CMakeLists.txt``
+file, this variable is not set.
diff --git a/Help/variable/CMAKE_SHARED_LIBRARY_PREFIX.rst b/Help/variable/CMAKE_SHARED_LIBRARY_PREFIX.rst
index a863e2a..8afabaf 100644
--- a/Help/variable/CMAKE_SHARED_LIBRARY_PREFIX.rst
+++ b/Help/variable/CMAKE_SHARED_LIBRARY_PREFIX.rst
@@ -3,6 +3,6 @@ CMAKE_SHARED_LIBRARY_PREFIX
 
 The prefix for shared libraries that you link to.
 
-The prefix to use for the name of a shared library, lib on UNIX.
+The prefix to use for the name of a shared library, ``lib`` on UNIX.
 
-CMAKE_SHARED_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>.
+``CMAKE_SHARED_LIBRARY_PREFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_SHARED_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_SHARED_LIBRARY_SUFFIX.rst
index c296ecd..1f96a32 100644
--- a/Help/variable/CMAKE_SHARED_LIBRARY_SUFFIX.rst
+++ b/Help/variable/CMAKE_SHARED_LIBRARY_SUFFIX.rst
@@ -3,7 +3,7 @@ CMAKE_SHARED_LIBRARY_SUFFIX
 
 The suffix for shared libraries that you link to.
 
-The suffix to use for the end of a shared library filename, .dll on
+The suffix to use for the end of a shared library filename, ``.dll`` on
 Windows.
 
-CMAKE_SHARED_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>.
+``CMAKE_SHARED_LIBRARY_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst
index fedc626..4bf87a0 100644
--- a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst
+++ b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst
@@ -3,5 +3,5 @@ CMAKE_SHARED_LINKER_FLAGS_<CONFIG>
 
 Flags to be used when linking a shared library.
 
-Same as CMAKE_C_FLAGS_* but used by the linker when creating shared
+Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating shared
 libraries.
diff --git a/Help/variable/CMAKE_SHARED_MODULE_PREFIX.rst b/Help/variable/CMAKE_SHARED_MODULE_PREFIX.rst
index a5a2428..d6eef98 100644
--- a/Help/variable/CMAKE_SHARED_MODULE_PREFIX.rst
+++ b/Help/variable/CMAKE_SHARED_MODULE_PREFIX.rst
@@ -5,4 +5,4 @@ The prefix for loadable modules that you link to.
 
 The prefix to use for the name of a loadable module on this platform.
 
-CMAKE_SHARED_MODULE_PREFIX_<LANG> overrides this for language <LANG>.
+``CMAKE_SHARED_MODULE_PREFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_SHARED_MODULE_SUFFIX.rst b/Help/variable/CMAKE_SHARED_MODULE_SUFFIX.rst
index 32a3c34..81515c3 100644
--- a/Help/variable/CMAKE_SHARED_MODULE_SUFFIX.rst
+++ b/Help/variable/CMAKE_SHARED_MODULE_SUFFIX.rst
@@ -6,4 +6,4 @@ The suffix for shared libraries that you link to.
 The suffix to use for the end of a loadable module filename on this
 platform
 
-CMAKE_SHARED_MODULE_SUFFIX_<LANG> overrides this for language <LANG>.
+``CMAKE_SHARED_MODULE_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_SIZEOF_VOID_P.rst b/Help/variable/CMAKE_SIZEOF_VOID_P.rst
index 98dbed6..f5464d1 100644
--- a/Help/variable/CMAKE_SIZEOF_VOID_P.rst
+++ b/Help/variable/CMAKE_SIZEOF_VOID_P.rst
@@ -1,8 +1,8 @@
 CMAKE_SIZEOF_VOID_P
 -------------------
 
-Size of a void pointer.
+Size of a ``void`` pointer.
 
 This is set to the size of a pointer on the target machine, and is determined
-by a try compile.  If a 64 bit size is found, then the library search
-path is modified to look for 64 bit libraries first.
+by a try compile.  If a 64-bit size is found, then the library search
+path is modified to look for 64-bit libraries first.
diff --git a/Help/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.rst b/Help/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.rst
index 33ee8a8..80a68c9 100644
--- a/Help/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.rst
+++ b/Help/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.rst
@@ -1,11 +1,11 @@
 CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
 ---------------------------------
 
-Don't make the install target depend on the all target.
+Don't make the ``install`` target depend on the ``all`` target.
 
-By default, the "install" target depends on the "all" target.  This
-has the effect, that when "make install" is invoked or INSTALL is
-built, first the "all" target is built, then the installation starts.
-If CMAKE_SKIP_INSTALL_ALL_DEPENDENCY is set to TRUE, this dependency
-is not created, so the installation process will start immediately,
+By default, the ``install`` target depends on the ``all`` target.  This
+has the effect, that when ``make install`` is invoked or ``INSTALL`` is
+built, first the ``all`` target is built, then the installation starts.
+If :variable:`CMAKE_SKIP_INSTALL_ALL_DEPENDENCY` is set to ``TRUE``, this
+dependency is not created, so the installation process will start immediately,
 independent from whether the project has been completely built or not.
diff --git a/Help/variable/CMAKE_SKIP_INSTALL_RPATH.rst b/Help/variable/CMAKE_SKIP_INSTALL_RPATH.rst
index f16b212..cc0ac21 100644
--- a/Help/variable/CMAKE_SKIP_INSTALL_RPATH.rst
+++ b/Help/variable/CMAKE_SKIP_INSTALL_RPATH.rst
@@ -11,4 +11,4 @@ always installed without RPATH, even if RPATH is enabled when
 building.  This can be useful for example to allow running tests from
 the build directory with RPATH enabled before the installation step.
 To omit RPATH in both the build and install steps, use
-CMAKE_SKIP_RPATH instead.
+:variable:`CMAKE_SKIP_RPATH` instead.
diff --git a/Help/variable/CMAKE_SKIP_INSTALL_RULES.rst b/Help/variable/CMAKE_SKIP_INSTALL_RULES.rst
index 5eda254..44966f3 100644
--- a/Help/variable/CMAKE_SKIP_INSTALL_RULES.rst
+++ b/Help/variable/CMAKE_SKIP_INSTALL_RULES.rst
@@ -3,5 +3,6 @@ CMAKE_SKIP_INSTALL_RULES
 
 Whether to disable generation of installation rules.
 
-If TRUE, cmake will neither generate installaton rules nor
-will it generate cmake_install.cmake files. This variable is FALSE by default.
+If ``TRUE``, cmake will neither generate installaton rules nor
+will it generate ``cmake_install.cmake`` files. This variable is ``FALSE`` by
+default.
diff --git a/Help/variable/CMAKE_SKIP_RPATH.rst b/Help/variable/CMAKE_SKIP_RPATH.rst
index c93f67f..d7ce8e4 100644
--- a/Help/variable/CMAKE_SKIP_RPATH.rst
+++ b/Help/variable/CMAKE_SKIP_RPATH.rst
@@ -3,8 +3,8 @@ CMAKE_SKIP_RPATH
 
 If true, do not add run time path information.
 
-If this is set to TRUE, then the rpath information is not added to
+If this is set to ``TRUE``, then the rpath information is not added to
 compiled executables.  The default is to add rpath information if the
 platform supports it.  This allows for easy running from the build
 tree.  To omit RPATH in the install step, but not the build step, use
-CMAKE_SKIP_INSTALL_RPATH instead.
+:variable:`CMAKE_SKIP_INSTALL_RPATH` instead.
diff --git a/Help/variable/CMAKE_SOURCE_DIR.rst b/Help/variable/CMAKE_SOURCE_DIR.rst
index 088fa83..3df0226 100644
--- a/Help/variable/CMAKE_SOURCE_DIR.rst
+++ b/Help/variable/CMAKE_SOURCE_DIR.rst
@@ -5,4 +5,4 @@ The path to the top level of the source tree.
 
 This is the full path to the top level of the current CMake source
 tree.  For an in-source build, this would be the same as
-CMAKE_BINARY_DIR.
+:variable:`CMAKE_BINARY_DIR`.
diff --git a/Help/variable/CMAKE_STAGING_PREFIX.rst b/Help/variable/CMAKE_STAGING_PREFIX.rst
index c4de7da..1310e94 100644
--- a/Help/variable/CMAKE_STAGING_PREFIX.rst
+++ b/Help/variable/CMAKE_STAGING_PREFIX.rst
@@ -5,9 +5,10 @@ This variable may be set to a path to install to when cross-compiling. This can
 be useful if the path in :variable:`CMAKE_SYSROOT` is read-only, or otherwise
 should remain pristine.
 
-The CMAKE_STAGING_PREFIX location is also used as a search prefix by the ``find_*``
-commands. This can be controlled by setting the :variable:`CMAKE_FIND_NO_INSTALL_PREFIX`
-variable.
+The ``CMAKE_STAGING_PREFIX`` location is also used as a search prefix by the
+``find_*`` commands. This can be controlled by setting the
+:variable:`CMAKE_FIND_NO_INSTALL_PREFIX` variable.
 
-If any RPATH/RUNPATH entries passed to the linker contain the CMAKE_STAGING_PREFIX,
-the matching path fragments are replaced with the :variable:`CMAKE_INSTALL_PREFIX`.
+If any RPATH/RUNPATH entries passed to the linker contain the
+``CMAKE_STAGING_PREFIX``, the matching path fragments are replaced with the
+:variable:`CMAKE_INSTALL_PREFIX`.
diff --git a/Help/variable/CMAKE_STATIC_LIBRARY_PREFIX.rst b/Help/variable/CMAKE_STATIC_LIBRARY_PREFIX.rst
index 0a3095d..714b5cc 100644
--- a/Help/variable/CMAKE_STATIC_LIBRARY_PREFIX.rst
+++ b/Help/variable/CMAKE_STATIC_LIBRARY_PREFIX.rst
@@ -3,6 +3,6 @@ CMAKE_STATIC_LIBRARY_PREFIX
 
 The prefix for static libraries that you link to.
 
-The prefix to use for the name of a static library, lib on UNIX.
+The prefix to use for the name of a static library, ``lib`` on UNIX.
 
-CMAKE_STATIC_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>.
+``CMAKE_STATIC_LIBRARY_PREFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_STATIC_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_STATIC_LIBRARY_SUFFIX.rst
index 4d07671..28dc09d 100644
--- a/Help/variable/CMAKE_STATIC_LIBRARY_SUFFIX.rst
+++ b/Help/variable/CMAKE_STATIC_LIBRARY_SUFFIX.rst
@@ -3,7 +3,7 @@ CMAKE_STATIC_LIBRARY_SUFFIX
 
 The suffix for static libraries that you link to.
 
-The suffix to use for the end of a static library filename, .lib on
+The suffix to use for the end of a static library filename, ``.lib`` on
 Windows.
 
-CMAKE_STATIC_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>.
+``CMAKE_STATIC_LIBRARY_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG.rst
index 6cde24d..b9f8003 100644
--- a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG.rst
+++ b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG.rst
@@ -3,5 +3,5 @@ CMAKE_STATIC_LINKER_FLAGS_<CONFIG>
 
 Flags to be used when linking a static library.
 
-Same as CMAKE_C_FLAGS_* but used by the linker when creating static
+Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating static
 libraries.
diff --git a/Help/variable/CMAKE_SYSTEM.rst b/Help/variable/CMAKE_SYSTEM.rst
index 23f5980..c7d0d8a 100644
--- a/Help/variable/CMAKE_SYSTEM.rst
+++ b/Help/variable/CMAKE_SYSTEM.rst
@@ -1,7 +1,7 @@
 CMAKE_SYSTEM
 ------------
 
-Composit Name of OS CMake is compiling for.
+Composite name of operating system CMake is compiling for.
 
 This variable is the composite of :variable:`CMAKE_SYSTEM_NAME` and
 :variable:`CMAKE_SYSTEM_VERSION`, e.g.
diff --git a/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
new file mode 100644
index 0000000..3c6687c
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
@@ -0,0 +1,7 @@
+CMAKE_SYSTEM_APPBUNDLE_PATH
+---------------------------
+
+Search path for OS X application bundles used by the :command:`find_program`,
+and :command:`find_package` commands.  By default it contains the standard
+directories for the current system.  It is *not* intended to be modified by
+the project, use :variable:`CMAKE_APPBUNDLE_PATH` for this.
diff --git a/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
new file mode 100644
index 0000000..1e8b0d9
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
@@ -0,0 +1,8 @@
+CMAKE_SYSTEM_FRAMEWORK_PATH
+---------------------------
+
+Search path for OS X frameworks used by the :command:`find_library`,
+:command:`find_package`, :command:`find_path`, and :command:`find_file`
+commands.  By default it contains the standard directories for the
+current system.  It is *not* intended to be modified by the project,
+use :variable:`CMAKE_FRAMEWORK_PATH` for this.
diff --git a/Help/variable/CMAKE_SYSTEM_NAME.rst b/Help/variable/CMAKE_SYSTEM_NAME.rst
index 189dc18..c3a42e5 100644
--- a/Help/variable/CMAKE_SYSTEM_NAME.rst
+++ b/Help/variable/CMAKE_SYSTEM_NAME.rst
@@ -1,8 +1,20 @@
 CMAKE_SYSTEM_NAME
 -----------------
 
-Name of the OS CMake is building for.
+The name of the operating system for which CMake is to build.
+See the :variable:`CMAKE_SYSTEM_VERSION` variable for the OS version.
 
-This is the name of the OS on which CMake is targeting.  This variable
-is the same as :variable:`CMAKE_HOST_SYSTEM_NAME` if you build for the
-host system instead of the target system when cross compiling.
+System Name for Host Builds
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``CMAKE_SYSTEM_NAME`` is by default set to the same value as the
+:variable:`CMAKE_HOST_SYSTEM_NAME` variable so that the build
+targets the host system.
+
+System Name for Cross Compiling
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``CMAKE_SYSTEM_NAME`` may be set explicitly when first configuring a new build
+tree in order to enable :ref:`cross compiling <Cross Compiling Toolchain>`.
+In this case the :variable:`CMAKE_SYSTEM_VERSION` variable must also be
+set explicitly.
diff --git a/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst b/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst
index 2f5313b..09280de 100644
--- a/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst
+++ b/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst
@@ -7,4 +7,4 @@ This variable is the same as :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` if
 you build for the host system instead of the target system when
 cross compiling.
 
-* The Green Hills MULTI generator sets this to ``ARM`` by default
+* The :generator:`Green Hills MULTI` generator sets this to ``ARM`` by default.
diff --git a/Help/variable/CMAKE_SYSTEM_VERSION.rst b/Help/variable/CMAKE_SYSTEM_VERSION.rst
index 33510bb..aba8ca3 100644
--- a/Help/variable/CMAKE_SYSTEM_VERSION.rst
+++ b/Help/variable/CMAKE_SYSTEM_VERSION.rst
@@ -1,8 +1,28 @@
 CMAKE_SYSTEM_VERSION
 --------------------
 
-The OS version CMake is building for.
+The version of the operating system for which CMake is to build.
+See the :variable:`CMAKE_SYSTEM_NAME` variable for the OS name.
 
-This variable is the same as :variable:`CMAKE_HOST_SYSTEM_VERSION` if
-you build for the host system instead of the target system when
-cross compiling.
+System Version for Host Builds
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When the :variable:`CMAKE_SYSTEM_NAME` variable takes its default value
+then ``CMAKE_SYSTEM_VERSION`` is by default set to the same value as the
+:variable:`CMAKE_HOST_SYSTEM_VERSION` variable so that the build targets
+the host system version.
+
+In the case of a host build then ``CMAKE_SYSTEM_VERSION`` may be set
+explicitly when first configuring a new build tree in order to enable
+targeting the build for a different version of the host operating system
+than is actually running on the host.  This is allowed and not considered
+cross compiling so long as the binaries built for the specified OS version
+can still run on the host.
+
+System Version for Cross Compiling
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When the :variable:`CMAKE_SYSTEM_NAME` variable is set explicitly to
+enable :ref:`cross compiling <Cross Compiling Toolchain>` then the
+value of ``CMAKE_SYSTEM_VERSION`` must also be set explicitly to specify
+the target system version.
diff --git a/Help/variable/CMAKE_TOOLCHAIN_FILE.rst b/Help/variable/CMAKE_TOOLCHAIN_FILE.rst
index e1a65e1..168ee74 100644
--- a/Help/variable/CMAKE_TOOLCHAIN_FILE.rst
+++ b/Help/variable/CMAKE_TOOLCHAIN_FILE.rst
@@ -4,6 +4,6 @@ CMAKE_TOOLCHAIN_FILE
 Path to toolchain file supplied to :manual:`cmake(1)`.
 
 This variable is specified on the command line when cross-compiling with CMake.
-It is the path to a file which is read early in the CMake run and which specifies
-locations for compilers and toolchain utilities, and other target platform and
-compiler related information.
+It is the path to a file which is read early in the CMake run and which
+specifies locations for compilers and toolchain utilities, and other target
+platform and compiler related information.
diff --git a/Help/variable/CMAKE_TRY_COMPILE_CONFIGURATION.rst b/Help/variable/CMAKE_TRY_COMPILE_CONFIGURATION.rst
index a92feab..d731f02 100644
--- a/Help/variable/CMAKE_TRY_COMPILE_CONFIGURATION.rst
+++ b/Help/variable/CMAKE_TRY_COMPILE_CONFIGURATION.rst
@@ -1,9 +1,10 @@
 CMAKE_TRY_COMPILE_CONFIGURATION
 -------------------------------
 
-Build configuration used for try_compile and try_run projects.
+Build configuration used for :command:`try_compile` and :command:`try_run`
+projects.
 
-Projects built by try_compile and try_run are built synchronously
-during the CMake configuration step.  Therefore a specific build
+Projects built by :command:`try_compile` and :command:`try_run` are built
+synchronously during the CMake configuration step.  Therefore a specific build
 configuration must be chosen even if the generated build system
 supports multiple configurations.
diff --git a/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE.rst b/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE.rst
index 5a4c86b..9af0d97 100644
--- a/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE.rst
+++ b/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE.rst
@@ -4,20 +4,20 @@ CMAKE_USER_MAKE_RULES_OVERRIDE
 Specify a CMake file that overrides platform information.
 
 CMake loads the specified file while enabling support for each
-language from either the project() or enable_language() commands.  It
-is loaded after CMake's builtin compiler and platform information
+language from either the :command:`project` or :command:`enable_language`
+commands.  It is loaded after CMake's builtin compiler and platform information
 modules have been loaded but before the information is used.  The file
 may set platform information variables to override CMake's defaults.
 
 This feature is intended for use only in overriding information
 variables that must be set before CMake builds its first test project
 to check that the compiler for a language works.  It should not be
-used to load a file in cases that a normal include() will work.  Use
+used to load a file in cases that a normal :command:`include` will work.  Use
 it only as a last resort for behavior that cannot be achieved any
-other way.  For example, one may set CMAKE_C_FLAGS_INIT to change the
-default value used to initialize CMAKE_C_FLAGS before it is cached.
-The override file should NOT be used to set anything that could be set
-after languages are enabled, such as variables like
-CMAKE_RUNTIME_OUTPUT_DIRECTORY that affect the placement of binaries.
-Information set in the file will be used for try_compile and try_run
-builds too.
+other way.  For example, one may set ``CMAKE_C_FLAGS_INIT`` to change the
+default value used to initialize :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>`
+before it is cached.  The override file should NOT be used to set anything
+that could be set after languages are enabled, such as variables like
+:variable:`CMAKE_RUNTIME_OUTPUT_DIRECTORY` that affect the placement of
+binaries.  Information set in the file will be used for :command:`try_compile`
+and :command:`try_run` builds too.
diff --git a/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE_LANG.rst b/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE_LANG.rst
index e6d2c68..e7139ac 100644
--- a/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE_LANG.rst
+++ b/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE_LANG.rst
@@ -1,7 +1,8 @@
 CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG>
 -------------------------------------
 
-Specify a CMake file that overrides platform information for <LANG>.
+Specify a CMake file that overrides platform information for ``<LANG>``.
 
-This is a language-specific version of CMAKE_USER_MAKE_RULES_OVERRIDE
-loaded only when enabling language <LANG>.
+This is a language-specific version of
+:variable:`CMAKE_USER_MAKE_RULES_OVERRIDE` loaded only when enabling language
+``<LANG>``.
diff --git a/Help/variable/CMAKE_USE_RELATIVE_PATHS.rst b/Help/variable/CMAKE_USE_RELATIVE_PATHS.rst
index af6f08c..06fe0fb 100644
--- a/Help/variable/CMAKE_USE_RELATIVE_PATHS.rst
+++ b/Help/variable/CMAKE_USE_RELATIVE_PATHS.rst
@@ -1,10 +1,5 @@
 CMAKE_USE_RELATIVE_PATHS
 ------------------------
 
-Use relative paths (May not work!).
-
-If this is set to TRUE, then CMake will use relative paths between the
-source and binary tree.  This option does not work for more
-complicated projects, and relative paths are used when possible.  In
-general, it is not possible to move CMake generated makefiles to a
-different location regardless of the value of this variable.
+This variable has no effect.  The partially implemented effect it
+had in previous releases was removed in CMake 3.4.
diff --git a/Help/variable/CMAKE_VERBOSE_MAKEFILE.rst b/Help/variable/CMAKE_VERBOSE_MAKEFILE.rst
index 2420a25..232a2fd 100644
--- a/Help/variable/CMAKE_VERBOSE_MAKEFILE.rst
+++ b/Help/variable/CMAKE_VERBOSE_MAKEFILE.rst
@@ -3,7 +3,7 @@ CMAKE_VERBOSE_MAKEFILE
 
 Enable verbose output from Makefile builds.
 
-This variable is a cache entry initialized (to FALSE) by
+This variable is a cache entry initialized (to ``FALSE``) by
 the :command:`project` command.  Users may enable the option
 in their local build tree to get more verbose output from
 Makefile builds and show each command line as it is launched.
diff --git a/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst b/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
index 68f1ff6..f54472a 100644
--- a/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
+++ b/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
@@ -1,8 +1,8 @@
 CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
 -----------------------------------------
 
-Include INSTALL target to default build.
+Include ``INSTALL`` target to default build.
 
-In Visual Studio solution, by default the INSTALL target will not be part of
-the default build. Setting this variable will enable the INSTALL target to be
-part of the default build.
+In Visual Studio solution, by default the ``INSTALL`` target will not be part
+of the default build. Setting this variable will enable the ``INSTALL`` target
+to be part of the default build.
diff --git a/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst b/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst
index 7e9d317..0be10e5 100644
--- a/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst
+++ b/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst
@@ -1,7 +1,7 @@
 CMAKE_VS_INTEL_Fortran_PROJECT_VERSION
 --------------------------------------
 
-When generating for Visual Studio 7 or greater with the Intel Fortran
-plugin installed, this specifies the .vfproj project file format
+When generating for :generator:`Visual Studio 7` or greater with the Intel
+Fortran plugin installed, this specifies the ``.vfproj`` project file format
 version.  This is intended for internal use by CMake and should not be
 used by project code.
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET.rst
index 08c6061..144a41d 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET.rst
@@ -5,6 +5,6 @@ Visual Studio Platform Toolset name.
 
 VS 10 and above use MSBuild under the hood and support multiple
 compiler toolchains.  CMake may specify a toolset explicitly, such as
-"v110" for VS 11 or "Windows7.1SDK" for 64-bit support in VS 10
+``v110`` for VS 11 or ``Windows7.1SDK`` for 64-bit support in VS 10
 Express.  CMake provides the name of the chosen toolset in this
 variable.
diff --git a/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
new file mode 100644
index 0000000..6392849
--- /dev/null
+++ b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
@@ -0,0 +1,11 @@
+CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
+----------------------------------------
+
+Visual Studio Windows Target Platform Version.
+
+When targeting Windows 10 and above Visual Studio 2015 and above support
+specification of a target Windows version to select a corresponding SDK.
+The :variable:`CMAKE_SYSTEM_VERSION` variable may be set to specify a
+version.  Otherwise CMake computes a default version based on the Windows
+SDK versions available.  The chosen Windows target version number is provided
+in ``CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION``.
diff --git a/Help/variable/CMAKE_WARN_DEPRECATED.rst b/Help/variable/CMAKE_WARN_DEPRECATED.rst
index 7b2510b..662cbd8 100644
--- a/Help/variable/CMAKE_WARN_DEPRECATED.rst
+++ b/Help/variable/CMAKE_WARN_DEPRECATED.rst
@@ -3,5 +3,5 @@ CMAKE_WARN_DEPRECATED
 
 Whether to issue deprecation warnings for macros and functions.
 
-If TRUE, this can be used by macros and functions to issue deprecation
-warnings.  This variable is FALSE by default.
+If ``TRUE``, this can be used by macros and functions to issue deprecation
+warnings.  This variable is ``FALSE`` by default.
diff --git a/Help/variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst b/Help/variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
index f6a188d..81c1158 100644
--- a/Help/variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
+++ b/Help/variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
@@ -1,8 +1,9 @@
 CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
 ------------------------------------------
 
-Ask cmake_install.cmake script to warn each time a file with absolute INSTALL DESTINATION is encountered.
+Ask ``cmake_install.cmake`` script to warn each time a file with absolute
+``INSTALL DESTINATION`` is encountered.
 
-This variable is used by CMake-generated cmake_install.cmake scripts.
-If one sets this variable to ON while running the script, it may get
+This variable is used by CMake-generated ``cmake_install.cmake`` scripts.
+If one sets this variable to ``ON`` while running the script, it may get
 warning messages from the script.
diff --git a/Help/variable/CMAKE_WIN32_EXECUTABLE.rst b/Help/variable/CMAKE_WIN32_EXECUTABLE.rst
index 3e1e0dd..b96abba 100644
--- a/Help/variable/CMAKE_WIN32_EXECUTABLE.rst
+++ b/Help/variable/CMAKE_WIN32_EXECUTABLE.rst
@@ -1,7 +1,7 @@
 CMAKE_WIN32_EXECUTABLE
 ----------------------
 
-Default value for WIN32_EXECUTABLE of targets.
+Default value for :prop_tgt:`WIN32_EXECUTABLE` of targets.
 
-This variable is used to initialize the WIN32_EXECUTABLE property on
-all the targets.  See that target property for additional information.
+This variable is used to initialize the :prop_tgt:`WIN32_EXECUTABLE` property
+on all the targets.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..1636842
--- /dev/null
+++ b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,6 @@
+CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------------
+
+Default value for :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
+This variable is used to initialize the property on each target as it is
+created.
diff --git a/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst b/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
index 096f64e..122b9f6 100644
--- a/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
+++ b/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
@@ -3,8 +3,8 @@ CMAKE_XCODE_ATTRIBUTE_<an-attribute>
 
 Set Xcode target attributes directly.
 
-Tell the Xcode generator to set '<an-attribute>' to a given value in
-the generated Xcode project.  Ignored on other generators.
+Tell the :generator:`Xcode` generator to set '<an-attribute>' to a given value
+in the generated Xcode project.  Ignored on other generators.
 
 See the :prop_tgt:`XCODE_ATTRIBUTE_<an-attribute>` target property
 to set attributes on a specific target.
diff --git a/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst b/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst
index f0a4841..210da52 100644
--- a/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst
+++ b/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst
@@ -3,7 +3,7 @@ CMAKE_XCODE_PLATFORM_TOOLSET
 
 Xcode compiler selection.
 
-Xcode supports selection of a compiler from one of the installed
+:generator:`Xcode` supports selection of a compiler from one of the installed
 toolsets.  CMake provides the name of the chosen toolset in this
-variable, if any is explicitly selected (e.g.  via the cmake -T
-option).
+variable, if any is explicitly selected (e.g.  via the :manual:`cmake(1)`
+``-T`` option).
diff --git a/Help/variable/CPACK_ABSOLUTE_DESTINATION_FILES.rst b/Help/variable/CPACK_ABSOLUTE_DESTINATION_FILES.rst
index d836629..928fe45 100644
--- a/Help/variable/CPACK_ABSOLUTE_DESTINATION_FILES.rst
+++ b/Help/variable/CPACK_ABSOLUTE_DESTINATION_FILES.rst
@@ -1,10 +1,10 @@
 CPACK_ABSOLUTE_DESTINATION_FILES
 --------------------------------
 
-List of files which have been installed using  an ABSOLUTE DESTINATION path.
+List of files which have been installed using an ``ABSOLUTE DESTINATION`` path.
 
 This variable is a Read-Only variable which is set internally by CPack
 during installation and before packaging using
-CMAKE_ABSOLUTE_DESTINATION_FILES defined in cmake_install.cmake
+:variable:`CMAKE_ABSOLUTE_DESTINATION_FILES` defined in ``cmake_install.cmake``
 scripts.  The value can be used within CPack project configuration
-file and/or CPack<GEN>.cmake file of <GEN> generator.
+file and/or ``CPack<GEN>.cmake`` file of ``<GEN>`` generator.
diff --git a/Help/variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY.rst b/Help/variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY.rst
index e938978..6cf75e4 100644
--- a/Help/variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY.rst
+++ b/Help/variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY.rst
@@ -3,6 +3,6 @@ CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
 
 Boolean toggle to include/exclude top level directory (component case).
 
-Similar usage as CPACK_INCLUDE_TOPLEVEL_DIRECTORY but for the
-component case.  See CPACK_INCLUDE_TOPLEVEL_DIRECTORY documentation
-for the detail.
+Similar usage as :variable:`CPACK_INCLUDE_TOPLEVEL_DIRECTORY` but for the
+component case.  See :variable:`CPACK_INCLUDE_TOPLEVEL_DIRECTORY`
+documentation for the detail.
diff --git a/Help/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst b/Help/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
index 4d96385..5dad6bd 100644
--- a/Help/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
+++ b/Help/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
@@ -1,10 +1,11 @@
 CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
 -------------------------------------------
 
-Ask CPack to error out as soon as a file with absolute INSTALL DESTINATION is encountered.
+Ask CPack to error out as soon as a file with absolute ``INSTALL DESTINATION``
+is encountered.
 
 The fatal error is emitted before the installation of the offending
-file takes place.  Some CPack generators, like NSIS,enforce this
+file takes place.  Some CPack generators, like NSIS, enforce this
 internally.  This variable triggers the definition
-ofCMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runsVariables
-common to all CPack generators
+of :variable:`CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION` when CPack
+runs.
diff --git a/Help/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY.rst b/Help/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY.rst
index 4f96bff..b8e9105 100644
--- a/Help/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY.rst
+++ b/Help/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY.rst
@@ -4,16 +4,17 @@ CPACK_INCLUDE_TOPLEVEL_DIRECTORY
 Boolean toggle to include/exclude top level directory.
 
 When preparing a package CPack installs the item under the so-called
-top level directory.  The purpose of is to include (set to 1 or ON or
-TRUE) the top level directory in the package or not (set to 0 or OFF
-or FALSE).
+top level directory.  The purpose of is to include (set to ``1`` or ``ON`` or
+``TRUE``) the top level directory in the package or not (set to ``0`` or
+``OFF`` or ``FALSE``).
 
 Each CPack generator has a built-in default value for this variable.
 E.g.  Archive generators (ZIP, TGZ, ...) includes the top level
 whereas RPM or DEB don't.  The user may override the default value by
 setting this variable.
 
-There is a similar variable CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
-which may be used to override the behavior for the component packaging
+There is a similar variable
+:variable:`CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY` which may be used
+to override the behavior for the component packaging
 case which may have different default value for historical (now
 backward compatibility) reason.
diff --git a/Help/variable/CPACK_INSTALL_SCRIPT.rst b/Help/variable/CPACK_INSTALL_SCRIPT.rst
index 59b8cd7..12a48a4 100644
--- a/Help/variable/CPACK_INSTALL_SCRIPT.rst
+++ b/Help/variable/CPACK_INSTALL_SCRIPT.rst
@@ -5,4 +5,4 @@ Extra CMake script provided by the user.
 
 If set this CMake script will be executed by CPack during its local
 [CPack-private] installation which is done right before packaging the
-files.  The script is not called by e.g.: make install.
+files.  The script is not called by e.g.: ``make install``.
diff --git a/Help/variable/CPACK_PACKAGING_INSTALL_PREFIX.rst b/Help/variable/CPACK_PACKAGING_INSTALL_PREFIX.rst
index f9cfa1b..f423e2e 100644
--- a/Help/variable/CPACK_PACKAGING_INSTALL_PREFIX.rst
+++ b/Help/variable/CPACK_PACKAGING_INSTALL_PREFIX.rst
@@ -3,11 +3,13 @@ CPACK_PACKAGING_INSTALL_PREFIX
 
 The prefix used in the built package.
 
-Each CPack generator has a default value (like /usr).  This default
-value may be overwritten from the CMakeLists.txt or the cpack command
-line by setting an alternative value.
+Each CPack generator has a default value (like ``/usr``).  This default
+value may be overwritten from the ``CMakeLists.txt`` or the :manual:`cpack(1)`
+command line by setting an alternative value.  Example:
 
-e.g.  set(CPACK_PACKAGING_INSTALL_PREFIX "/opt")
+::
 
-This is not the same purpose as CMAKE_INSTALL_PREFIX which is used
+  set(CPACK_PACKAGING_INSTALL_PREFIX "/opt")
+
+This is not the same purpose as :variable:`CMAKE_INSTALL_PREFIX` which is used
 when installing from the build tree without building a package.
diff --git a/Help/variable/CPACK_SET_DESTDIR.rst b/Help/variable/CPACK_SET_DESTDIR.rst
index 69d82e6..27fd355 100644
--- a/Help/variable/CPACK_SET_DESTDIR.rst
+++ b/Help/variable/CPACK_SET_DESTDIR.rst
@@ -1,30 +1,31 @@
 CPACK_SET_DESTDIR
 -----------------
 
-Boolean toggle to make CPack use DESTDIR mechanism when packaging.
+Boolean toggle to make CPack use ``DESTDIR`` mechanism when packaging.
 
-DESTDIR means DESTination DIRectory.  It is commonly used by makefile
+``DESTDIR`` means DESTination DIRectory.  It is commonly used by makefile
 users in order to install software at non-default location.  It is a
 basic relocation mechanism that should not be used on Windows (see
-CMAKE_INSTALL_PREFIX documentation).  It is usually invoked like this:
+:variable:`CMAKE_INSTALL_PREFIX` documentation).  It is usually invoked like
+this:
 
 ::
 
  make DESTDIR=/home/john install
 
 which will install the concerned software using the installation
-prefix, e.g.  "/usr/local" prepended with the DESTDIR value which
-finally gives "/home/john/usr/local".  When preparing a package, CPack
+prefix, e.g. ``/usr/local`` prepended with the ``DESTDIR`` value which
+finally gives ``/home/john/usr/local``.  When preparing a package, CPack
 first installs the items to be packaged in a local (to the build tree)
-directory by using the same DESTDIR mechanism.  Nevertheless, if
-CPACK_SET_DESTDIR is set then CPack will set DESTDIR before doing the
+directory by using the same ``DESTDIR`` mechanism.  Nevertheless, if
+``CPACK_SET_DESTDIR`` is set then CPack will set ``DESTDIR`` before doing the
 local install.  The most noticeable difference is that without
-CPACK_SET_DESTDIR, CPack uses CPACK_PACKAGING_INSTALL_PREFIX as a
-prefix whereas with CPACK_SET_DESTDIR set, CPack will use
-CMAKE_INSTALL_PREFIX as a prefix.
+``CPACK_SET_DESTDIR``, CPack uses :variable:`CPACK_PACKAGING_INSTALL_PREFIX`
+as a prefix whereas with ``CPACK_SET_DESTDIR`` set, CPack will use
+:variable:`CMAKE_INSTALL_PREFIX` as a prefix.
 
-Manually setting CPACK_SET_DESTDIR may help (or simply be necessary)
-if some install rules uses absolute DESTINATION (see CMake INSTALL
-command).  However, starting with CPack/CMake 2.8.3 RPM and DEB
-installers tries to handle DESTDIR automatically so that it is seldom
-necessary for the user to set it.
+Manually setting ``CPACK_SET_DESTDIR`` may help (or simply be necessary)
+if some install rules uses absolute ``DESTINATION`` (see CMake
+:command:`install` command).  However, starting with CPack/CMake 2.8.3 RPM
+and DEB installers tries to handle ``DESTDIR`` automatically so that it is
+seldom necessary for the user to set it.
diff --git a/Help/variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst b/Help/variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
index 8d6f54f..3fc5cca 100644
--- a/Help/variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
+++ b/Help/variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
@@ -1,8 +1,9 @@
 CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
 ------------------------------------------
 
-Ask CPack to warn each time a file with absolute INSTALL DESTINATION is encountered.
+Ask CPack to warn each time a file with absolute ``INSTALL DESTINATION`` is
+encountered.
 
 This variable triggers the definition of
-CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runs
-cmake_install.cmake scripts.
+:variable:`CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION` when CPack runs
+``cmake_install.cmake`` scripts.
diff --git a/Help/variable/CTEST_CHANGE_ID.rst b/Help/variable/CTEST_CHANGE_ID.rst
new file mode 100644
index 0000000..a423f49
--- /dev/null
+++ b/Help/variable/CTEST_CHANGE_ID.rst
@@ -0,0 +1,9 @@
+CTEST_CHANGE_ID
+---------------
+
+Specify the CTest ``ChangeId`` setting
+in a :manual:`ctest(1)` dashboard client script.
+
+This setting allows CTest to pass arbitrary information about this
+build up to CDash.  One use of this feature is to allow CDash to
+post comments on your pull request if anything goes wrong with your build.
diff --git a/Help/variable/CTEST_COVERAGE_COMMAND.rst b/Help/variable/CTEST_COVERAGE_COMMAND.rst
index a669dd7..0491d42 100644
--- a/Help/variable/CTEST_COVERAGE_COMMAND.rst
+++ b/Help/variable/CTEST_COVERAGE_COMMAND.rst
@@ -12,12 +12,12 @@ Java project can generate a series of XML files.
 
 The Cobertura Coverage parser expects to read the coverage data from a
 single XML file which contains the coverage data for all modules.
-Cobertura has a program with the ability to merge given cobertura.ser files
+Cobertura has a program with the ability to merge given ``cobertura.ser`` files
 and then another program to generate a combined XML file from the previous
 merged file.  For command line testing, this can be done by hand prior to
 CTest looking for the coverage files. For script builds,
 set the ``CTEST_COVERAGE_COMMAND`` variable to point to a file which will
-perform these same steps, such as a .sh or .bat file.
+perform these same steps, such as a ``.sh`` or ``.bat`` file.
 
 .. code-block:: cmake
 
@@ -35,17 +35,17 @@ the :command:`configure_file` command and might contain the following code:
   cobertura-report --datafile coberturamerge.ser --destination . \
                    --format xml $SourceDirs
 
-The script uses ``find`` to capture the paths to all of the cobertura.ser files
-found below the project's source directory.  It keeps the list of files and
-supplies it as an argument to the ``cobertura-merge`` program. The ``--datafile``
-argument signifies where the result of the merge will be kept.
+The script uses ``find`` to capture the paths to all of the ``cobertura.ser``
+files found below the project's source directory.  It keeps the list of files
+and supplies it as an argument to the ``cobertura-merge`` program. The
+``--datafile`` argument signifies where the result of the merge will be kept.
 
 The combined ``coberturamerge.ser`` file is then used to generate the XML report
-using the ``cobertura-report`` program.  The call to the cobertura-report program
-requires some named arguments.
+using the ``cobertura-report`` program.  The call to the cobertura-report
+program requires some named arguments.
 
 ``--datafila``
-  path to the merged .ser file
+  path to the merged ``.ser`` file
 
 ``--destination``
   path to put the output files(s)
@@ -54,7 +54,7 @@ requires some named arguments.
   file format to write output in: xml or html
 
 The rest of the supplied arguments consist of the full paths to the
-/src/main/java directories of each module within the souce tree. These
+``/src/main/java`` directories of each module within the souce tree. These
 directories are needed and should not be forgotten.
 
 .. _`Cobertura`: http://cobertura.github.io/cobertura/
diff --git a/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst b/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
new file mode 100644
index 0000000..d5893c9
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_COVERAGE_EXCLUDE
+-----------------------------
+
+A list of regular expressions which will be used to exclude files by their
+path from coverage output by the :command:`ctest_coverage` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst b/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
new file mode 100644
index 0000000..cd65ae3
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_ERROR_EXCEPTION
+----------------------------
+
+A list of regular expressions which will be used to exclude when detecting
+error messages in build outputs by the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst b/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
new file mode 100644
index 0000000..558f5e5
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_ERROR_MATCH
+------------------------
+
+A list of regular expressions which will be used to detect error messages in
+build outputs by the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst b/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
new file mode 100644
index 0000000..614859b
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_ERROR_POST_CONTEXT
+-------------------------------
+
+The number of lines to include as context which follow an error message by the
+:command:`ctest_test` command. The default is 10.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst b/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
new file mode 100644
index 0000000..74dc47a
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_ERROR_PRE_CONTEXT
+------------------------------
+
+The number of lines to include as context which precede an error message by
+the :command:`ctest_test` command. The default is 10.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
new file mode 100644
index 0000000..5aeae88
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
@@ -0,0 +1,8 @@
+CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE
+--------------------------------------------
+
+When saving a failing test's output, this is the maximum size, in bytes, that
+will be collected by the :command:`ctest_test` command. Defaults to 307200
+(300 KiB).
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
new file mode 100644
index 0000000..920cb04
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
@@ -0,0 +1,8 @@
+CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
+-------------------------------------
+
+The maximum number of errors in a single build step which will be detected.
+After this, the :command:`ctest_test` command will truncate the output.
+Defaults to 50.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
new file mode 100644
index 0000000..a1f1cc1
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
@@ -0,0 +1,8 @@
+CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
+---------------------------------------
+
+The maximum number of warnings in a single build step which will be detected.
+After this, the :command:`ctest_test` command will truncate the output.
+Defaults to 50.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
new file mode 100644
index 0000000..1fbb8c5
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
@@ -0,0 +1,8 @@
+CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
+--------------------------------------------
+
+When saving a passing test's output, this is the maximum size, in bytes, that
+will be collected by the :command:`ctest_test` command. Defaults to 1024
+(1 KiB).
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst b/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
new file mode 100644
index 0000000..578576c
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_MEMCHECK_IGNORE
+----------------------------
+
+A list of regular expressions to use to exclude tests during the
+:command:`ctest_memcheck` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst b/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
new file mode 100644
index 0000000..40291fe
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
@@ -0,0 +1,6 @@
+CTEST_CUSTOM_POST_MEMCHECK
+--------------------------
+
+A list of commands to run at the end of the :command:`ctest_memcheck` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_POST_TEST.rst b/Help/variable/CTEST_CUSTOM_POST_TEST.rst
new file mode 100644
index 0000000..791292c
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_POST_TEST.rst
@@ -0,0 +1,6 @@
+CTEST_CUSTOM_POST_TEST
+----------------------
+
+A list of commands to run at the end of the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst b/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
new file mode 100644
index 0000000..00de8aa
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_PRE_MEMCHECK
+-------------------------
+
+A list of commands to run at the start of the :command:`ctest_memcheck`
+command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_PRE_TEST.rst b/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
new file mode 100644
index 0000000..6af7152
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
@@ -0,0 +1,6 @@
+CTEST_CUSTOM_PRE_TEST
+----------------------
+
+A list of commands to run at the start of the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_TEST_IGNORE.rst b/Help/variable/CTEST_CUSTOM_TEST_IGNORE.rst
new file mode 100644
index 0000000..6114e60
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_TEST_IGNORE.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_TEST_IGNORE
+------------------------
+
+A list of regular expressions to use to exclude tests during the
+:command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst b/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
new file mode 100644
index 0000000..36fa37d
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_WARNING_EXCEPTION
+------------------------------
+
+A list of regular expressions which will be used to exclude when detecting
+warning messages in build outputs by the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst b/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
new file mode 100644
index 0000000..a35be96
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_WARNING_MATCH
+--------------------------
+
+A list of regular expressions which will be used to detect warning messages in
+build outputs by the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_XXX.txt b/Help/variable/CTEST_CUSTOM_XXX.txt
new file mode 100644
index 0000000..02d1547
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_XXX.txt
@@ -0,0 +1,2 @@
+It is initialized by :manual:`ctest(1)`, but may be edited in a ``CTestCustom``
+file. See :command:`ctest_read_custom_files` documentation.
diff --git a/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst b/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
new file mode 100644
index 0000000..286f7df
--- /dev/null
+++ b/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
@@ -0,0 +1,7 @@
+CTEST_EXTRA_COVERAGE_GLOB
+-------------------------
+
+A list of regular expressions which will be used to find files which should be
+covered by the :command:`ctest_coverage` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
index f1087c0..b963293 100644
--- a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
@@ -3,5 +3,6 @@ CTEST_MEMORYCHECK_TYPE
 
 Specify the CTest ``MemoryCheckType`` setting
 in a :manual:`ctest(1)` dashboard client script.
-Valid values are Valgrind, Purify, BoundsChecker, and ThreadSanitizer,
-AddressSanitizer, MemorySanitizer, and UndefinedBehaviorSanitizer.
+Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, and
+``ThreadSanitizer``, ``AddressSanitizer``, ``MemorySanitizer``, and
+``UndefinedBehaviorSanitizer``.
diff --git a/Help/variable/CTEST_TEST_LOAD.rst b/Help/variable/CTEST_TEST_LOAD.rst
new file mode 100644
index 0000000..80823fe
--- /dev/null
+++ b/Help/variable/CTEST_TEST_LOAD.rst
@@ -0,0 +1,7 @@
+CTEST_TEST_LOAD
+---------------
+
+Specify the ``TestLoad`` setting in the :ref:`CTest Test Step`
+of a :manual:`ctest(1)` dashboard client script.  This sets the
+default value for the ``TEST_LOAD`` option of the :command:`ctest_test`
+command.
diff --git a/Help/variable/CYGWIN.rst b/Help/variable/CYGWIN.rst
index c168878..0039e07 100644
--- a/Help/variable/CYGWIN.rst
+++ b/Help/variable/CYGWIN.rst
@@ -1,6 +1,6 @@
 CYGWIN
 ------
 
-True for Cygwin.
+``True`` for Cygwin.
 
-Set to true when using Cygwin.
+Set to ``true`` when using Cygwin.
diff --git a/Help/variable/ENV.rst b/Help/variable/ENV.rst
index 977afc3..368152a 100644
--- a/Help/variable/ENV.rst
+++ b/Help/variable/ENV.rst
@@ -3,5 +3,5 @@ ENV
 
 Access environment variables.
 
-Use the syntax $ENV{VAR} to read environment variable VAR.  See also
-the set() command to set ENV{VAR}.
+Use the syntax ``$ENV{VAR}`` to read environment variable ``VAR``.  See also
+the :command:`set` command to set ``ENV{VAR}``.
diff --git a/Help/variable/EXECUTABLE_OUTPUT_PATH.rst b/Help/variable/EXECUTABLE_OUTPUT_PATH.rst
index 7079230..26d3e92 100644
--- a/Help/variable/EXECUTABLE_OUTPUT_PATH.rst
+++ b/Help/variable/EXECUTABLE_OUTPUT_PATH.rst
@@ -3,6 +3,6 @@ EXECUTABLE_OUTPUT_PATH
 
 Old executable location variable.
 
-The target property RUNTIME_OUTPUT_DIRECTORY supercedes this variable
-for a target if it is set.  Executable targets are otherwise placed in
+The target property :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` supercedes this
+variable for a target if it is set.  Executable targets are otherwise placed in
 this directory.
diff --git a/Help/variable/LIBRARY_OUTPUT_PATH.rst b/Help/variable/LIBRARY_OUTPUT_PATH.rst
index 1c1f8ae..ba02911 100644
--- a/Help/variable/LIBRARY_OUTPUT_PATH.rst
+++ b/Help/variable/LIBRARY_OUTPUT_PATH.rst
@@ -3,7 +3,7 @@ LIBRARY_OUTPUT_PATH
 
 Old library location variable.
 
-The target properties ARCHIVE_OUTPUT_DIRECTORY,
-LIBRARY_OUTPUT_DIRECTORY, and RUNTIME_OUTPUT_DIRECTORY supercede this
-variable for a target if they are set.  Library targets are otherwise
-placed in this directory.
+The target properties :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY`,
+:prop_tgt:`LIBRARY_OUTPUT_DIRECTORY`, and :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY`
+supercede this variable for a target if they are set.  Library targets are
+otherwise placed in this directory.
diff --git a/Help/variable/MINGW.rst b/Help/variable/MINGW.rst
index 521d417..6d29be4 100644
--- a/Help/variable/MINGW.rst
+++ b/Help/variable/MINGW.rst
@@ -1,6 +1,6 @@
 MINGW
 -----
 
-True when using MinGW
+``True`` when using MinGW
 
-Set to true when the compiler is some version of MinGW.
+Set to ``true`` when the compiler is some version of MinGW.
diff --git a/Help/variable/MSVC.rst b/Help/variable/MSVC.rst
index e9f931b..913ed08 100644
--- a/Help/variable/MSVC.rst
+++ b/Help/variable/MSVC.rst
@@ -1,6 +1,6 @@
 MSVC
 ----
 
-True when using Microsoft Visual C
+``True`` when using Microsoft Visual C++.
 
-Set to true when the compiler is some version of Microsoft Visual C.
+Set to ``true`` when the compiler is some version of Microsoft Visual C++.
diff --git a/Help/variable/MSVC10.rst b/Help/variable/MSVC10.rst
index 894c5aa..33692ad 100644
--- a/Help/variable/MSVC10.rst
+++ b/Help/variable/MSVC10.rst
@@ -1,6 +1,6 @@
 MSVC10
 ------
 
-True when using Microsoft Visual C 10.0
+``True`` when using Microsoft Visual C++ 10.0
 
-Set to true when the compiler is version 10.0 of Microsoft Visual C.
+Set to ``true`` when the compiler is version 10.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC11.rst b/Help/variable/MSVC11.rst
index fe25297..3ab606d 100644
--- a/Help/variable/MSVC11.rst
+++ b/Help/variable/MSVC11.rst
@@ -1,6 +1,6 @@
 MSVC11
 ------
 
-True when using Microsoft Visual C 11.0
+``True`` when using Microsoft Visual C++ 11.0
 
-Set to true when the compiler is version 11.0 of Microsoft Visual C.
+Set to ``true`` when the compiler is version 11.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC12.rst b/Help/variable/MSVC12.rst
index 216d3d3..15fa64b 100644
--- a/Help/variable/MSVC12.rst
+++ b/Help/variable/MSVC12.rst
@@ -1,6 +1,6 @@
 MSVC12
 ------
 
-True when using Microsoft Visual C 12.0
+``True`` when using Microsoft Visual C++ 12.0.
 
-Set to true when the compiler is version 12.0 of Microsoft Visual C.
+Set to ``true`` when the compiler is version 12.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC14.rst b/Help/variable/MSVC14.rst
index 33c782b..0b9125d 100644
--- a/Help/variable/MSVC14.rst
+++ b/Help/variable/MSVC14.rst
@@ -1,6 +1,6 @@
 MSVC14
 ------
 
-True when using Microsoft Visual C 14.0
+``True`` when using Microsoft Visual C++ 14.0.
 
-Set to true when the compiler is version 14.0 of Microsoft Visual C.
+Set to ``true`` when the compiler is version 14.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC60.rst b/Help/variable/MSVC60.rst
index 572e9f4..14f09cf 100644
--- a/Help/variable/MSVC60.rst
+++ b/Help/variable/MSVC60.rst
@@ -1,6 +1,6 @@
 MSVC60
 ------
 
-True when using Microsoft Visual C 6.0
+``True`` when using Microsoft Visual C++ 6.0.
 
-Set to true when the compiler is version 6.0 of Microsoft Visual C.
+Set to ``true`` when the compiler is version 6.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC70.rst b/Help/variable/MSVC70.rst
index b1b7a88..76fa96f 100644
--- a/Help/variable/MSVC70.rst
+++ b/Help/variable/MSVC70.rst
@@ -1,6 +1,6 @@
 MSVC70
 ------
 
-True when using Microsoft Visual C 7.0
+``True`` when using Microsoft Visual C++ 7.0.
 
-Set to true when the compiler is version 7.0 of Microsoft Visual C.
+Set to ``true`` when the compiler is version 7.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC71.rst b/Help/variable/MSVC71.rst
index af309a6..d69d4fc 100644
--- a/Help/variable/MSVC71.rst
+++ b/Help/variable/MSVC71.rst
@@ -1,6 +1,6 @@
 MSVC71
 ------
 
-True when using Microsoft Visual C 7.1
+``True`` when using Microsoft Visual C++ 7.1.
 
-Set to true when the compiler is version 7.1 of Microsoft Visual C.
+Set to ``true`` when the compiler is version 7.1 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC80.rst b/Help/variable/MSVC80.rst
index 306c67f..b17777c 100644
--- a/Help/variable/MSVC80.rst
+++ b/Help/variable/MSVC80.rst
@@ -1,6 +1,6 @@
 MSVC80
 ------
 
-True when using Microsoft Visual C 8.0
+``True`` when using Microsoft Visual C++ 8.0.
 
-Set to true when the compiler is version 8.0 of Microsoft Visual C.
+Set to ``true`` when the compiler is version 8.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC90.rst b/Help/variable/MSVC90.rst
index 3cfcc67..7162d6c 100644
--- a/Help/variable/MSVC90.rst
+++ b/Help/variable/MSVC90.rst
@@ -1,6 +1,6 @@
 MSVC90
 ------
 
-True when using Microsoft Visual C 9.0
+``True`` when using Microsoft Visual C++ 9.0.
 
-Set to true when the compiler is version 9.0 of Microsoft Visual C.
+Set to ``true`` when the compiler is version 9.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC_IDE.rst b/Help/variable/MSVC_IDE.rst
index 055f876..027d1bc 100644
--- a/Help/variable/MSVC_IDE.rst
+++ b/Help/variable/MSVC_IDE.rst
@@ -1,7 +1,7 @@
 MSVC_IDE
 --------
 
-True when using the Microsoft Visual C IDE
+``True`` when using the Microsoft Visual C++ IDE.
 
-Set to true when the target platform is the Microsoft Visual C IDE, as
+Set to ``true`` when the target platform is the Microsoft Visual C++ IDE, as
 opposed to the command line compiler.
diff --git a/Help/variable/UNIX.rst b/Help/variable/UNIX.rst
index 82e3454..0877b7c 100644
--- a/Help/variable/UNIX.rst
+++ b/Help/variable/UNIX.rst
@@ -1,7 +1,7 @@
 UNIX
 ----
 
-True for UNIX and UNIX like operating systems.
+``True`` for UNIX and UNIX like operating systems.
 
-Set to true when the target system is UNIX or UNIX like (i.e.  APPLE
-and CYGWIN).
+Set to ``true`` when the target system is UNIX or UNIX like (i.e.
+:variable:`APPLE` and :variable:`CYGWIN`).
diff --git a/Help/variable/WIN32.rst b/Help/variable/WIN32.rst
index 8cf7bf3..2189069 100644
--- a/Help/variable/WIN32.rst
+++ b/Help/variable/WIN32.rst
@@ -1,6 +1,6 @@
 WIN32
 -----
 
-True on windows systems, including win64.
+``True`` on Windows systems, including Win64.
 
-Set to true when the target system is Windows.
+Set to ``true`` when the target system is Windows.
diff --git a/Help/variable/XCODE_VERSION.rst b/Help/variable/XCODE_VERSION.rst
index b6f0403..b85d41e 100644
--- a/Help/variable/XCODE_VERSION.rst
+++ b/Help/variable/XCODE_VERSION.rst
@@ -1,7 +1,7 @@
 XCODE_VERSION
 -------------
 
-Version of Xcode (Xcode generator only).
+Version of Xcode (:generator:`Xcode` generator only).
 
 Under the Xcode generator, this is the version of Xcode as specified
-in "Xcode.app/Contents/version.plist" (such as "3.1.2").
+in ``Xcode.app/Contents/version.plist`` (such as ``3.1.2``).
diff --git a/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in b/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in
index b1c4fdf..bc78016 100644
--- a/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in
+++ b/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in
@@ -9,22 +9,22 @@
 
 set(PACKAGE_VERSION "@CVF_VERSION@")
 
-if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
   set(PACKAGE_VERSION_COMPATIBLE FALSE)
 else()
   set(PACKAGE_VERSION_COMPATIBLE TRUE)
-  if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+  if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
     set(PACKAGE_VERSION_EXACT TRUE)
   endif()
 endif()
 
 # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
-if("${CMAKE_SIZEOF_VOID_P}"  STREQUAL ""  OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
+if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
    return()
 endif()
 
 # check that the installed version has the same 32/64bit-ness as the one which is currently searching:
-if(NOT "${CMAKE_SIZEOF_VOID_P}"  STREQUAL  "@CMAKE_SIZEOF_VOID_P@")
+if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@")
    math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
    set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
    set(PACKAGE_VERSION_UNSUITABLE TRUE)
diff --git a/Modules/BasicConfigVersion-ExactVersion.cmake.in b/Modules/BasicConfigVersion-ExactVersion.cmake.in
index 9fd0136..de4a23a 100644
--- a/Modules/BasicConfigVersion-ExactVersion.cmake.in
+++ b/Modules/BasicConfigVersion-ExactVersion.cmake.in
@@ -17,30 +17,30 @@ else()
   set(CVF_VERSION_NO_TWEAK "@CVF_VERSION@")
 endif()
 
-if("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+\\.[0-9]+\\.[0-9]+)\\.") # strip the tweak version
+if(PACKAGE_FIND_VERSION MATCHES "^([0-9]+\\.[0-9]+\\.[0-9]+)\\.") # strip the tweak version
   set(REQUESTED_VERSION_NO_TWEAK "${CMAKE_MATCH_1}")
 else()
   set(REQUESTED_VERSION_NO_TWEAK "${PACKAGE_FIND_VERSION}")
 endif()
 
-if("${REQUESTED_VERSION_NO_TWEAK}" STREQUAL "${CVF_VERSION_NO_TWEAK}")
+if(REQUESTED_VERSION_NO_TWEAK STREQUAL CVF_VERSION_NO_TWEAK)
   set(PACKAGE_VERSION_COMPATIBLE TRUE)
 else()
   set(PACKAGE_VERSION_COMPATIBLE FALSE)
 endif()
 
-if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
   set(PACKAGE_VERSION_EXACT TRUE)
 endif()
 
 
 # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
-if("${CMAKE_SIZEOF_VOID_P}"  STREQUAL ""  OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
+if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
    return()
 endif()
 
 # check that the installed version has the same 32/64bit-ness as the one which is currently searching:
-if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@")
+if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@")
   math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
   set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
   set(PACKAGE_VERSION_UNSUITABLE TRUE)
diff --git a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in
index 4acd9bb..a32245d 100644
--- a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in
+++ b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in
@@ -11,7 +11,7 @@
 
 set(PACKAGE_VERSION "@CVF_VERSION@")
 
-if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
   set(PACKAGE_VERSION_COMPATIBLE FALSE)
 else()
 
@@ -21,25 +21,25 @@ else()
     set(CVF_VERSION_MAJOR "@CVF_VERSION@")
   endif()
 
-  if("${PACKAGE_FIND_VERSION_MAJOR}" STREQUAL "${CVF_VERSION_MAJOR}")
+  if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR)
     set(PACKAGE_VERSION_COMPATIBLE TRUE)
   else()
     set(PACKAGE_VERSION_COMPATIBLE FALSE)
   endif()
 
-  if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+  if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
       set(PACKAGE_VERSION_EXACT TRUE)
   endif()
 endif()
 
 
 # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
-if("${CMAKE_SIZEOF_VOID_P}"  STREQUAL ""  OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
+if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
    return()
 endif()
 
 # check that the installed version has the same 32/64bit-ness as the one which is currently searching:
-if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@")
+if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@")
   math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
   set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
   set(PACKAGE_VERSION_UNSUITABLE TRUE)
diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake
index 62ef972..0e547c4 100644
--- a/Modules/CMakeASMInformation.cmake
+++ b/Modules/CMakeASMInformation.cmake
@@ -108,7 +108,7 @@ mark_as_advanced(CMAKE_ASM${ASM_DIALECT}_FLAGS
 
 
 if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT)
-  set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+  set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 endif()
 
 if(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY)
diff --git a/Modules/CMakeASM_MASMInformation.cmake b/Modules/CMakeASM_MASMInformation.cmake
index 972883c..bd76b98 100644
--- a/Modules/CMakeASM_MASMInformation.cmake
+++ b/Modules/CMakeASM_MASMInformation.cmake
@@ -18,7 +18,7 @@ set(ASM_DIALECT "_MASM")
 
 set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm)
 
-set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <FLAGS> /c  /Fo <OBJECT> <SOURCE>")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /c  /Fo <OBJECT> <SOURCE>")
 
 include(CMakeASMInformation)
 set(ASM_DIALECT)
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index 86cd894..a1bfc70 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -2,6 +2,8 @@ set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@")
 set(CMAKE_C_COMPILER_ARG1 "@CMAKE_C_COMPILER_ARG1@")
 set(CMAKE_C_COMPILER_ID "@CMAKE_C_COMPILER_ID@")
 set(CMAKE_C_COMPILER_VERSION "@CMAKE_C_COMPILER_VERSION@")
+set(CMAKE_C_COMPILER_LINKS_STATICALLY "@CMAKE_C_COMPILER_LINKS_STATICALLY@")
+set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "@CMAKE_C_STANDARD_COMPUTED_DEFAULT@")
 set(CMAKE_C_COMPILE_FEATURES "@CMAKE_C_COMPILE_FEATURES@")
 set(CMAKE_C90_COMPILE_FEATURES "@CMAKE_C90_COMPILE_FEATURES@")
 set(CMAKE_C99_COMPILE_FEATURES "@CMAKE_C99_COMPILE_FEATURES@")
@@ -52,12 +54,14 @@ if(CMAKE_C_LIBRARY_ARCHITECTURE)
   set(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_C_LIBRARY_ARCHITECTURE@")
 endif()
 
+set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "@CMAKE_C_CL_SHOWINCLUDES_PREFIX@")
+if(CMAKE_C_CL_SHOWINCLUDES_PREFIX)
+  set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}")
+endif()
+
 @CMAKE_C_SYSROOT_FLAG_CODE@
 @CMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG_CODE@
 
 set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "@CMAKE_C_IMPLICIT_LINK_LIBRARIES@")
 set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_DIRECTORIES@")
 set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
-
- at SET_CMAKE_CMCLDEPS_EXECUTABLE@
- at SET_CMAKE_CL_SHOWINCLUDES_PREFIX@
diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in
index 09ae509..b224007 100644
--- a/Modules/CMakeCCompilerId.c.in
+++ b/Modules/CMakeCCompilerId.c.in
@@ -24,6 +24,17 @@ char const* qnxnto = "INFO" ":" "qnxnto[]";
 @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
 @CMAKE_C_COMPILER_ID_ERROR_FOR_TEST@
 
+const char* info_language_dialect_default = "INFO" ":" "dialect_default["
+#if !defined(__STDC_VERSION__)
+  "90"
+#elif __STDC_VERSION__ >= 201000L
+  "11"
+#elif __STDC_VERSION__ >= 199901L
+  "99"
+#else
+#endif
+"]";
+
 /*--------------------------------------------------------------------------*/
 
 #ifdef ID_VOID_MAIN
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index 332b26e..0d102a1 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -75,6 +75,10 @@ if(CMAKE_C_SIZEOF_DATA_PTR)
   unset(CMAKE_C_ABI_FILES)
 endif()
 
+if(CMAKE_C_COMPILER_LINKS_STATICALLY)
+  set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+endif()
+
 # This should be included before the _INIT variables are
 # used to initialize the cache.  Since the rule variables
 # have if blocks on them, users can still define them here.
@@ -175,7 +179,7 @@ endif()
 # Create a static archive incrementally for large object file counts.
 # If CMAKE_C_CREATE_STATIC_LIBRARY is set it will override these.
 if(NOT DEFINED CMAKE_C_ARCHIVE_CREATE)
-  set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> cq <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_C_ARCHIVE_APPEND)
   set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
@@ -187,7 +191,7 @@ endif()
 # compile a C file into an object file
 if(NOT CMAKE_C_COMPILE_OBJECT)
   set(CMAKE_C_COMPILE_OBJECT
-    "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -o <OBJECT>   -c <SOURCE>")
+    "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>   -c <SOURCE>")
 endif()
 
 if(NOT CMAKE_C_LINK_EXECUTABLE)
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index af79a31..4218a6d 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -2,6 +2,8 @@ set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
 set(CMAKE_CXX_COMPILER_ARG1 "@CMAKE_CXX_COMPILER_ARG1@")
 set(CMAKE_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@")
 set(CMAKE_CXX_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@")
+set(CMAKE_CXX_COMPILER_LINKS_STATICALLY "@CMAKE_CXX_COMPILER_LINKS_STATICALLY@")
+set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "@CMAKE_CXX_STANDARD_COMPUTED_DEFAULT@")
 set(CMAKE_CXX_COMPILE_FEATURES "@CMAKE_CXX_COMPILE_FEATURES@")
 set(CMAKE_CXX98_COMPILE_FEATURES "@CMAKE_CXX98_COMPILE_FEATURES@")
 set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
@@ -53,12 +55,14 @@ if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
   set(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_CXX_LIBRARY_ARCHITECTURE@")
 endif()
 
+set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "@CMAKE_CXX_CL_SHOWINCLUDES_PREFIX@")
+if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
+  set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
+endif()
+
 @CMAKE_CXX_SYSROOT_FLAG_CODE@
 @CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG_CODE@
 
 set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "@CMAKE_CXX_IMPLICIT_LINK_LIBRARIES@")
 set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@")
 set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
-
- at SET_CMAKE_CMCLDEPS_EXECUTABLE@
- at SET_CMAKE_CL_SHOWINCLUDES_PREFIX@
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
index cc3ab49..d467507 100644
--- a/Modules/CMakeCXXCompilerId.cpp.in
+++ b/Modules/CMakeCXXCompilerId.cpp.in
@@ -23,6 +23,16 @@ char const* qnxnto = "INFO" ":" "qnxnto[]";
 @CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
 @CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST@
 
+const char* info_language_dialect_default = "INFO" ":" "dialect_default["
+#if __cplusplus >= 201402L
+  "14"
+#elif __cplusplus >= 201103L
+  "11"
+#else
+  "98"
+#endif
+"]";
+
 /*--------------------------------------------------------------------------*/
 
 int main(int argc, char* argv[])
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
index 72b2857..dad7969 100644
--- a/Modules/CMakeCXXInformation.cmake
+++ b/Modules/CMakeCXXInformation.cmake
@@ -74,6 +74,10 @@ if(CMAKE_CXX_SIZEOF_DATA_PTR)
   unset(CMAKE_CXX_ABI_FILES)
 endif()
 
+if(CMAKE_CXX_COMPILER_LINKS_STATICALLY)
+  set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+endif()
+
 # This should be included before the _INIT variables are
 # used to initialize the cache.  Since the rule variables
 # have if blocks on them, users can still define them here.
@@ -266,7 +270,7 @@ endif()
 # Create a static archive incrementally for large object file counts.
 # If CMAKE_CXX_CREATE_STATIC_LIBRARY is set it will override these.
 if(NOT DEFINED CMAKE_CXX_ARCHIVE_CREATE)
-  set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> cq <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_CXX_ARCHIVE_APPEND)
   set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
@@ -278,7 +282,7 @@ endif()
 # compile a C++ file into an object file
 if(NOT CMAKE_CXX_COMPILE_OBJECT)
   set(CMAKE_CXX_COMPILE_OBJECT
-    "<CMAKE_CXX_COMPILER>  <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+    "<CMAKE_CXX_COMPILER>  <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 endif()
 
 if(NOT CMAKE_CXX_LINK_EXECUTABLE)
diff --git a/Modules/CMakeClDeps.cmake b/Modules/CMakeClDeps.cmake
deleted file mode 100644
index b46e7c2..0000000
--- a/Modules/CMakeClDeps.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-
-#=============================================================================
-# Copyright 2012 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-#
-# When using Ninja cl.exe is wrapped by cmcldeps to extract the included
-# headers for dependency tracking.
-#
-# cmcldeps path is set, and cmcldeps needs to know the localized string
-# in front of each include path, so it can remove it.
-#
-
-if(CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPILER AND CMAKE_COMMAND)
-  string(REPLACE "cmake.exe" "cmcldeps.exe"  CMAKE_CMCLDEPS_EXECUTABLE ${CMAKE_COMMAND})
-  set(showdir ${CMAKE_BINARY_DIR}/CMakeFiles/ShowIncludes)
-  file(WRITE ${showdir}/foo.h "\n")
-  file(WRITE ${showdir}/main.c "#include \"foo.h\" \nint main(){}\n")
-  execute_process(COMMAND ${CMAKE_C_COMPILER} /nologo /showIncludes ${showdir}/main.c
-                  WORKING_DIRECTORY ${showdir} OUTPUT_VARIABLE outLine)
-  string(REGEX MATCH "\n([^:]*:[^:]*:[ \t]*)" tmp "${outLine}")
-  set(localizedPrefix "${CMAKE_MATCH_1}")
-  set(SET_CMAKE_CMCLDEPS_EXECUTABLE   "set(CMAKE_CMCLDEPS_EXECUTABLE \"${CMAKE_CMCLDEPS_EXECUTABLE}\")")
-  set(SET_CMAKE_CL_SHOWINCLUDES_PREFIX "set(CMAKE_CL_SHOWINCLUDES_PREFIX \"${localizedPrefix}\")")
-endif()
diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake
index db477cb..e0b5468 100644
--- a/Modules/CMakeDetermineCCompiler.cmake
+++ b/Modules/CMakeDetermineCCompiler.cmake
@@ -80,6 +80,7 @@ else()
   # Each entry in this list is a set of extra flags to try
   # adding to the compile line to see if it helps produce
   # a valid identification file.
+  set(CMAKE_C_COMPILER_ID_TEST_FLAGS_FIRST)
   set(CMAKE_C_COMPILER_ID_TEST_FLAGS
     # Try compiling to an object file only.
     "-c"
@@ -100,11 +101,19 @@ if(NOT CMAKE_C_COMPILER_ID_RUN)
     CMAKE_C_COMPILER_ID_PLATFORM_CONTENT)
 
   # The IAR compiler produces weird output.
-  # See http://www.cmake.org/Bug/view.php?id=10176#c19598
+  # See https://cmake.org/Bug/view.php?id=10176#c19598
   list(APPEND CMAKE_C_COMPILER_ID_VENDORS IAR)
   set(CMAKE_C_COMPILER_ID_VENDOR_FLAGS_IAR )
   set(CMAKE_C_COMPILER_ID_VENDOR_REGEX_IAR "IAR .+ Compiler")
 
+  # Match the link line from xcodebuild output of the form
+  #  Ld ...
+  #      ...
+  #      /path/to/cc ...CompilerIdC/...
+  # to extract the compiler front-end for the language.
+  set(CMAKE_C_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdC/(\\./)?(CompilerIdC.xctest/)?CompilerIdC[ \t\n\\\"]")
+  set(CMAKE_C_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
   include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
   CMAKE_DETERMINE_COMPILER_ID(C CFLAGS CMakeCCompilerId.c)
 
@@ -164,7 +173,6 @@ endif ()
 
 include(CMakeFindBinUtils)
 if(MSVC_C_ARCHITECTURE_ID)
-  include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake)
   set(SET_MSVC_C_ARCHITECTURE_ID
     "set(MSVC_C_ARCHITECTURE_ID ${MSVC_C_ARCHITECTURE_ID})")
 endif()
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
index 18e735b..3c9bbc2 100644
--- a/Modules/CMakeDetermineCXXCompiler.cmake
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -78,6 +78,7 @@ else()
   # Each entry in this list is a set of extra flags to try
   # adding to the compile line to see if it helps produce
   # a valid identification file.
+  set(CMAKE_CXX_COMPILER_ID_TEST_FLAGS_FIRST)
   set(CMAKE_CXX_COMPILER_ID_TEST_FLAGS
     # Try compiling to an object file only.
     "-c"
@@ -95,11 +96,19 @@ if(NOT CMAKE_CXX_COMPILER_ID_RUN)
     CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT)
 
   # The IAR compiler produces weird output.
-  # See http://www.cmake.org/Bug/view.php?id=10176#c19598
+  # See https://cmake.org/Bug/view.php?id=10176#c19598
   list(APPEND CMAKE_CXX_COMPILER_ID_VENDORS IAR)
   set(CMAKE_CXX_COMPILER_ID_VENDOR_FLAGS_IAR )
   set(CMAKE_CXX_COMPILER_ID_VENDOR_REGEX_IAR "IAR .+ Compiler")
 
+  # Match the link line from xcodebuild output of the form
+  #  Ld ...
+  #      ...
+  #      /path/to/cc ...CompilerIdCXX/...
+  # to extract the compiler front-end for the language.
+  set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdCXX/(\\./)?(CompilerIdCXX.xctest/)?CompilerIdCXX[ \t\n\\\"]")
+  set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
   include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
   CMAKE_DETERMINE_COMPILER_ID(CXX CXXFLAGS CMakeCXXCompilerId.cpp)
 
@@ -162,7 +171,6 @@ endif ()
 
 include(CMakeFindBinUtils)
 if(MSVC_CXX_ARCHITECTURE_ID)
-  include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake)
   set(SET_MSVC_CXX_ARCHITECTURE_ID
     "set(MSVC_CXX_ARCHITECTURE_ID ${MSVC_CXX_ARCHITECTURE_ID})")
 endif()
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 403ac08..2e74100 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -34,12 +34,19 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
 
   # Try building with no extra flags and then try each set
   # of helper flags.  Stop when the compiler is identified.
-  foreach(flags "" ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS})
-    if(NOT CMAKE_${lang}_COMPILER_ID)
-      CMAKE_DETERMINE_COMPILER_ID_BUILD("${lang}" "${flags}" "${src}")
-      foreach(file ${COMPILER_${lang}_PRODUCED_FILES})
-        CMAKE_DETERMINE_COMPILER_ID_CHECK("${lang}" "${CMAKE_${lang}_COMPILER_ID_DIR}/${file}" "${src}")
-      endforeach()
+  foreach(flags ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS_FIRST}
+                ""
+                ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS})
+    CMAKE_DETERMINE_COMPILER_ID_BUILD("${lang}" "${flags}" "${src}")
+    CMAKE_DETERMINE_COMPILER_ID_MATCH_VENDOR("${lang}" "${COMPILER_${lang}_PRODUCED_OUTPUT}")
+    if(CMAKE_${lang}_COMPILER_ID)
+      break()
+    endif()
+    foreach(file ${COMPILER_${lang}_PRODUCED_FILES})
+      CMAKE_DETERMINE_COMPILER_ID_CHECK("${lang}" "${CMAKE_${lang}_COMPILER_ID_DIR}/${file}" "${src}")
+    endforeach()
+    if(CMAKE_${lang}_COMPILER_ID)
+      break()
     endif()
   endforeach()
 
@@ -68,6 +75,12 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
     set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
   endif()
 
+  if(CMAKE_GENERATOR STREQUAL "Ninja" AND MSVC_${lang}_ARCHITECTURE_ID)
+    CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX(${lang})
+  else()
+    set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "")
+  endif()
+
   # Display the final identification result.
   if(CMAKE_${lang}_COMPILER_ID)
     if(CMAKE_${lang}_COMPILER_VERSION)
@@ -92,9 +105,12 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
   set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
   set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}"
     PARENT_SCOPE)
+  set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "${CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX}" PARENT_SCOPE)
+  set(CMAKE_${lang}_COMPILER_LINKS_STATICALLY "${CMAKE_${lang}_COMPILER_LINKS_STATICALLY}" PARENT_SCOPE)
   set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
   set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
   set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
+  set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT}" PARENT_SCOPE)
 endfunction()
 
 include(CMakeCompilerIdDetection)
@@ -194,6 +210,9 @@ Id flags: ${testflags}
     else()
       set(id_system_version "")
     endif()
+    if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
+      set(id_WindowsTargetPlatformVersion "<WindowsTargetPlatformVersion>${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}</WindowsTargetPlatformVersion>")
+    endif()
     if(id_platform STREQUAL ARM)
       set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>")
     else()
@@ -210,7 +229,7 @@ Id flags: ${testflags}
       set(id_subsystem 1)
     endif()
     set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
-    get_filename_component(id_src "${src}" NAME)
+    set(id_src "${src}")
     configure_file(${CMAKE_ROOT}/Modules/CompilerId/VS-${v}.${ext}.in
       ${id_dir}/CompilerId${lang}.${ext} @ONLY)
     if(CMAKE_VS_MSBUILD_COMMAND AND NOT lang STREQUAL "Fortran")
@@ -249,7 +268,7 @@ Id flags: ${testflags}
     set(id_lang "${lang}")
     set(id_type ${CMAKE_${lang}_COMPILER_XCODE_TYPE})
     set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
-    get_filename_component(id_src "${src}" NAME)
+    set(id_src "${src}")
     if(CMAKE_XCODE_PLATFORM_TOOLSET)
       set(id_toolset "GCC_VERSION = ${CMAKE_XCODE_PLATFORM_TOOLSET};")
     else()
@@ -297,41 +316,26 @@ Id flags: ${testflags}
       set(ENV{MACOSX_DEPLOYMENT_TARGET} "${_ENV_MACOSX_DEPLOYMENT_TARGET}")
     endif()
 
-    # Match the link line from xcodebuild output of the form
-    #  Ld ...
-    #      ...
-    #      /path/to/cc ...CompilerId${lang}/...
-    # to extract the compiler front-end for the language.
-    if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerId${lang}/(\\./)?(CompilerId${lang}.xctest/)?CompilerId${lang}[ \t\n\\\"]")
-      set(_comp "${CMAKE_MATCH_2}")
-      if(EXISTS "${_comp}")
-        set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
+    if(DEFINED CMAKE_${lang}_COMPILER_ID_TOOL_MATCH_REGEX)
+      if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "${CMAKE_${lang}_COMPILER_ID_TOOL_MATCH_REGEX}")
+        set(_comp "${CMAKE_MATCH_${CMAKE_${lang}_COMPILER_ID_TOOL_MATCH_INDEX}}")
+        if(EXISTS "${_comp}")
+          set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
+        endif()
       endif()
     endif()
   else()
-    if(COMMAND EXECUTE_PROCESS)
-      execute_process(
-        COMMAND "${CMAKE_${lang}_COMPILER}"
-                ${CMAKE_${lang}_COMPILER_ID_ARG1}
-                ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
-                ${testflags}
-                "${src}"
-        WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
-        OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
-        ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
-        RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
-        )
-    else()
-      exec_program(
-        "${CMAKE_${lang}_COMPILER}" ${CMAKE_${lang}_COMPILER_ID_DIR}
-        ARGS ${CMAKE_${lang}_COMPILER_ID_ARG1}
-             ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
-             ${testflags}
-             \"${src}\"
-        OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
-        RETURN_VALUE CMAKE_${lang}_COMPILER_ID_RESULT
-        )
-    endif()
+    execute_process(
+      COMMAND "${CMAKE_${lang}_COMPILER}"
+              ${CMAKE_${lang}_COMPILER_ID_ARG1}
+              ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
+              ${testflags}
+              "${src}"
+      WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
+      OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
+      ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
+      RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
+      )
   endif()
 
   # Check the result of compilation.
@@ -355,6 +359,7 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
 
     # No output files should be inspected.
     set(COMPILER_${lang}_PRODUCED_FILES)
+    set(COMPILER_${lang}_PRODUCED_OUTPUT)
   else()
     # Compilation succeeded.
     file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -395,10 +400,24 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
         "${src}\" did not produce an executable in \""
         "${CMAKE_${lang}_COMPILER_ID_DIR}\".\n\n")
     endif()
+
+    set(COMPILER_${lang}_PRODUCED_OUTPUT "${CMAKE_${lang}_COMPILER_ID_OUTPUT}")
   endif()
 
   # Return the files produced by the compilation.
   set(COMPILER_${lang}_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
+  set(COMPILER_${lang}_PRODUCED_OUTPUT "${COMPILER_${lang}_PRODUCED_OUTPUT}" PARENT_SCOPE)
+endfunction()
+
+#-----------------------------------------------------------------------------
+# Function to extract the compiler id from compiler output.
+function(CMAKE_DETERMINE_COMPILER_ID_MATCH_VENDOR lang output)
+  foreach(vendor ${CMAKE_${lang}_COMPILER_ID_MATCH_VENDORS})
+    if(output MATCHES "${CMAKE_${lang}_COMPILER_ID_MATCH_VENDOR_REGEX_${vendor}}")
+      set(CMAKE_${lang}_COMPILER_ID "${vendor}")
+    endif()
+  endforeach()
+  set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
 endfunction()
 
 #-----------------------------------------------------------------------------
@@ -468,6 +487,9 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
       if("${info}" MATCHES "INFO:qnxnto\\[\\]")
         set(COMPILER_QNXNTO 1)
       endif()
+      if("${info}" MATCHES "INFO:dialect_default\\[([^]\"]*)\\]")
+        set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_MATCH_1}")
+      endif()
     endforeach()
 
     # Construct compiler version from components if needed.
@@ -511,6 +533,13 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
       endif()
     endif()
 
+    if(UNIX)
+      execute_process(COMMAND file "${file}" OUTPUT_VARIABLE out ERROR_VARIABLE out)
+      if(out MATCHES "statically linked")
+        set(CMAKE_${lang}_COMPILER_LINKS_STATICALLY 1 PARENT_SCOPE)
+      endif()
+    endif()
+
     # Check if a valid compiler and platform were found.
     if(COMPILER_ID AND NOT COMPILER_ID_TWICE)
       set(CMAKE_${lang}_COMPILER_ID "${COMPILER_ID}")
@@ -571,6 +600,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
   set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
   set(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE)
   set(COMPILER_QNXNTO "${COMPILER_QNXNTO}" PARENT_SCOPE)
+  set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT}" PARENT_SCOPE)
 endfunction()
 
 #-----------------------------------------------------------------------------
@@ -626,3 +656,27 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang)
     endif()
   endforeach()
 endfunction()
+
+function(CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX lang)
+  # Run this MSVC-compatible compiler to detect what the /showIncludes
+  # option displays.  We can use a C source even with the C++ compiler
+  # because MSVC-compatible compilers handle both and show the same output.
+  set(showdir ${CMAKE_BINARY_DIR}/CMakeFiles/ShowIncludes)
+  file(WRITE ${showdir}/foo.h "\n")
+  file(WRITE ${showdir}/main.c "#include \"foo.h\" \nint main(){}\n")
+  execute_process(
+    COMMAND "${CMAKE_${lang}_COMPILER}"
+            ${CMAKE_${lang}_COMPILER_ID_ARG1}
+            ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
+            /nologo /showIncludes /c main.c
+    WORKING_DIRECTORY ${showdir}
+    OUTPUT_VARIABLE out
+    ERROR_VARIABLE err
+    RESULT_VARIABLE res
+    )
+  if(res EQUAL 0 AND "${out}" MATCHES "\n([^:]*:[^:]*:[ \t]*)")
+    set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "${CMAKE_MATCH_1}" PARENT_SCOPE)
+  else()
+    set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "" PARENT_SCOPE)
+  endif()
+endfunction()
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
index 3a27127..911ffac 100644
--- a/Modules/CMakeDetermineFortranCompiler.cmake
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -98,6 +98,10 @@ else()
   # Each entry in this list is a set of extra flags to try
   # adding to the compile line to see if it helps produce
   # a valid identification executable.
+  set(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS_FIRST
+    # Get verbose output to help distinguish compilers.
+    "-v"
+    )
   set(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS
     # Try compiling to an object file only.
     "-c"
@@ -111,6 +115,10 @@ endif()
 if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
   set(CMAKE_Fortran_COMPILER_ID_RUN 1)
 
+  # Table of per-vendor compiler output regular expressions.
+  list(APPEND CMAKE_Fortran_COMPILER_ID_MATCH_VENDORS CCur)
+  set(CMAKE_Fortran_COMPILER_ID_MATCH_VENDOR_REGEX_CCur "Concurrent Fortran [0-9]+ Compiler")
+
   # Table of per-vendor compiler id flags with expected output.
   list(APPEND CMAKE_Fortran_COMPILER_ID_VENDORS Compaq)
   set(CMAKE_Fortran_COMPILER_ID_VENDOR_FLAGS_Compaq "-what")
@@ -119,6 +127,14 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
   set(CMAKE_Fortran_COMPILER_ID_VENDOR_FLAGS_NAG "-V")
   set(CMAKE_Fortran_COMPILER_ID_VENDOR_REGEX_NAG "NAG Fortran Compiler")
 
+  # Match the link line from xcodebuild output of the form
+  #  Ld ...
+  #      ...
+  #      /path/to/cc ...CompilerIdFortran/...
+  # to extract the compiler front-end for the language.
+  set(CMAKE_Fortran_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdFortran/(\\./)?(CompilerIdFortran.xctest/)?CompilerIdFortran[ \t\n\\\"]")
+  set(CMAKE_Fortran_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
   set(_version_info "")
   foreach(m MAJOR MINOR PATCH TWEAK)
     set(_COMP "_${m}")
diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake
new file mode 100644
index 0000000..bff1ae9
--- /dev/null
+++ b/Modules/CMakeDetermineSwiftCompiler.cmake
@@ -0,0 +1,53 @@
+
+#=============================================================================
+# Copyright 2002-2015 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
+
+if("${CMAKE_GENERATOR}" STREQUAL "Xcode")
+  if(XCODE_VERSION VERSION_LESS 6.1)
+    message(FATAL_ERROR "Swift language not supported by Xcode ${XCODE_VERSION}")
+  endif()
+  set(CMAKE_Swift_COMPILER_XCODE_TYPE sourcecode.swift)
+  _cmake_find_compiler_path(Swift)
+else()
+  message(FATAL_ERROR "Swift language not supported by \"${CMAKE_GENERATOR}\" generator")
+endif()
+
+# Build a small source file to identify the compiler.
+if(NOT CMAKE_Swift_COMPILER_ID_RUN)
+  set(CMAKE_Swift_COMPILER_ID_RUN 1)
+
+  list(APPEND CMAKE_Swift_COMPILER_ID_MATCH_VENDORS Apple)
+  set(CMAKE_Swift_COMPILER_ID_MATCH_VENDOR_REGEX_Apple "com.apple.xcode.tools.swift.compiler")
+
+  set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_REGEX "\nCompileSwiftSources[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]* -c[^\r\n]*CompilerIdSwift/CompilerId/main.swift")
+  set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
+  # Try to identify the compiler.
+  set(CMAKE_Swift_COMPILER_ID)
+  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
+  CMAKE_DETERMINE_COMPILER_ID(Swift "" CompilerId/main.swift)
+endif()
+
+if (NOT _CMAKE_TOOLCHAIN_LOCATION)
+  get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_Swift_COMPILER}" PATH)
+endif ()
+
+include(CMakeFindBinUtils)
+
+# configure variables set in this file for fast reload later on
+configure_file(${CMAKE_ROOT}/Modules/CMakeSwiftCompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake
+  @ONLY
+  )
diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake
index fa14641..d9f7579 100644
--- a/Modules/CMakeDetermineSystem.cmake
+++ b/Modules/CMakeDetermineSystem.cmake
@@ -123,7 +123,9 @@ elseif(CMAKE_VS_WINCE_VERSION)
   set(PRESET_CMAKE_SYSTEM_NAME TRUE)
 else()
   set(CMAKE_SYSTEM_NAME      "${CMAKE_HOST_SYSTEM_NAME}")
-  set(CMAKE_SYSTEM_VERSION   "${CMAKE_HOST_SYSTEM_VERSION}")
+  if(NOT DEFINED CMAKE_SYSTEM_VERSION)
+    set(CMAKE_SYSTEM_VERSION "${CMAKE_HOST_SYSTEM_VERSION}")
+  endif()
   set(CMAKE_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR}")
   set(CMAKE_CROSSCOMPILING FALSE)
   set(PRESET_CMAKE_SYSTEM_NAME FALSE)
diff --git a/Modules/CMakeExpandImportedTargets.cmake b/Modules/CMakeExpandImportedTargets.cmake
index 8ac3364..28f2e46 100644
--- a/Modules/CMakeExpandImportedTargets.cmake
+++ b/Modules/CMakeExpandImportedTargets.cmake
@@ -2,6 +2,19 @@
 # CMakeExpandImportedTargets
 # --------------------------
 #
+# Deprecated.  Do not use.
+#
+# This module was once needed to expand imported targets to the underlying
+# libraries they reference on disk for use with the :command:`try_compile`
+# and :command:`try_run` commands.  These commands now support imported
+# libraries in their ``LINK_LIBRARIES`` options (since CMake 2.8.11
+# for :command:`try_compile` and since CMake 3.2 for :command:`try_run`).
+#
+# This module does not support the policy :policy:`CMP0022` ``NEW``
+# behavior or use of the :prop_tgt:`INTERFACE_LINK_LIBRARIES` property
+# because :manual:`generator expressions <cmake-generator-expressions(7)>`
+# cannot be evaluated during configuration.
+#
 # ::
 #
 #  CMAKE_EXPAND_IMPORTED_TARGETS(<var> LIBRARIES lib1 lib2...libN
@@ -14,9 +27,6 @@
 # respective configuration of the imported targets if it exists.  If no
 # CONFIGURATION is given, it uses the first configuration from
 # ${CMAKE_CONFIGURATION_TYPES} if set, otherwise ${CMAKE_BUILD_TYPE}.
-# This macro is used by all Check*.cmake files which use try_compile()
-# or try_run() and support CMAKE_REQUIRED_LIBRARIES , so that these
-# checks support imported targets in CMAKE_REQUIRED_LIBRARIES:
 #
 # ::
 #
diff --git a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake
index 064e650..3bfb876 100644
--- a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake
+++ b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake
@@ -101,6 +101,8 @@ if (NOT CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS)
     _DETERMINE_GCC_SYSTEM_INCLUDE_DIRS(c _dirs _defines)
     set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS "${_dirs}" CACHE INTERNAL "C compiler system include directories")
     set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS "${_defines}" CACHE INTERNAL "C compiler system defined macros")
+  elseif ("${CMAKE_C_COMPILER_ID}" MATCHES MSVC)
+    set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS "$ENV{INCLUDE}" CACHE INTERNAL "C compiler system include directories")
   endif ()
 endif ()
 
@@ -110,6 +112,8 @@ if (NOT CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS)
     _DETERMINE_GCC_SYSTEM_INCLUDE_DIRS(c++ _dirs _defines)
     set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS "${_dirs}" CACHE INTERNAL "CXX compiler system include directories")
     set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS "${_defines}" CACHE INTERNAL "CXX compiler system defined macros")
+  elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES MSVC)
+    set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS "$ENV{INCLUDE}" CACHE INTERNAL "CXX compiler system include directories")
   endif ()
 endif ()
 
diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in
index 14fdd60..6b984e5 100644
--- a/Modules/CMakeFortranCompiler.cmake.in
+++ b/Modules/CMakeFortranCompiler.cmake.in
@@ -2,6 +2,7 @@ set(CMAKE_Fortran_COMPILER "@CMAKE_Fortran_COMPILER@")
 set(CMAKE_Fortran_COMPILER_ARG1 "@CMAKE_Fortran_COMPILER_ARG1@")
 set(CMAKE_Fortran_COMPILER_ID "@CMAKE_Fortran_COMPILER_ID@")
 set(CMAKE_Fortran_COMPILER_VERSION "@CMAKE_Fortran_COMPILER_VERSION@")
+set(CMAKE_Fortran_COMPILER_LINKS_STATICALLY "@CMAKE_Fortran_COMPILER_LINKS_STATICALLY@")
 set(CMAKE_Fortran_PLATFORM_ID "@CMAKE_Fortran_PLATFORM_ID@")
 set(CMAKE_Fortran_SIMULATE_ID "@CMAKE_Fortran_SIMULATE_ID@")
 set(CMAKE_Fortran_SIMULATE_VERSION "@CMAKE_Fortran_SIMULATE_VERSION@")
diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in
index 2533d3f..017af91 100644
--- a/Modules/CMakeFortranCompilerId.F.in
+++ b/Modules/CMakeFortranCompilerId.F.in
@@ -17,7 +17,9 @@
 
 # if defined(_MSC_VER)
         PRINT *, 'INFO:simulate[MSVC]'
-#  if _MSC_VER >= 1800
+#  if _MSC_VER >= 1900
+        PRINT *, 'INFO:simulate_version[019.00]'
+#  elif _MSC_VER >= 1800
         PRINT *, 'INFO:simulate_version[018.00]'
 #  elif _MSC_VER >= 1700
         PRINT *, 'INFO:simulate_version[017.00]'
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake
index d638207..aa48df7 100644
--- a/Modules/CMakeFortranInformation.cmake
+++ b/Modules/CMakeFortranInformation.cmake
@@ -51,6 +51,10 @@ if(CMAKE_Fortran_SIZEOF_DATA_PTR)
   unset(CMAKE_Fortran_ABI_FILES)
 endif()
 
+if(CMAKE_Fortran_COMPILER_LINKS_STATICALLY)
+  set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+endif()
+
 # This should be included before the _INIT variables are
 # used to initialize the cache.  Since the rule variables
 # have if blocks on them, users can still define them here.
@@ -194,7 +198,7 @@ endif()
 # Create a static archive incrementally for large object file counts.
 # If CMAKE_Fortran_CREATE_STATIC_LIBRARY is set it will override these.
 if(NOT DEFINED CMAKE_Fortran_ARCHIVE_CREATE)
-  set(CMAKE_Fortran_ARCHIVE_CREATE "<CMAKE_AR> cq <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_Fortran_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_Fortran_ARCHIVE_APPEND)
   set(CMAKE_Fortran_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
@@ -207,7 +211,7 @@ endif()
 # (put -o after -c to workaround bug in at least one mpif77 wrapper)
 if(NOT CMAKE_Fortran_COMPILE_OBJECT)
   set(CMAKE_Fortran_COMPILE_OBJECT
-    "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -c <SOURCE> -o <OBJECT>")
+    "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -c <SOURCE> -o <OBJECT>")
 endif()
 
 # link a fortran program
diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
index 8a14aea..5ae757d 100644
--- a/Modules/CMakeGenericSystem.cmake
+++ b/Modules/CMakeGenericSystem.cmake
@@ -44,7 +44,7 @@ set (CMAKE_SKIP_INSTALL_RPATH "NO" CACHE BOOL
 
 set(CMAKE_VERBOSE_MAKEFILE FALSE CACHE BOOL "If this value is on, makefiles will be generated without the .SILENT directive, and all commands will be echoed to the console during the make.  This is useful for debugging only. With Visual Studio IDE projects all commands are done without /nologo.")
 
-if(CMAKE_GENERATOR MATCHES "Makefiles")
+if(CMAKE_GENERATOR MATCHES "Make")
   set(CMAKE_COLOR_MAKEFILE ON CACHE BOOL
     "Enable/Disable color output during build."
     )
@@ -52,6 +52,9 @@ if(CMAKE_GENERATOR MATCHES "Makefiles")
   if(DEFINED CMAKE_RULE_MESSAGES)
     set_property(GLOBAL PROPERTY RULE_MESSAGES ${CMAKE_RULE_MESSAGES})
   endif()
+  if(DEFINED CMAKE_TARGET_MESSAGES)
+    set_property(GLOBAL PROPERTY TARGET_MESSAGES ${CMAKE_TARGET_MESSAGES})
+  endif()
   if(CMAKE_GENERATOR MATCHES "Unix Makefiles")
     set(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
       "Enable/Disable output of compile commands during generation."
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake
index 8abc465..59092bd 100644
--- a/Modules/CMakeParseImplicitLinkInfo.cmake
+++ b/Modules/CMakeParseImplicitLinkInfo.cmake
@@ -31,7 +31,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj
   # Construct a regex to match linker lines.  It must match both the
   # whole line and just the command (argv[0]).
   set(linker_regex "^( *|.*[/\\])(${linker}|([^/\\]+-)?ld|collect2)[^/\\]*( |$)")
-  set(linker_exclude_regex "collect2 version ")
+  set(linker_exclude_regex "collect2 version |^[A-Za-z0-9_]+=")
   set(log "${log}  link line regex: [${linker_regex}]\n")
   string(REGEX REPLACE "\r?\n" ";" output_lines "${text}")
   foreach(line IN LISTS output_lines)
diff --git a/Modules/CMakeRCInformation.cmake b/Modules/CMakeRCInformation.cmake
index 6bb2636..94abd4b 100644
--- a/Modules/CMakeRCInformation.cmake
+++ b/Modules/CMakeRCInformation.cmake
@@ -44,7 +44,7 @@ set(CMAKE_INCLUDE_FLAG_RC "-I")
 # compile a Resource file into an object file
 if(NOT CMAKE_RC_COMPILE_OBJECT)
   set(CMAKE_RC_COMPILE_OBJECT
-    "<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> /fo<OBJECT> <SOURCE>")
+    "<CMAKE_RC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /fo<OBJECT> <SOURCE>")
 endif()
 
 mark_as_advanced(
diff --git a/Modules/CMakeSwiftCompiler.cmake.in b/Modules/CMakeSwiftCompiler.cmake.in
new file mode 100644
index 0000000..45f0a31
--- /dev/null
+++ b/Modules/CMakeSwiftCompiler.cmake.in
@@ -0,0 +1,5 @@
+set(CMAKE_Swift_COMPILER "@CMAKE_Swift_COMPILER@")
+set(CMAKE_Swift_COMPILER_ID "@CMAKE_Swift_COMPILER_ID@")
+
+set(CMAKE_Swift_COMPILER_ID_RUN 1)
+set(CMAKE_Swift_SOURCE_FILE_EXTENSIONS swift)
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
new file mode 100644
index 0000000..61ad928
--- /dev/null
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -0,0 +1,41 @@
+
+#=============================================================================
+# Copyright 2004-2015 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+set(CMAKE_Swift_OUTPUT_EXTENSION .o)
+
+# Load compiler-specific information.
+if(CMAKE_Swift_COMPILER_ID)
+  include(Compiler/${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
+endif()
+
+# load the system- and compiler specific files
+if(CMAKE_Swift_COMPILER_ID)
+  # load a hardware specific file, mostly useful for embedded compilers
+  if(CMAKE_SYSTEM_PROCESSOR)
+    include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+  endif()
+  include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
+endif()
+
+# for most systems a module is the same as a shared library
+# so unless the variable CMAKE_MODULE_EXISTS is set just
+# copy the values from the LIBRARY variables
+if(NOT CMAKE_MODULE_EXISTS)
+  set(CMAKE_SHARED_MODULE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_Swift_FLAGS})
+  set(CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_Swift_FLAGS})
+endif()
+
+include(CMakeCommonLanguageInclude)
+
+set(CMAKE_Swift_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake
new file mode 100644
index 0000000..89849fb
--- /dev/null
+++ b/Modules/CMakeTestSwiftCompiler.cmake
@@ -0,0 +1,65 @@
+
+#=============================================================================
+# Copyright 2003-2015 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+if(CMAKE_Swift_COMPILER_FORCED)
+  # The compiler configuration was forced by the user.
+  # Assume the user has configured all compiler information.
+  set(CMAKE_Swift_COMPILER_WORKS TRUE)
+  return()
+endif()
+
+include(CMakeTestCompilerCommon)
+
+# Remove any cached result from an older CMake version.
+# We now store this in CMakeSwiftCompiler.cmake.
+unset(CMAKE_Swift_COMPILER_WORKS CACHE)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that that selected C++ compiler can actually compile
+# and link the most basic of programs.   If not, a fatal error
+# is set and cmake stops processing commands and will not generate
+# any makefiles or projects.
+if(NOT CMAKE_Swift_COMPILER_WORKS)
+  PrintTestCompilerStatus("Swift" "")
+  file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
+    "import Foundation\n"
+    "print(\"CMake\")\n")
+  try_compile(CMAKE_Swift_COMPILER_WORKS ${CMAKE_BINARY_DIR}
+    ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
+    OUTPUT_VARIABLE __CMAKE_Swift_COMPILER_OUTPUT)
+  # Move result from cache to normal variable.
+  set(CMAKE_Swift_COMPILER_WORKS ${CMAKE_Swift_COMPILER_WORKS})
+  unset(CMAKE_Swift_COMPILER_WORKS CACHE)
+  set(Swift_TEST_WAS_RUN 1)
+endif()
+
+if(NOT CMAKE_Swift_COMPILER_WORKS)
+  PrintTestCompilerStatus("Swift" " -- broken")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    "Determining if the Swift compiler works failed with "
+    "the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
+  message(FATAL_ERROR "The Swift compiler \"${CMAKE_Swift_COMPILER}\" "
+    "is not able to compile a simple test program.\nIt fails "
+    "with the following output:\n ${__CMAKE_Swift_COMPILER_OUTPUT}\n\n"
+    "CMake will not be able to correctly generate this project.")
+else()
+  if(Swift_TEST_WAS_RUN)
+    PrintTestCompilerStatus("Swift" " -- works")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "Determining if the Swift compiler works passed with "
+      "the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
+  endif()
+endif()
+
+unset(__CMAKE_Swift_COMPILER_OUTPUT)
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index e223286..5756001 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -182,6 +182,17 @@
 #  will be a boolean variable which enables stripping of all files (a list
 #  of files evaluates to TRUE in CMake, so this change is compatible).
 #
+# .. variable:: CPACK_VERBATIM_VARIABLES
+#
+#  If set to TRUE, values of variables prefixed with CPACK_ will be escaped
+#  before being written to the configuration files, so that the cpack program
+#  receives them exactly as they were specified. If not, characters like quotes
+#  and backslashes can cause parsing errors or alter the value received by the
+#  cpack program. Defaults to FALSE for backwards compatibility.
+#
+#  * Mandatory : NO
+#  * Default   : FALSE
+#
 # The following CPack variables are specific to source packages, and
 # will not affect binary packages:
 #
@@ -299,49 +310,68 @@ endif()
 include(CPackComponent)
 
 # Macro for setting values if a user did not overwrite them
+# Mangles CMake-special characters. Only kept for backwards compatibility.
 macro(cpack_set_if_not_set name value)
-  if(NOT DEFINED "${name}")
-    set(${name} "${value}")
-  endif()
+  message(DEPRECATION "cpack_set_if_not_set is obsolete; do not use.")
+  _cpack_set_default("${name}" "${value}")
 endmacro()
 
-# cpack_encode_variables - Macro to encode variables for the configuration file
+# cpack_encode_variables - Function to encode variables for the configuration file
 # find any variable that starts with CPACK and create a variable
 # _CPACK_OTHER_VARIABLES_ that contains SET commands for
 # each cpack variable.  _CPACK_OTHER_VARIABLES_ is then
 # used as an @ replacment in configure_file for the CPackConfig.
-macro(cpack_encode_variables)
-  set(_CPACK_OTHER_VARIABLES_)
+function(cpack_encode_variables)
+  set(commands "")
   get_cmake_property(res VARIABLES)
   foreach(var ${res})
     if(var MATCHES "^CPACK")
-      set(_CPACK_OTHER_VARIABLES_
-        "${_CPACK_OTHER_VARIABLES_}\nSET(${var} \"${${var}}\")")
+      if(CPACK_VERBATIM_VARIABLES)
+        _cpack_escape_for_cmake(value "${${var}}")
+      else()
+        set(value "${${var}}")
       endif()
+
+      set(commands "${commands}\nSET(${var} \"${value}\")")
+    endif()
   endforeach()
-endmacro()
+
+  set(_CPACK_OTHER_VARIABLES_ "${commands}" PARENT_SCOPE)
+endfunction()
+
+# Internal use functions
+function(_cpack_set_default name value)
+  if(NOT DEFINED "${name}")
+    set("${name}" "${value}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+function(_cpack_escape_for_cmake var value)
+  string(REGEX REPLACE "([\\\$\"])" "\\\\\\1" escaped "${value}")
+  set("${var}" "${escaped}" PARENT_SCOPE)
+endfunction()
 
 # Set the package name
-cpack_set_if_not_set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
-cpack_set_if_not_set(CPACK_PACKAGE_VERSION_MAJOR "0")
-cpack_set_if_not_set(CPACK_PACKAGE_VERSION_MINOR "1")
-cpack_set_if_not_set(CPACK_PACKAGE_VERSION_PATCH "1")
-cpack_set_if_not_set(CPACK_PACKAGE_VERSION
+_cpack_set_default(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
+_cpack_set_default(CPACK_PACKAGE_VERSION_MAJOR "0")
+_cpack_set_default(CPACK_PACKAGE_VERSION_MINOR "1")
+_cpack_set_default(CPACK_PACKAGE_VERSION_PATCH "1")
+_cpack_set_default(CPACK_PACKAGE_VERSION
   "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
-cpack_set_if_not_set(CPACK_PACKAGE_VENDOR "Humanity")
-cpack_set_if_not_set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
+_cpack_set_default(CPACK_PACKAGE_VENDOR "Humanity")
+_cpack_set_default(CPACK_PACKAGE_DESCRIPTION_SUMMARY
   "${CMAKE_PROJECT_NAME} built using CMake")
 
-cpack_set_if_not_set(CPACK_PACKAGE_DESCRIPTION_FILE
+_cpack_set_default(CPACK_PACKAGE_DESCRIPTION_FILE
   "${CMAKE_ROOT}/Templates/CPack.GenericDescription.txt")
-cpack_set_if_not_set(CPACK_RESOURCE_FILE_LICENSE
+_cpack_set_default(CPACK_RESOURCE_FILE_LICENSE
   "${CMAKE_ROOT}/Templates/CPack.GenericLicense.txt")
-cpack_set_if_not_set(CPACK_RESOURCE_FILE_README
+_cpack_set_default(CPACK_RESOURCE_FILE_README
   "${CMAKE_ROOT}/Templates/CPack.GenericDescription.txt")
-cpack_set_if_not_set(CPACK_RESOURCE_FILE_WELCOME
+_cpack_set_default(CPACK_RESOURCE_FILE_WELCOME
   "${CMAKE_ROOT}/Templates/CPack.GenericWelcome.txt")
 
-cpack_set_if_not_set(CPACK_MODULE_PATH "${CMAKE_MODULE_PATH}")
+_cpack_set_default(CPACK_MODULE_PATH "${CMAKE_MODULE_PATH}")
 
 if(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL)
   set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
@@ -359,7 +389,7 @@ if(__cpack_system_name MATCHES "Windows")
     set(__cpack_system_name win32)
   endif()
 endif()
-cpack_set_if_not_set(CPACK_SYSTEM_NAME "${__cpack_system_name}")
+_cpack_set_default(CPACK_SYSTEM_NAME "${__cpack_system_name}")
 
 # Root dir: default value should be the string literal "$PROGRAMFILES"
 # for backwards compatibility. Projects may set this value to anything.
@@ -369,17 +399,17 @@ if("x${__cpack_system_name}" STREQUAL "xwin64")
 else()
   set(__cpack_root_default "$PROGRAMFILES")
 endif()
-cpack_set_if_not_set(CPACK_NSIS_INSTALL_ROOT "${__cpack_root_default}")
+_cpack_set_default(CPACK_NSIS_INSTALL_ROOT "${__cpack_root_default}")
 
 # <project>-<major>.<minor>.<patch>-<release>-<platform>.<pkgtype>
-cpack_set_if_not_set(CPACK_PACKAGE_FILE_NAME
+_cpack_set_default(CPACK_PACKAGE_FILE_NAME
   "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}")
-cpack_set_if_not_set(CPACK_PACKAGE_INSTALL_DIRECTORY
+_cpack_set_default(CPACK_PACKAGE_INSTALL_DIRECTORY
   "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
-cpack_set_if_not_set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
+_cpack_set_default(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
   "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
-cpack_set_if_not_set(CPACK_PACKAGE_DEFAULT_LOCATION "/")
-cpack_set_if_not_set(CPACK_PACKAGE_RELOCATABLE "true")
+_cpack_set_default(CPACK_PACKAGE_DEFAULT_LOCATION "/")
+_cpack_set_default(CPACK_PACKAGE_RELOCATABLE "true")
 
 # always force to exactly "true" or "false" for CPack.Info.plist.in:
 if(CPACK_PACKAGE_RELOCATABLE)
@@ -519,10 +549,10 @@ mark_as_advanced(
   )
 
 # Set some other variables
-cpack_set_if_not_set(CPACK_INSTALL_CMAKE_PROJECTS
+_cpack_set_default(CPACK_INSTALL_CMAKE_PROJECTS
   "${CMAKE_BINARY_DIR};${CMAKE_PROJECT_NAME};ALL;/")
-cpack_set_if_not_set(CPACK_CMAKE_GENERATOR "${CMAKE_GENERATOR}")
-cpack_set_if_not_set(CPACK_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}")
+_cpack_set_default(CPACK_CMAKE_GENERATOR "${CMAKE_GENERATOR}")
+_cpack_set_default(CPACK_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}")
 # if the user has set CPACK_NSIS_DISPLAY_NAME remember it
 if(DEFINED CPACK_NSIS_DISPLAY_NAME)
   set(CPACK_NSIS_DISPLAY_NAME_SET TRUE)
@@ -531,34 +561,32 @@ endif()
 # explicitly, then use that as the default
 # value of CPACK_NSIS_PACKAGE_NAME  instead
 # of CPACK_PACKAGE_INSTALL_DIRECTORY
-cpack_set_if_not_set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+_cpack_set_default(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
 
 if(CPACK_NSIS_DISPLAY_NAME_SET)
-  string(REPLACE "\\" "\\\\"
-    _NSIS_DISPLAY_NAME_TMP  "${CPACK_NSIS_DISPLAY_NAME}")
-  cpack_set_if_not_set(CPACK_NSIS_PACKAGE_NAME "${_NSIS_DISPLAY_NAME_TMP}")
+  _cpack_set_default(CPACK_NSIS_PACKAGE_NAME "${CPACK_NSIS_DISPLAY_NAME}")
 else()
-  cpack_set_if_not_set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+  _cpack_set_default(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
 endif()
 
-cpack_set_if_not_set(CPACK_OUTPUT_CONFIG_FILE
+_cpack_set_default(CPACK_OUTPUT_CONFIG_FILE
   "${CMAKE_BINARY_DIR}/CPackConfig.cmake")
 
-cpack_set_if_not_set(CPACK_SOURCE_OUTPUT_CONFIG_FILE
+_cpack_set_default(CPACK_SOURCE_OUTPUT_CONFIG_FILE
   "${CMAKE_BINARY_DIR}/CPackSourceConfig.cmake")
 
-cpack_set_if_not_set(CPACK_SET_DESTDIR OFF)
-cpack_set_if_not_set(CPACK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
+_cpack_set_default(CPACK_SET_DESTDIR OFF)
+_cpack_set_default(CPACK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
 
-cpack_set_if_not_set(CPACK_NSIS_INSTALLER_ICON_CODE "")
-cpack_set_if_not_set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
+_cpack_set_default(CPACK_NSIS_INSTALLER_ICON_CODE "")
+_cpack_set_default(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
 
 # WiX specific variables
-cpack_set_if_not_set(CPACK_WIX_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
+_cpack_set_default(CPACK_WIX_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
 
 # set sysroot so SDK tools can be used
 if(CMAKE_OSX_SYSROOT)
-  cpack_set_if_not_set(CPACK_OSX_SYSROOT "${CMAKE_OSX_SYSROOT}")
+  _cpack_set_default(CPACK_OSX_SYSROOT "${CMAKE_OSX_SYSROOT}")
 endif()
 
 if(DEFINED CPACK_COMPONENTS_ALL)
@@ -598,13 +626,20 @@ cpack_encode_variables()
 configure_file("${cpack_input_file}" "${CPACK_OUTPUT_CONFIG_FILE}" @ONLY)
 
 # Generate source file
-cpack_set_if_not_set(CPACK_SOURCE_INSTALLED_DIRECTORIES
+_cpack_set_default(CPACK_SOURCE_INSTALLED_DIRECTORIES
   "${CMAKE_SOURCE_DIR};/")
-cpack_set_if_not_set(CPACK_SOURCE_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}-Source")
-cpack_set_if_not_set(CPACK_SOURCE_PACKAGE_FILE_NAME
+_cpack_set_default(CPACK_SOURCE_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}-Source")
+_cpack_set_default(CPACK_SOURCE_PACKAGE_FILE_NAME
   "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-Source")
-cpack_set_if_not_set(CPACK_SOURCE_IGNORE_FILES
-  "/CVS/;/\\\\\\\\.svn/;/\\\\\\\\.bzr/;/\\\\\\\\.hg/;/\\\\\\\\.git/;\\\\\\\\.swp$;\\\\\\\\.#;/#")
+
+set(__cpack_source_ignore_files_default
+  "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#")
+if(NOT CPACK_VERBATIM_VARIABLES)
+  _cpack_escape_for_cmake(__cpack_source_ignore_files_default
+    "${__cpack_source_ignore_files_default}")
+endif()
+_cpack_set_default(CPACK_SOURCE_IGNORE_FILES "${__cpack_source_ignore_files_default}")
+
 set(CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_SOURCE_INSTALL_CMAKE_PROJECTS}")
 set(CPACK_INSTALLED_DIRECTORIES "${CPACK_SOURCE_INSTALLED_DIRECTORIES}")
 set(CPACK_GENERATOR "${CPACK_SOURCE_GENERATOR}")
diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake
index 573e5aa..96d5609 100644
--- a/Modules/CPackComponent.cmake
+++ b/Modules/CPackComponent.cmake
@@ -263,7 +263,7 @@
 #
 # The site argument is a URL where the archives for downloadable
 # components will reside, e.g.,
-# http://www.cmake.org/files/2.6.1/installer/ All of the archives
+# https://cmake.org/files/2.6.1/installer/ All of the archives
 # produced by CPack should be uploaded to that location.
 #
 # UPLOAD_DIRECTORY is the local directory where CPack will create the
@@ -301,7 +301,7 @@
 if(NOT CPackComponent_CMake_INCLUDED)
 set(CPackComponent_CMake_INCLUDED 1)
 
-# Argument-parsing macro from http://www.cmake.org/Wiki/CMakeMacroParseArguments
+# Argument-parsing macro from https://cmake.org/Wiki/CMakeMacroParseArguments
 macro(cpack_parse_arguments prefix arg_names option_names)
   set(${prefix}_DEFAULT_ARGS)
   foreach(arg_name ${arg_names})
diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake
index 09cddcd..60e0d1f 100644
--- a/Modules/CPackDeb.cmake
+++ b/Modules/CPackDeb.cmake
@@ -9,7 +9,7 @@
 #
 # CPackDeb may be used to create Deb package using CPack.
 # CPackDeb is a CPack generator thus it uses the CPACK_XXX variables
-# used by CPack : http://www.cmake.org/Wiki/CMake:CPackConfiguration.
+# used by CPack : https://cmake.org/Wiki/CMake:CPackConfiguration.
 # CPackDeb generator should work on any linux host but it will produce
 # better deb package when Debian specific tools 'dpkg-xxx' are usable on
 # the build system.
@@ -23,7 +23,7 @@
 # a component GROUP name.
 #
 # You'll find a detailed usage on the wiki:
-# http://www.cmake.org/Wiki/CMake:CPackPackageGenerators#DEB_.28UNIX_only.29 .
+# https://cmake.org/Wiki/CMake:CPackPackageGenerators#DEB_.28UNIX_only.29 .
 # However as a handy reminder here comes the list of specific variables:
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_NAME
@@ -78,6 +78,7 @@
 #
 #    set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.1-6), libc6 (< 2.4)")
 #
+#
 # .. variable:: CPACK_DEBIAN_PACKAGE_MAINTAINER
 #
 #  The Debian package maintainer
@@ -152,7 +153,7 @@
 #    You may need set :variable:`CMAKE_INSTALL_RPATH` to an appropriate value
 #    if you use this feature, because if you don't :code:`dpkg-shlibdeps`
 #    may fail to find your own shared libs.
-#    See http://www.cmake.org/Wiki/CMake_RPATH_handling.
+#    See https://cmake.org/Wiki/CMake_RPATH_handling.
 #
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_DEBUG
@@ -164,6 +165,7 @@
 #  * Default   : -
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_PREDEPENDS
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_PREDEPENDS
 #
 #  Sets the `Pre-Depends` field of the Debian package.
 #  Like :variable:`Depends <CPACK_DEBIAN_PACKAGE_DEPENDS>`, except that it
@@ -172,11 +174,16 @@
 #  pre-dependency.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   :
+#
+#    - An empty string for non-component based installations
+#    - :variable:`CPACK_DEBIAN_PACKAGE_PREDEPENDS` for component-based
+#      installations.
 #
 #  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_ENHANCES
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_ENHANCES
 #
 #  Sets the `Enhances` field of the Debian package.
 #  Similar to :variable:`Suggests <CPACK_DEBIAN_PACKAGE_SUGGESTS>` but works
@@ -184,11 +191,16 @@
 #  functionality of another package.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   :
+#
+#    - An empty string for non-component based installations
+#    - :variable:`CPACK_DEBIAN_PACKAGE_ENHANCES` for component-based
+#      installations.
 #
 #  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_BREAKS
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_BREAKS
 #
 #  Sets the `Breaks` field of the Debian package.
 #  When a binary package (P) declares that it breaks other packages (B),
@@ -199,12 +211,17 @@
 #  packages (B) cannot be reconfigured again.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   :
+#
+#    - An empty string for non-component based installations
+#    - :variable:`CPACK_DEBIAN_PACKAGE_BREAKS` for component-based
+#      installations.
 #
 #  See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-breaks
 #
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_CONFLICTS
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONFLICTS
 #
 #  Sets the `Conflicts` field of the Debian package.
 #  When one binary package declares a conflict with another using a `Conflicts`
@@ -212,7 +229,11 @@
 #  the same time.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   :
+#
+#    - An empty string for non-component based installations
+#    - :variable:`CPACK_DEBIAN_PACKAGE_CONFLICTS` for component-based
+#      installations.
 #
 #  See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-conflicts
 #
@@ -225,53 +246,74 @@
 #    time.
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_PROVIDES
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_PROVIDES
 #
 #  Sets the `Provides` field of the Debian package.
 #  A virtual package is one which appears in the `Provides` control field of
 #  another package.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   :
+#
+#    - An empty string for non-component based installations
+#    - :variable:`CPACK_DEBIAN_PACKAGE_PROVIDES` for component-based
+#      installations.
 #
 #  See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-virtual
 #
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_REPLACES
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_REPLACES
 #
 #  Sets the `Replaces` field of the Debian package.
 #  Packages can declare in their control file that they should overwrite
 #  files in certain other packages, or completely replace other packages.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   :
+#
+#    - An empty string for non-component based installations
+#    - :variable:`CPACK_DEBIAN_PACKAGE_REPLACES` for component-based
+#      installations.
 #
 #  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 #
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_RECOMMENDS
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_RECOMMENDS
 #
 #  Sets the `Recommends` field of the Debian package.
 #  Allows packages to declare a strong, but not absolute, dependency on other
 #  packages.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   :
+#
+#    - An empty string for non-component based installations
+#    - :variable:`CPACK_DEBIAN_PACKAGE_RECOMMENDS` for component-based
+#      installations.
 #
 #  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 #
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_SUGGESTS
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_SUGGESTS
 #
 #  Sets the `Suggests` field of the Debian package.
 #  Allows packages to declare a suggested package install grouping.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   :
+#
+#    - An empty string for non-component based installations
+#    - :variable:`CPACK_DEBIAN_PACKAGE_SUGGESTS` for component-based
+#      installations.
 #
 #  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 #
 #
 # .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_EXTRA
 #
 #  This variable allow advanced user to add custom script to the
 #  control.tar.gz.
@@ -284,6 +326,34 @@
 #
 #   set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
 #       "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
+#
+#  .. note::
+#
+#    The original permissions of the files will be used in the final
+#    package unless the variable
+#    :variable:`CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION` is set.
+#    In particular, the scripts should have the proper executable
+#    flag prior to the generation of the package.
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
+#               CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_STRICT_PERMISSION
+#
+#  This variable indicates if the Debian policy on control files should be
+#  strictly followed.
+#
+#  * Mandatory : NO
+#  * Default   : FALSE
+#
+#  Usage::
+#
+#   set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+#
+#  .. note::
+#
+#    This overrides the permissions on the original files, following the rules
+#    set by Debian policy
+#    https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
+#
 
 
 #=============================================================================
@@ -320,11 +390,6 @@ function(cpack_deb_prepare_package_vars)
     set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
   endif()
 
-  find_program(FAKEROOT_EXECUTABLE fakeroot)
-  if(FAKEROOT_EXECUTABLE)
-    set(CPACK_DEBIAN_FAKEROOT_EXECUTABLE ${FAKEROOT_EXECUTABLE})
-  endif()
-
   set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_PATH}")
 
   # per component automatic discover: some of the component might not have
@@ -495,19 +560,21 @@ function(cpack_deb_prepare_package_vars)
   # You should set: DEBIAN_PACKAGE_DEPENDS
   # TODO: automate 'objdump -p | grep NEEDED'
 
-  # if per-component dependency, overrides the global CPACK_DEBIAN_PACKAGE_DEPENDS
+  # if per-component dependency, overrides the global CPACK_DEBIAN_PACKAGE_${dependency_type_}
   # automatic dependency discovery will be performed afterwards.
   if(CPACK_DEB_PACKAGE_COMPONENT)
-    string(TOUPPER "${CPACK_DEB_PACKAGE_COMPONENT}" _local_component_name)
-    set(_component_depends_var "CPACK_DEBIAN_${_local_component_name}_PACKAGE_DEPENDS")
+    foreach(dependency_type_ DEPENDS RECOMMENDS SUGGESTS PREDEPENDS ENHANCES BREAKS CONFLICTS PROVIDES REPLACES)
+      set(_component_var "CPACK_DEBIAN_${_local_component_name}_PACKAGE_${dependency_type_}")
 
-    # if set, overrides the global dependency
-    if(DEFINED ${_component_depends_var})
-      set(CPACK_DEBIAN_PACKAGE_DEPENDS "${${_component_depends_var}}")
-      if(CPACK_DEBIAN_PACKAGE_DEBUG)
-        message("CPackDeb Debug: component '${_local_component_name}' dependencies set to '${CPACK_DEBIAN_PACKAGE_DEPENDS}'")
+      # if set, overrides the global dependency
+      if(DEFINED ${_component_var})
+        set(CPACK_DEBIAN_PACKAGE_${dependency_type_} "${${_component_var}}")
+        if(CPACK_DEBIAN_PACKAGE_DEBUG)
+          message("CPackDeb Debug: component '${_local_component_name}' ${dependency_type_}"
+            "dependencies set to '${CPACK_DEBIAN_PACKAGE_${dependency_}}'")
+        endif()
       endif()
-    endif()
+    endforeach()
   endif()
 
   # at this point, the CPACK_DEBIAN_PACKAGE_DEPENDS is properly set
@@ -542,7 +609,6 @@ function(cpack_deb_prepare_package_vars)
       set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
     endif()
   else()
-    string(TOUPPER ${CPACK_DEB_PACKAGE_COMPONENT} _local_component_name)
     set(component_description_var CPACK_COMPONENT_${_local_component_name}_DESCRIPTION)
 
     # component description overrides package description
@@ -584,13 +650,20 @@ function(cpack_deb_prepare_package_vars)
   # - conffiles
   # - postinst
   # - postrm
-  # - prerm"
+  # - prerm
   # Usage:
   # set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
   #    "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
 
   # Are we packaging components ?
   if(CPACK_DEB_PACKAGE_COMPONENT)
+    # override values with per component version if set
+    foreach(VAR_NAME_ "PACKAGE_CONTROL_EXTRA" "PACKAGE_CONTROL_STRICT_PERMISSION")
+      if(CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_})
+        set(CPACK_DEBIAN_${VAR_NAME_} "${CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}}")
+      endif()
+    endforeach()
+
     set(CPACK_DEB_PACKAGE_COMPONENT_PART_NAME "-${CPACK_DEB_PACKAGE_COMPONENT}")
     string(TOLOWER "${CPACK_PACKAGE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_NAME}" CPACK_DEBIAN_PACKAGE_NAME)
   else()
@@ -607,6 +680,7 @@ function(cpack_deb_prepare_package_vars)
      message("CPackDeb:Debug: CPACK_PACKAGE_FILE_NAME           = ${CPACK_PACKAGE_FILE_NAME}")
      message("CPackDeb:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY   = ${CPACK_PACKAGE_INSTALL_DIRECTORY}")
      message("CPackDeb:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}")
+     message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION = ${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}")
   endif()
 
   # For debian source packages:
@@ -632,7 +706,6 @@ function(cpack_deb_prepare_package_vars)
   set(GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_DEBIAN_PACKAGE_MAINTAINER}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_DEBIAN_PACKAGE_DESCRIPTION}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}" PARENT_SCOPE)
-  set(GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE "${CPACK_DEBIAN_FAKEROOT_EXECUTABLE}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_COMPRESSION_TYPE "${CPACK_DEBIAN_COMPRESSION_TYPE}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS "${CPACK_DEBIAN_PACKAGE_RECOMMENDS}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS "${CPACK_DEBIAN_PACKAGE_SUGGESTS}" PARENT_SCOPE)
@@ -644,6 +717,8 @@ function(cpack_deb_prepare_package_vars)
   set(GEN_CPACK_DEBIAN_PACKAGE_PROVIDES "${CPACK_DEBIAN_PACKAGE_PROVIDES}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_REPLACES "${CPACK_DEBIAN_PACKAGE_REPLACES}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}" PARENT_SCOPE)
+  set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
+      "${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}" PARENT_SCOPE)
   set(GEN_WDIR "${WDIR}" PARENT_SCOPE)
 endfunction()
 
diff --git a/Modules/CPackNSIS.cmake b/Modules/CPackNSIS.cmake
index 4b2e0eb..c6b3d19 100644
--- a/Modules/CPackNSIS.cmake
+++ b/Modules/CPackNSIS.cmake
@@ -115,7 +115,7 @@
 #
 #   set(CPACK_NSIS_MENU_LINKS
 #       "doc/cmake- at CMake_VERSION_MAJOR@. at CMake_VERSION_MINOR@/cmake.html"
-#       "CMake Help" "http://www.cmake.org" "CMake Web Site")
+#       "CMake Help" "https://cmake.org" "CMake Web Site")
 #
 
 #=============================================================================
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index cb77fb8..1e7b055 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -9,7 +9,7 @@
 #
 # CPackRPM may be used to create RPM package using CPack.  CPackRPM is a
 # CPack generator thus it uses the CPACK_XXX variables used by CPack :
-# http://www.cmake.org/Wiki/CMake:CPackConfiguration
+# https://cmake.org/Wiki/CMake:CPackConfiguration
 #
 # However CPackRPM has specific features which are controlled by the
 # specifics CPACK_RPM_XXX variables.  CPackRPM is a component aware
@@ -24,7 +24,7 @@
 #
 # ::
 #
-#   http://www.cmake.org/Wiki/CMake:CPackPackageGenerators#RPM_.28Unix_Only.29
+#   https://cmake.org/Wiki/CMake:CPackPackageGenerators#RPM_.28Unix_Only.29
 #
 # However as a handy reminder here comes the list of specific variables:
 #
@@ -95,6 +95,7 @@
 #  * Default   : CPACK_PACKAGE_VENDOR if set or "unknown"
 #
 # .. variable:: CPACK_RPM_PACKAGE_URL
+#               CPACK_RPM_<component>_PACKAGE_URL
 #
 #  The projects URL.
 #
@@ -123,7 +124,55 @@
 #  compression whereas older cannot use such RPM.  Using this one can enforce
 #  compression type to be used.  Possible value are: lzma, xz, bzip2 and gzip.
 #
+# .. variable:: CPACK_RPM_PACKAGE_AUTOREQ
+#               CPACK_RPM_<component>_PACKAGE_AUTOREQ
+#
+#  RPM spec autoreq field.
+#
+#  * Mandatory : NO
+#  * Default   : -
+#
+#  May be used to enable (1, yes) or disable (0, no) automatic shared libraries
+#  dependency detection. Dependencies are added to requires list.
+#
+#  .. note::
+#
+#    By defalut automatic dependency detection is enabled by rpm generator.
+#
+# .. variable:: CPACK_RPM_PACKAGE_AUTOPROV
+#               CPACK_RPM_<component>_PACKAGE_AUTOPROV
+#
+#  RPM spec autoprov field.
+#
+#  * Mandatory : NO
+#  * Default   : -
+#
+#  May be used to enable (1, yes) or disable (0, no) automatic listing of shared
+#  libraries that are provided by the package. Shared libraries are added to
+#  provides list.
+#
+#  .. note::
+#
+#    By defalut automatic provides detection is enabled by rpm generator.
+#
+# .. variable:: CPACK_RPM_PACKAGE_AUTOREQPROV
+#               CPACK_RPM_<component>_PACKAGE_AUTOREQPROV
+#
+#  RPM spec autoreqprov field.
+#
+#  * Mandatory : NO
+#  * Default   : -
+#
+#  Variable enables/disables autoreq and autoprov at the same time.
+#  See :variable:`CPACK_RPM_PACKAGE_AUTOREQ` and :variable:`CPACK_RPM_PACKAGE_AUTOPROV`
+#  for more details.
+#
+#  .. note::
+#
+#    By defalut automatic detection feature is enabled by rpm.
+#
 # .. variable:: CPACK_RPM_PACKAGE_REQUIRES
+#               CPACK_RPM_<component>_PACKAGE_REQUIRES
 #
 #  RPM spec requires field.
 #
@@ -139,7 +188,25 @@
 #
 #   rpm -qp --requires file.rpm
 #
+# .. variable:: CPACK_RPM_PACKAGE_CONFLICTS
+#               CPACK_RPM_<component>_PACKAGE_CONFLICTS
+#
+#  RPM spec conflicts field.
+#
+#  * Mandatory : NO
+#  * Default   : -
+#
+#  May be used to set negative RPM dependencies (conflicts). Note that you must enclose
+#  the complete requires string between quotes, for example::
+#
+#   set(CPACK_RPM_PACKAGE_CONFLICTS "libxml2")
+#
+#  The conflicting package list of an RPM file could be printed with::
+#
+#   rpm -qp --conflicts file.rpm
+#
 # .. variable:: CPACK_RPM_PACKAGE_REQUIRES_PRE
+#               CPACK_RPM_<component>_PACKAGE_REQUIRES_PRE
 #
 #  RPM spec requires(pre) field.
 #
@@ -152,6 +219,7 @@
 #   set(CPACK_RPM_PACKAGE_REQUIRES_PRE "shadow-utils, initscripts")
 #
 # .. variable:: CPACK_RPM_PACKAGE_REQUIRES_POST
+#               CPACK_RPM_<component>_PACKAGE_REQUIRES_POST
 #
 #  RPM spec requires(post) field.
 #
@@ -165,6 +233,7 @@
 #
 #
 # .. variable:: CPACK_RPM_PACKAGE_REQUIRES_POSTUN
+#               CPACK_RPM_<component>_PACKAGE_REQUIRES_POSTUN
 #
 #  RPM spec requires(postun) field.
 #
@@ -178,6 +247,7 @@
 #
 #
 # .. variable:: CPACK_RPM_PACKAGE_REQUIRES_PREUN
+#               CPACK_RPM_<component>_PACKAGE_REQUIRES_PREUN
 #
 #  RPM spec requires(preun) field.
 #
@@ -190,6 +260,7 @@
 #   set(CPACK_RPM_PACKAGE_REQUIRES_PREUN "shadow-utils, initscripts")
 #
 # .. variable:: CPACK_RPM_PACKAGE_SUGGESTS
+#               CPACK_RPM_<component>_PACKAGE_SUGGESTS
 #
 #  RPM spec suggest field.
 #
@@ -200,6 +271,7 @@
 #  enclose the complete requires string between quotes.
 #
 # .. variable:: CPACK_RPM_PACKAGE_PROVIDES
+#               CPACK_RPM_<component>_PACKAGE_PROVIDES
 #
 #  RPM spec provides field.
 #
@@ -212,6 +284,7 @@
 #   rpm -qp --provides file.rpm
 #
 # .. variable:: CPACK_RPM_PACKAGE_OBSOLETES
+#               CPACK_RPM_<component>_PACKAGE_OBSOLETES
 #
 #  RPM spec obsoletes field.
 #
diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake
index 5fe51a6..bef8e16 100644
--- a/Modules/CPackWIX.cmake
+++ b/Modules/CPackWIX.cmake
@@ -16,7 +16,7 @@
 #
 #  Will be automatically generated unless explicitly provided.
 #
-#  It should be explicitly set to a constant generated gloabally unique
+#  It should be explicitly set to a constant generated globally unique
 #  identifier (GUID) to allow your installers to replace existing
 #  installations that use the same GUID.
 #
@@ -226,7 +226,7 @@
 #  This variable can be used to provide a value for
 #  the Windows Installer property ``<PROPERTY>``
 #
-#  The follwing list contains some example properties that can be used to
+#  The following list contains some example properties that can be used to
 #  customize information under
 #  "Programs and Features" (also known as "Add or Remove Programs")
 #
diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake
index 6c74cf3..ef3aa76 100644
--- a/Modules/CTestCoverageCollectGCOV.cmake
+++ b/Modules/CTestCoverageCollectGCOV.cmake
@@ -161,7 +161,7 @@ function(ctest_coverage_collect_gcov)
       message(STATUS "Could not determine source file corresponding to: ${gcov_file}")
     endif()
 
-    foreach(exclude_entry ${CTEST_CUSTOM_COVERAGE_EXCLUDE})
+    foreach(exclude_entry IN LISTS CTEST_CUSTOM_COVERAGE_EXCLUDE)
       if(source_file MATCHES "${exclude_entry}")
         set(is_excluded true)
 
diff --git a/Modules/CheckForPthreads.c b/Modules/CheckForPthreads.c
index 7250fbf..2732957 100644
--- a/Modules/CheckForPthreads.c
+++ b/Modules/CheckForPthreads.c
@@ -31,7 +31,7 @@ void* runner(void* args)
   int cc;
   for ( cc = 0; cc < 10; cc ++ )
     {
-    printf("%d CC: %d\n", (int)args, cc);
+    printf("%p CC: %d\n", args, cc);
     }
   res ++;
   return 0;
diff --git a/Modules/CheckFunctionExists.c b/Modules/CheckFunctionExists.c
index 607b3e8..fd29618 100644
--- a/Modules/CheckFunctionExists.c
+++ b/Modules/CheckFunctionExists.c
@@ -1,5 +1,8 @@
 #ifdef CHECK_FUNCTION_EXISTS
 
+#ifdef __cplusplus
+extern "C"
+#endif
 char CHECK_FUNCTION_EXISTS();
 #ifdef __CLASSIC_C__
 int main(){
diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake
index d277c32..5dd3751 100644
--- a/Modules/CheckFunctionExists.cmake
+++ b/Modules/CheckFunctionExists.cmake
@@ -57,14 +57,26 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
     else()
       set(CHECK_FUNCTION_EXISTS_ADD_INCLUDES)
     endif()
+
+    if(CMAKE_C_COMPILER_LOADED)
+      set(_cfe_source ${CMAKE_ROOT}/Modules/CheckFunctionExists.c)
+    elseif(CMAKE_CXX_COMPILER_LOADED)
+      set(_cfe_source ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckFunctionExists/CheckFunctionExists.cxx)
+      configure_file(${CMAKE_ROOT}/Modules/CheckFunctionExists.c "${_cfe_source}" COPYONLY)
+    else()
+      message(FATAL_ERROR "CHECK_FUNCTION_EXISTS needs either C or CXX language enabled")
+    endif()
+
     try_compile(${VARIABLE}
       ${CMAKE_BINARY_DIR}
-      ${CMAKE_ROOT}/Modules/CheckFunctionExists.c
+      ${_cfe_source}
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
       ${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
       "${CHECK_FUNCTION_EXISTS_ADD_INCLUDES}"
       OUTPUT_VARIABLE OUTPUT)
+    unset(_cfe_source)
+
     if(${VARIABLE})
       set(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}")
       if(NOT CMAKE_REQUIRED_QUIET)
diff --git a/Modules/CheckLibraryExists.cmake b/Modules/CheckLibraryExists.cmake
index 95c595a..6b53823 100644
--- a/Modules/CheckLibraryExists.cmake
+++ b/Modules/CheckLibraryExists.cmake
@@ -53,15 +53,26 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
       set(CHECK_LIBRARY_EXISTS_LIBRARIES
         ${CHECK_LIBRARY_EXISTS_LIBRARIES} ${CMAKE_REQUIRED_LIBRARIES})
     endif()
+
+    if(CMAKE_C_COMPILER_LOADED)
+      set(_cle_source ${CMAKE_ROOT}/Modules/CheckFunctionExists.c)
+    elseif(CMAKE_CXX_COMPILER_LOADED)
+      set(_cle_source ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckLibraryExists/CheckFunctionExists.cxx)
+      configure_file(${CMAKE_ROOT}/Modules/CheckFunctionExists.c "${_cle_source}" COPYONLY)
+    else()
+      message(FATAL_ERROR "CHECK_FUNCTION_EXISTS needs either C or CXX language enabled")
+    endif()
+
     try_compile(${VARIABLE}
       ${CMAKE_BINARY_DIR}
-      ${CMAKE_ROOT}/Modules/CheckFunctionExists.c
+      ${_cle_source}
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
       LINK_LIBRARIES ${CHECK_LIBRARY_EXISTS_LIBRARIES}
       CMAKE_FLAGS
       -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_LIBRARY_EXISTS_DEFINITION}
       -DLINK_DIRECTORIES:STRING=${LOCATION}
       OUTPUT_VARIABLE OUTPUT)
+    unset(_cle_source)
 
     if(${VARIABLE})
       if(NOT CMAKE_REQUIRED_QUIET)
diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake
index 79c5ba7..c4dff3f 100644
--- a/Modules/CheckSymbolExists.cmake
+++ b/Modules/CheckSymbolExists.cmake
@@ -44,10 +44,14 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-
-
 macro(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
-  _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+  if(CMAKE_C_COMPILER_LOADED)
+    _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+  elseif(CMAKE_CXX_COMPILER_LOADED)
+    _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+  else()
+    message(FATAL_ERROR "CHECK_SYMBOL_EXISTS needs either C or CXX language enabled")
+  endif()
 endmacro()
 
 macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake
index 10454f6..5908c26 100644
--- a/Modules/Compiler/AppleClang-C.cmake
+++ b/Modules/Compiler/AppleClang-C.cmake
@@ -13,7 +13,12 @@ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
 endif()
 
 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
-  set(CMAKE_C_STANDARD_DEFAULT 99)
+  if (NOT CMAKE_C_COMPILER_FORCED)
+    if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT)
+      message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}")
+    endif()
+    set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT})
+  endif()
 endif()
 
 macro(cmake_record_c_compile_features)
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
index 5194da4..c4e342b 100644
--- a/Modules/Compiler/AppleClang-CXX.cmake
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -13,16 +13,25 @@ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
   set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
 endif()
 
-if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.1)
+  set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14")
+  set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
   # AppleClang 5.0 knows this flag, but does not set a __cplusplus macro greater than 201103L
   set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
   set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
 endif()
 
 if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
-  set(CMAKE_CXX_STANDARD_DEFAULT 98)
+  if (NOT CMAKE_CXX_COMPILER_FORCED)
+    if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+      message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+    endif()
+    set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
+  endif()
 endif()
 
+
 macro(cmake_record_cxx_compile_features)
   macro(_get_appleclang_features std_version list)
     record_compiler_features(CXX "${std_version}" ${list})
diff --git a/Modules/Compiler/CCur-Fortran.cmake b/Modules/Compiler/CCur-Fortran.cmake
new file mode 100644
index 0000000..6ec06ae
--- /dev/null
+++ b/Modules/Compiler/CCur-Fortran.cmake
@@ -0,0 +1 @@
+include(Compiler/GNU-Fortran)
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake
index 548d0a5..a2e81c1 100644
--- a/Modules/Compiler/Clang-C.cmake
+++ b/Modules/Compiler/Clang-C.cmake
@@ -17,10 +17,13 @@ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
   set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
 endif()
 
-if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6)
-  set(CMAKE_C_STANDARD_DEFAULT 11)
-elseif(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
-  set(CMAKE_C_STANDARD_DEFAULT 99)
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
+  if (NOT CMAKE_C_COMPILER_FORCED)
+    if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT)
+      message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}")
+    endif()
+    set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT})
+  endif()
 endif()
 
 macro(cmake_record_c_compile_features)
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 84b2c74..055a8ee 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -31,8 +31,13 @@ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
   set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
 endif()
 
-if(UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
-  set(CMAKE_CXX_STANDARD_DEFAULT 98)
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
+  if (NOT CMAKE_CXX_COMPILER_FORCED)
+    if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+      message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+    endif()
+    set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
+  endif()
 endif()
 
 macro(cmake_record_cxx_compile_features)
diff --git a/Modules/Compiler/Cray-DetermineCompiler.cmake b/Modules/Compiler/Cray-DetermineCompiler.cmake
index 881b82c..6602294 100644
--- a/Modules/Compiler/Cray-DetermineCompiler.cmake
+++ b/Modules/Compiler/Cray-DetermineCompiler.cmake
@@ -2,5 +2,5 @@
 set(_compiler_id_pp_test "defined(_CRAYC)")
 
 set(_compiler_id_version_compute "
-# define @PREFIX at COMPILER_VERSION_MAJOR @MACRO_DEC@(_RELEASE)
+# define @PREFIX at COMPILER_VERSION_MAJOR @MACRO_DEC@(_RELEASE_MAJOR)
 # define @PREFIX at COMPILER_VERSION_MINOR @MACRO_DEC@(_RELEASE_MINOR)")
diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake
index 89704e6..d979fb7 100644
--- a/Modules/Compiler/GNU-C.cmake
+++ b/Modules/Compiler/GNU-C.cmake
@@ -22,22 +22,26 @@ elseif (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
   set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu1x")
 endif()
 
-if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
-  set(CMAKE_C_STANDARD_DEFAULT 11)
-elseif(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
-  set(CMAKE_C_STANDARD_DEFAULT 90)
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
+  if (NOT CMAKE_C_COMPILER_FORCED)
+    if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT)
+      message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}")
+    endif()
+    set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT})
+  endif()
 endif()
 
+
 macro(cmake_record_c_compile_features)
   macro(_get_gcc_features std_version list)
     record_compiler_features(C "${std_version}" ${list})
   endmacro()
 
   set(_result 0)
-  if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
+  if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
     _get_gcc_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES)
   endif()
-  if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
+  if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
     if (_result EQUAL 0)
       _get_gcc_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES)
     endif()
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index 2dc02f0..a7e71c3 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -35,7 +35,12 @@ elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
 endif()
 
 if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
-  set(CMAKE_CXX_STANDARD_DEFAULT 98)
+  if (NOT CMAKE_CXX_COMPILER_FORCED)
+    if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+      message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+    endif()
+    set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
+  endif()
 endif()
 
 macro(cmake_record_cxx_compile_features)
diff --git a/Modules/Compiler/GNU-DetermineCompiler.cmake b/Modules/Compiler/GNU-DetermineCompiler.cmake
index 261f148..6ddc566 100644
--- a/Modules/Compiler/GNU-DetermineCompiler.cmake
+++ b/Modules/Compiler/GNU-DetermineCompiler.cmake
@@ -3,7 +3,9 @@ set(_compiler_id_pp_test "defined(__GNUC__)")
 
 set(_compiler_id_version_compute "
 # define @PREFIX at COMPILER_VERSION_MAJOR @MACRO_DEC@(__GNUC__)
-# define @PREFIX at COMPILER_VERSION_MINOR @MACRO_DEC@(__GNUC_MINOR__)
+# if defined(__GNUC_MINOR__)
+#  define @PREFIX at COMPILER_VERSION_MINOR @MACRO_DEC@(__GNUC_MINOR__)
+# endif
 # if defined(__GNUC_PATCHLEVEL__)
 #  define @PREFIX at COMPILER_VERSION_PATCH @MACRO_DEC@(__GNUC_PATCHLEVEL__)
 # endif")
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
index f01255c..764fbf9 100644
--- a/Modules/Compiler/GNU.cmake
+++ b/Modules/Compiler/GNU.cmake
@@ -50,8 +50,8 @@ macro(__compiler_gnu lang)
   set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
   set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
   set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG")
-  set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-  set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+  set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+  set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
   if(NOT APPLE)
     set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
   endif()
diff --git a/Modules/Compiler/HP-C.cmake b/Modules/Compiler/HP-C.cmake
index 6dddcba..b42ba2b 100644
--- a/Modules/Compiler/HP-C.cmake
+++ b/Modules/Compiler/HP-C.cmake
@@ -1,4 +1,4 @@
 set(CMAKE_C_VERBOSE_FLAG "-v")
 
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
diff --git a/Modules/Compiler/HP-CXX.cmake b/Modules/Compiler/HP-CXX.cmake
index 6411dac..7548754 100644
--- a/Modules/Compiler/HP-CXX.cmake
+++ b/Modules/Compiler/HP-CXX.cmake
@@ -1,7 +1,7 @@
 set(CMAKE_CXX_VERBOSE_FLAG "-v")
 
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
 
 # HP aCC since version 3.80 supports the flag +hpxstd98 to get ANSI C++98
 # template support. It is known that version 6.25 doesn't need that flag.
diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake
index ad821ab..a6ca2c2 100644
--- a/Modules/Compiler/HP-Fortran.cmake
+++ b/Modules/Compiler/HP-Fortran.cmake
@@ -2,5 +2,5 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-v")
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "+source=fixed")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "+source=free")
 
-set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
diff --git a/Modules/Compiler/IAR-ASM.cmake b/Modules/Compiler/IAR-ASM.cmake
index 66fb052..844c30e 100644
--- a/Modules/Compiler/IAR-ASM.cmake
+++ b/Modules/Compiler/IAR-ASM.cmake
@@ -2,7 +2,7 @@
 
 include(Compiler/IAR)
 
-set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> <SOURCE> <DEFINES> <FLAGS> -o <OBJECT>")
+set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
 
 if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM")
   set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;asm;msa)
diff --git a/Modules/Compiler/IAR-C.cmake b/Modules/Compiler/IAR-C.cmake
index da29447..d2c7df9 100644
--- a/Modules/Compiler/IAR-C.cmake
+++ b/Modules/Compiler/IAR-C.cmake
@@ -3,9 +3,9 @@
 
 include(Compiler/IAR)
 
-set(CMAKE_C_COMPILE_OBJECT             "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <FLAGS> -o <OBJECT>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE     "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
+set(CMAKE_C_COMPILE_OBJECT             "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE     "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
 
 # The toolchains for ARM and AVR are quite different:
 if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM")
diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake
index eae9d1b..03ecdf1 100644
--- a/Modules/Compiler/IAR-CXX.cmake
+++ b/Modules/Compiler/IAR-CXX.cmake
@@ -2,10 +2,10 @@
 
 include(Compiler/IAR)
 
-set(CMAKE_CXX_COMPILE_OBJECT  "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <FLAGS> -o <OBJECT>")
+set(CMAKE_CXX_COMPILE_OBJECT  "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
 
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE     "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE     "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
 
 
 
diff --git a/Modules/Compiler/IAR.cmake b/Modules/Compiler/IAR.cmake
index 00e4713..8c6c3f6 100644
--- a/Modules/Compiler/IAR.cmake
+++ b/Modules/Compiler/IAR.cmake
@@ -1,6 +1,6 @@
 # This file is processed when the IAR compiler is used for a C or C++ file
 # Documentation can be downloaded here: http://www.iar.com/website1/1.0.1.0/675/1/
-# The initial feature request is here: http://www.cmake.org/Bug/view.php?id=10176
+# The initial feature request is here: https://cmake.org/Bug/view.php?id=10176
 # It also contains additional links and information.
 
 if(_IAR_CMAKE_LOADED)
@@ -39,7 +39,7 @@ endif()
 
 if(NOT IAR_TARGET_ARCHITECTURE)
   message(FATAL_ERROR "The IAR compiler for this architecture is not yet supported "
-          " by CMake. Please go to http://www.cmake.org/Bug and enter a feature request there.")
+          " by CMake. Please go to https://cmake.org/Bug and enter a feature request there.")
 endif()
 
 set(CMAKE_LINKER "${CMAKE_IAR_LINKER}" CACHE FILEPATH "The IAR linker" FORCE)
diff --git a/Modules/Compiler/Intel-C.cmake b/Modules/Compiler/Intel-C.cmake
index 1d651e3..dfba4b2 100644
--- a/Modules/Compiler/Intel-C.cmake
+++ b/Modules/Compiler/Intel-C.cmake
@@ -8,5 +8,5 @@ set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG")
 
 set(CMAKE_DEPFILE_FLAGS_C "-MMD -MT <OBJECT> -MF <DEPFILE>")
 
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake
index 020e862..7947695 100644
--- a/Modules/Compiler/Intel-CXX.cmake
+++ b/Modules/Compiler/Intel-CXX.cmake
@@ -8,5 +8,5 @@ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG")
 
 set(CMAKE_DEPFILE_FLAGS_CXX "-MMD -MT <OBJECT> -MF <DEPFILE>")
 
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake
index 9ebac5a..671d284 100644
--- a/Modules/Compiler/Intel-Fortran.cmake
+++ b/Modules/Compiler/Intel-Fortran.cmake
@@ -8,5 +8,5 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-v")
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
 
-set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/PGI.cmake b/Modules/Compiler/PGI.cmake
index 162e3c9..797945f 100644
--- a/Modules/Compiler/PGI.cmake
+++ b/Modules/Compiler/PGI.cmake
@@ -30,6 +30,6 @@ macro(__compiler_pgi lang)
   set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-O2 -gopt")
 
   # Preprocessing and assembly rules.
-  set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-  set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+  set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+  set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
 endmacro()
diff --git a/Modules/Compiler/QCC-CXX.cmake b/Modules/Compiler/QCC-CXX.cmake
index a676bbe..e86d1fa 100644
--- a/Modules/Compiler/QCC-CXX.cmake
+++ b/Modules/Compiler/QCC-CXX.cmake
@@ -4,7 +4,7 @@ __compiler_qcc(CXX)
 # If the toolchain uses qcc for CMAKE_CXX_COMPILER instead of QCC, the
 # default for the driver is not c++.
 set(CMAKE_CXX_COMPILE_OBJECT
-  "<CMAKE_CXX_COMPILER> -lang-c++ <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+  "<CMAKE_CXX_COMPILER> -lang-c++ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 
 set(CMAKE_CXX_LINK_EXECUTABLE
   "<CMAKE_CXX_COMPILER> -lang-c++ <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake
index 92252cb..c452983 100644
--- a/Modules/Compiler/SunPro-C.cmake
+++ b/Modules/Compiler/SunPro-C.cmake
@@ -22,5 +22,5 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
   set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Bdynamic")
 endforeach()
 
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake
index 022b4d4..50d68ee 100644
--- a/Modules/Compiler/SunPro-CXX.cmake
+++ b/Modules/Compiler/SunPro-CXX.cmake
@@ -22,8 +22,8 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
   set(CMAKE_${type}_LINK_DYNAMIC_CXX_FLAGS "-Bdynamic")
 endforeach()
 
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
 
 # Create archives with "CC -xar" in case user adds "-instances=extern"
 # so that template instantiations are available to archive members.
@@ -36,8 +36,13 @@ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
   set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=c++11")
 endif()
 
-if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
-  set(CMAKE_CXX_STANDARD_DEFAULT 98)
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+  if (NOT CMAKE_CXX_COMPILER_FORCED)
+    if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+      message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+    endif()
+    set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
+  endif()
 endif()
 
 macro(cmake_record_cxx_compile_features)
diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake
index 196aae4..610e191 100644
--- a/Modules/Compiler/SunPro-Fortran.cmake
+++ b/Modules/Compiler/SunPro-Fortran.cmake
@@ -18,5 +18,5 @@ set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-g -xO2 -DNDEBUG")
 set(CMAKE_Fortran_MODDIR_FLAG "-moddir=")
 set(CMAKE_Fortran_MODPATH_FLAG "-M")
 
-set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -F <SOURCE> -o <PREPROCESSED_SOURCE>")
-set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -F <SOURCE> -o <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/TI-ASM.cmake b/Modules/Compiler/TI-ASM.cmake
index e097626..a566d70 100644
--- a/Modules/Compiler/TI-ASM.cmake
+++ b/Modules/Compiler/TI-ASM.cmake
@@ -2,7 +2,7 @@ set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
 set(CMAKE_LINK_LIBRARY_FLAG "--library=")
 set(CMAKE_INCLUDE_FLAG_ASM "--include_path=")
 
-set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> --compile_only --asm_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<OBJECT>")
+set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> --compile_only --asm_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
 set(CMAKE_ASM_LINK_EXECUTABLE "<CMAKE_ASM_COMPILER> <OBJECTS> --run_linker --output_file=<TARGET> <CMAKE_ASM_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
 
 set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm;s;abs)
diff --git a/Modules/Compiler/TI-C.cmake b/Modules/Compiler/TI-C.cmake
index b580994..479666c 100644
--- a/Modules/Compiler/TI-C.cmake
+++ b/Modules/Compiler/TI-C.cmake
@@ -2,9 +2,9 @@ set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
 set(CMAKE_LINK_LIBRARY_FLAG "--library=")
 set(CMAKE_INCLUDE_FLAG_C "--include_path=")
 
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> --compile_only --skip_assembler --c_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> --preproc_only --c_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> --compile_only --skip_assembler --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> --preproc_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
 
-set(CMAKE_C_COMPILE_OBJECT  "<CMAKE_C_COMPILER> --compile_only --c_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<OBJECT>")
+set(CMAKE_C_COMPILE_OBJECT  "<CMAKE_C_COMPILER> --compile_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
 set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_C_LINK_FLAGS> <LINK_LIBRARIES> <LINK_FLAGS> <OBJECTS>")
diff --git a/Modules/Compiler/TI-CXX.cmake b/Modules/Compiler/TI-CXX.cmake
index 8cf5ac3..4104c3b 100644
--- a/Modules/Compiler/TI-CXX.cmake
+++ b/Modules/Compiler/TI-CXX.cmake
@@ -2,9 +2,9 @@ set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
 set(CMAKE_LINK_LIBRARY_FLAG "--library=")
 set(CMAKE_INCLUDE_FLAG_CXX "--include_path=")
 
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> --compile_only --skip_assembler --cpp_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> --preproc_only --cpp_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> --compile_only --skip_assembler --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> --preproc_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
 
-set(CMAKE_CXX_COMPILE_OBJECT  "<CMAKE_CXX_COMPILER> --compile_only --cpp_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<OBJECT>")
+set(CMAKE_CXX_COMPILE_OBJECT  "<CMAKE_CXX_COMPILER> --compile_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
 set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
 set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_CXX_LINK_FLAGS> <LINK_LIBRARIES> <LINK_FLAGS> <OBJECTS>")
diff --git a/Modules/Compiler/XL-ASM.cmake b/Modules/Compiler/XL-ASM.cmake
index 07507f9..212179e 100644
--- a/Modules/Compiler/XL-ASM.cmake
+++ b/Modules/Compiler/XL-ASM.cmake
@@ -1,9 +1,8 @@
 set(CMAKE_ASM_VERBOSE_FLAG "-V")
 
 # -qthreaded     = Ensures that all optimizations will be thread-safe
-# -qalias=noansi = Turns off type-based aliasing completely (safer optimizer)
 # -qhalt=e       = Halt on error messages (rather than just severe errors)
-set(CMAKE_ASM_FLAGS_INIT "-qthreaded -qalias=noansi -qhalt=e -qsourcetype=assembler")
+set(CMAKE_ASM_FLAGS_INIT "-qthreaded -qhalt=e -qsourcetype=assembler")
 
 set(CMAKE_ASM_FLAGS_DEBUG_INIT "-g")
 set(CMAKE_ASM_FLAGS_RELEASE_INIT "-O -DNDEBUG")
diff --git a/Modules/Compiler/XL-C.cmake b/Modules/Compiler/XL-C.cmake
index 09a5529..97dd017 100644
--- a/Modules/Compiler/XL-C.cmake
+++ b/Modules/Compiler/XL-C.cmake
@@ -4,6 +4,5 @@ set(CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT} -DNDEBUG")
 set(CMAKE_C_FLAGS_MINSIZEREL_INIT "${CMAKE_C_FLAGS_MINSIZEREL_INIT} -DNDEBUG")
 
 # -qthreaded     = Ensures that all optimizations will be thread-safe
-# -qalias=noansi = Turns off type-based aliasing completely (safer optimizer)
 # -qhalt=e       = Halt on error messages (rather than just severe errors)
-set(CMAKE_C_FLAGS_INIT "-qthreaded -qalias=noansi -qhalt=e")
+set(CMAKE_C_FLAGS_INIT "-qthreaded -qhalt=e")
diff --git a/Modules/Compiler/XL-CXX.cmake b/Modules/Compiler/XL-CXX.cmake
index 6c842cd..41372c1 100644
--- a/Modules/Compiler/XL-CXX.cmake
+++ b/Modules/Compiler/XL-CXX.cmake
@@ -8,4 +8,4 @@ set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "${CMAKE_CXX_FLAGS_MINSIZEREL_INIT} -DNDEBUG
 set(CMAKE_CXX_FLAGS_INIT "-qthreaded -qhalt=e")
 
 set(CMAKE_CXX_COMPILE_OBJECT
-  "<CMAKE_CXX_COMPILER> -+ <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+  "<CMAKE_CXX_COMPILER> -+ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
diff --git a/Modules/Compiler/XL.cmake b/Modules/Compiler/XL.cmake
index 7bf5020..bf4f554 100644
--- a/Modules/Compiler/XL.cmake
+++ b/Modules/Compiler/XL.cmake
@@ -33,8 +33,8 @@ macro(__compiler_xl lang)
   set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-O")
   set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-O")
   set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-g")
-  set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-  set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE     "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+  set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+  set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE     "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
 
   # CMAKE_XL_CreateExportList is part of the AIX XL compilers but not the linux ones.
   # If we found the tool, we'll use it to create exports, otherwise stick with the regular
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index a17d03d..2870a11 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -12,6 +12,7 @@
     <Keyword>Win32Proj</Keyword>
     @id_system@
     @id_system_version@
+    @id_WindowsTargetPlatformVersion@
     @id_WindowsSDKDesktopARMSupport@
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
diff --git a/Modules/CompilerId/main.swift.in b/Modules/CompilerId/main.swift.in
new file mode 100644
index 0000000..13f0ba0
--- /dev/null
+++ b/Modules/CompilerId/main.swift.in
@@ -0,0 +1 @@
+print("CMakeSwiftCompilerId")
diff --git a/Modules/DartConfiguration.tcl.in b/Modules/DartConfiguration.tcl.in
index 37a0a40..2da8354 100644
--- a/Modules/DartConfiguration.tcl.in
+++ b/Modules/DartConfiguration.tcl.in
@@ -69,6 +69,7 @@ UpdateType: @UPDATE_TYPE@
 
 # Compiler info
 Compiler: @CMAKE_CXX_COMPILER@
+CompilerVersion: @CMAKE_CXX_COMPILER_VERSION@
 
 # Dynamic analysis (MemCheck)
 PurifyCommand: @PURIFYCOMMAND@
@@ -95,6 +96,10 @@ SlurmRunCommand: @SLURM_SRUN_COMMAND@
 # Currently set to 25 minutes
 TimeOut: @DART_TESTING_TIMEOUT@
 
+# During parallel testing CTest will not start a new test if doing
+# so would cause the system load to exceed this value.
+TestLoad: @CTEST_TEST_LOAD@
+
 UseLaunchers: @CTEST_USE_LAUNCHERS@
 CurlOptions: @CTEST_CURL_OPTIONS@
 # warning, if you add new options here that have to do with submit,
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 11a24b8..c822bdb 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -175,6 +175,23 @@ Create custom targets to build projects in external trees
   ``LOG_INSTALL 1``
     Wrap install in script to log output
 
+  Steps can be given direct access to the terminal if possible.  With
+  the :generator:`Ninja` generator, this places the steps in the
+  ``console`` :prop_gbl:`pool <JOB_POOLS>`.  Options are:
+
+  ``USES_TERMINAL_DOWNLOAD 1``
+    Give download terminal access.
+  ``USES_TERMINAL_UPDATE 1``
+    Give update terminal access.
+  ``USES_TERMINAL_CONFIGURE 1``
+    Give configure terminal access.
+  ``USES_TERMINAL_BUILD 1``
+    Give build terminal access.
+  ``USES_TERMINAL_TEST 1``
+    Give test terminal access.
+  ``USES_TERMINAL_INSTALL 1``
+    Give install terminal access.
+
   Other options are:
 
   ``STEP_TARGETS <step-target>...``
@@ -256,6 +273,8 @@ Create custom targets to build projects in external trees
     Working directory for command
   ``LOG 1``
     Wrap step in script to log output
+  ``USES_TERMINAL 1``
+    Give the step direct access to the terminal if possible.
 
   The command line, comment, working directory, and byproducts of every
   standard and custom step are processed to replace tokens ``<SOURCE_DIR>``,
@@ -529,7 +548,7 @@ if(error_code)
 endif()
 
 execute_process(
-  COMMAND \"${git_EXECUTABLE}\" submodule init
+  COMMAND \"${git_EXECUTABLE}\" submodule init ${git_submodules}
   WORKING_DIRECTORY \"${work_dir}/${src_name}\"
   RESULT_VARIABLE error_code
   )
@@ -590,7 +609,7 @@ if(error_code)
 endif()
 
 execute_process(
-  COMMAND \"${hg_EXECUTABLE}\" clone \"${hg_repository}\" \"${src_name}\"
+  COMMAND \"${hg_EXECUTABLE}\" clone -U \"${hg_repository}\" \"${src_name}\"
   WORKING_DIRECTORY \"${work_dir}\"
   RESULT_VARIABLE error_code
   )
@@ -627,6 +646,11 @@ endfunction()
 
 
 function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_submodules git_repository work_dir)
+  if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.6)
+    set(git_stash_save_options --all --quiet)
+  else()
+    set(git_stash_save_options --quiet)
+  endif()
   file(WRITE ${script_filename}
 "if(\"${git_tag}\" STREQUAL \"\")
   message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
@@ -705,7 +729,7 @@ if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\"
     # perform git pull --rebase
     if(need_stash)
       execute_process(
-        COMMAND \"${git_EXECUTABLE}\" stash save --all --quiet
+        COMMAND \"${git_EXECUTABLE}\" stash save ${git_stash_save_options}
         WORKING_DIRECTORY \"${work_dir}\"
         RESULT_VARIABLE error_code
         )
@@ -1192,7 +1216,7 @@ function(_ep_get_build_command name step cmd_var)
         if(step STREQUAL "INSTALL")
           set(args install)
         endif()
-        if(step STREQUAL "TEST")
+        if("x${step}x" STREQUAL "xTESTx")
           set(args test)
         endif()
       else()
@@ -1211,7 +1235,7 @@ function(_ep_get_build_command name step cmd_var)
           list(APPEND args --target install)
         endif()
         # But for "TEST" drive the project with corresponding "ctest".
-        if(step STREQUAL "TEST")
+        if("x${step}x" STREQUAL "xTESTx")
           string(REGEX REPLACE "^(.*/)cmake([^/]*)$" "\\1ctest\\2" cmd "${cmd}")
           set(args "")
         endif()
@@ -1227,7 +1251,7 @@ function(_ep_get_build_command name step cmd_var)
       if(step STREQUAL "INSTALL")
         set(args install)
       endif()
-      if(step STREQUAL "TEST")
+      if("x${step}x" STREQUAL "xTESTx")
         set(args test)
       endif()
     endif()
@@ -1463,6 +1487,14 @@ function(ExternalProject_Add_Step name step)
     get_property(comment TARGET ${name} PROPERTY _EP_${step}_COMMENT)
   endif()
 
+  # Uses terminal?
+  get_property(uses_terminal TARGET ${name} PROPERTY _EP_${step}_USES_TERMINAL)
+  if(uses_terminal)
+    set(uses_terminal USES_TERMINAL)
+  else()
+    set(uses_terminal "")
+  endif()
+
   # Run every time?
   get_property(always TARGET ${name} PROPERTY _EP_${step}_ALWAYS)
   if(always)
@@ -1505,6 +1537,7 @@ function(ExternalProject_Add_Step name step)
     DEPENDS ${depends}
     WORKING_DIRECTORY ${work_dir}
     VERBATIM
+    ${uses_terminal}
     )
   set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step})
 
@@ -1603,20 +1636,6 @@ function(_ep_add_mkdir_command name)
 endfunction()
 
 
-function(_ep_get_git_version git_EXECUTABLE git_version_var)
-  if(git_EXECUTABLE)
-    execute_process(
-      COMMAND "${git_EXECUTABLE}" --version
-      OUTPUT_VARIABLE ov
-      ERROR_VARIABLE ev
-      OUTPUT_STRIP_TRAILING_WHITESPACE
-      )
-    string(REGEX REPLACE "^git version (.+)$" "\\1" version "${ov}")
-    set(${git_version_var} "${version}" PARENT_SCOPE)
-  endif()
-endfunction()
-
-
 function(_ep_is_dir_empty dir empty_var)
   file(GLOB gr "${dir}/*")
   if("${gr}" STREQUAL "")
@@ -1712,6 +1731,7 @@ function(_ep_add_download_command name)
       --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args} ${src_name})
     list(APPEND depends ${stamp_dir}/${name}-svninfo.txt)
   elseif(git_repository)
+    unset(CMAKE_MODULE_PATH) # Use CMake builtin find module
     find_package(Git QUIET)
     if(NOT GIT_EXECUTABLE)
       message(FATAL_ERROR "error: could not find git for clone of ${name}")
@@ -1719,9 +1739,8 @@ function(_ep_add_download_command name)
 
     # The git submodule update '--recursive' flag requires git >= v1.6.5
     #
-    _ep_get_git_version("${GIT_EXECUTABLE}" git_version)
-    if(git_version VERSION_LESS 1.6.5)
-      message(FATAL_ERROR "error: git version 1.6.5 or later required for 'git submodule update --recursive': git_version='${git_version}'")
+    if(GIT_VERSION_STRING VERSION_LESS 1.6.5)
+      message(FATAL_ERROR "error: git version 1.6.5 or later required for 'git submodule update --recursive': GIT_VERSION_STRING='${GIT_VERSION_STRING}'")
     endif()
 
     get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG)
@@ -1890,6 +1909,14 @@ function(_ep_add_download_command name)
     set(log "")
   endif()
 
+  get_property(uses_terminal TARGET ${name} PROPERTY
+    _EP_USES_TERMINAL_DOWNLOAD)
+  if(uses_terminal)
+    set(uses_terminal USES_TERMINAL 1)
+  else()
+    set(uses_terminal "")
+  endif()
+
   ExternalProject_Add_Step(${name} download
     COMMENT ${comment}
     COMMAND ${cmd}
@@ -1897,6 +1924,7 @@ function(_ep_add_download_command name)
     DEPENDS ${depends}
     DEPENDEES mkdir
     ${log}
+    ${uses_terminal}
     )
 endfunction()
 
@@ -2001,6 +2029,14 @@ Update to Mercurial >= 2.1.1.
     set(log "")
   endif()
 
+  get_property(uses_terminal TARGET ${name} PROPERTY
+    _EP_USES_TERMINAL_UPDATE)
+  if(uses_terminal)
+    set(uses_terminal USES_TERMINAL 1)
+  else()
+    set(uses_terminal "")
+  endif()
+
   ExternalProject_Add_Step(${name} update
     COMMENT ${comment}
     COMMAND ${cmd}
@@ -2009,6 +2045,7 @@ Update to Mercurial >= 2.1.1.
     WORKING_DIRECTORY ${work_dir}
     DEPENDEES download
     ${log}
+    ${uses_terminal}
     )
 
   if(always AND update_disconnected)
@@ -2021,6 +2058,7 @@ Update to Mercurial >= 2.1.1.
       WORKING_DIRECTORY ${work_dir}
       DEPENDEES download
       ${log}
+      ${uses_terminal}
     )
     set_property(SOURCE ${skip-update_stamp_file} PROPERTY SYMBOLIC 1)
   endif()
@@ -2149,6 +2187,14 @@ function(_ep_add_configure_command name)
     set(log "")
   endif()
 
+  get_property(uses_terminal TARGET ${name} PROPERTY
+    _EP_USES_TERMINAL_CONFIGURE)
+  if(uses_terminal)
+    set(uses_terminal USES_TERMINAL 1)
+  else()
+    set(uses_terminal "")
+  endif()
+
   get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
   if(update_disconnected_set)
     get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
@@ -2167,6 +2213,7 @@ function(_ep_add_configure_command name)
     DEPENDEES ${update_dep} patch
     DEPENDS ${file_deps}
     ${log}
+    ${uses_terminal}
     )
 endfunction()
 
@@ -2188,6 +2235,14 @@ function(_ep_add_build_command name)
     set(log "")
   endif()
 
+  get_property(uses_terminal TARGET ${name} PROPERTY
+    _EP_USES_TERMINAL_BUILD)
+  if(uses_terminal)
+    set(uses_terminal USES_TERMINAL 1)
+  else()
+    set(uses_terminal "")
+  endif()
+
   get_property(build_always TARGET ${name} PROPERTY _EP_BUILD_ALWAYS)
   if(build_always)
     set(always 1)
@@ -2204,6 +2259,7 @@ function(_ep_add_build_command name)
     DEPENDEES configure
     ALWAYS ${always}
     ${log}
+    ${uses_terminal}
     )
 endfunction()
 
@@ -2225,11 +2281,20 @@ function(_ep_add_install_command name)
     set(log "")
   endif()
 
+  get_property(uses_terminal TARGET ${name} PROPERTY
+    _EP_USES_TERMINAL_INSTALL)
+  if(uses_terminal)
+    set(uses_terminal USES_TERMINAL 1)
+  else()
+    set(uses_terminal "")
+  endif()
+
   ExternalProject_Add_Step(${name} install
     COMMAND ${cmd}
     WORKING_DIRECTORY ${binary_dir}
     DEPENDEES build
     ${log}
+    ${uses_terminal}
     )
 endfunction()
 
@@ -2277,6 +2342,14 @@ function(_ep_add_test_command name)
       set(log "")
     endif()
 
+    get_property(uses_terminal TARGET ${name} PROPERTY
+      _EP_USES_TERMINAL_TEST)
+    if(uses_terminal)
+      set(uses_terminal USES_TERMINAL 1)
+    else()
+      set(uses_terminal "")
+    endif()
+
     ExternalProject_Add_Step(${name} test
       COMMAND ${cmd}
       WORKING_DIRECTORY ${binary_dir}
@@ -2284,6 +2357,7 @@ function(_ep_add_test_command name)
       ${dependers_args}
       ${exclude_args}
       ${log}
+      ${uses_terminal}
       )
   endif()
 endfunction()
diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake
index ec3ee78..7d81276 100644
--- a/Modules/FindBISON.cmake
+++ b/Modules/FindBISON.cmake
@@ -2,60 +2,75 @@
 # FindBISON
 # ---------
 #
-# Find bison executable and provides macros to generate custom build rules
+# Find ``bison`` executable and provide a macro to generate custom build rules.
 #
 # The module defines the following variables:
 #
-# ::
+# ``BISON_EXECUTABLE``
+#   path to the ``bison`` program
 #
-#   BISON_EXECUTABLE - path to the bison program
-#   BISON_VERSION - version of bison
-#   BISON_FOUND - true if the program was found
+# ``BISON_VERSION``
+#   version of ``bison``
 #
+# ``BISON_FOUND``
+#   true if the program was found
 #
+# The minimum required version of ``bison`` can be specified using the
+# standard CMake syntax, e.g.  ``find_package(BISON 2.1.3)``.
 #
-# The minimum required version of bison can be specified using the
-# standard CMake syntax, e.g.  find_package(BISON 2.1.3)
+# If ``bison`` is found, the module defines the macro::
 #
-# If bison is found, the module defines the macros:
+#   BISON_TARGET(<Name> <YaccInput> <CodeOutput>
+#                [COMPILE_FLAGS <flags>]
+#                [DEFINES_FILE <file>]
+#                [VERBOSE <file>]
+#                )
 #
-# ::
+# which will create a custom rule to generate a parser.  ``<YaccInput>`` is
+# the path to a yacc file.  ``<CodeOutput>`` is the name of the source file
+# generated by bison.  A header file is also be generated, and contains
+# the token list.
 #
-#   BISON_TARGET(<Name> <YaccInput> <CodeOutput> [VERBOSE <file>]
-#               [COMPILE_FLAGS <string>])
+# The options are:
 #
-# which will create a custom rule to generate a parser.  <YaccInput> is
-# the path to a yacc file.  <CodeOutput> is the name of the source file
-# generated by bison.  A header file is also be generated, and contains
-# the token list.  If COMPILE_FLAGS option is specified, the next
-# parameter is added in the bison command line.  if VERBOSE option is
-# specified, <file> is created and contains verbose descriptions of the
-# grammar and parser.  The macro defines a set of variables:
+# ``COMPILE_FLAGS <flags>``
+#   Specify flags to be added to the ``bison`` command line.
+#
+# ``DEFINES_FILE <file>``
+#   Specify a non-default header ``<file>`` to be generated by ``bison``.
+#
+# ``VERBOSE <file>``
+#   Tell ``bison`` to write verbose descriptions of the grammar and
+#   parser to the given ``<file>``.
 #
-# ::
+# The macro defines the following variables:
 #
-#   BISON_${Name}_DEFINED - true is the macro ran successfully
-#   BISON_${Name}_INPUT - The input source file, an alias for <YaccInput>
-#   BISON_${Name}_OUTPUT_SOURCE - The source file generated by bison
-#   BISON_${Name}_OUTPUT_HEADER - The header file generated by bison
-#   BISON_${Name}_OUTPUTS - The sources files generated by bison
-#   BISON_${Name}_COMPILE_FLAGS - Options used in the bison command line
+# ``BISON_<Name>_DEFINED``
+#   true is the macro ran successfully
 #
+# ``BISON_<Name>_INPUT``
+#   The input source file, an alias for <YaccInput>
 #
+# ``BISON_<Name>_OUTPUT_SOURCE``
+#   The source file generated by bison
 #
-# ::
+# ``BISON_<Name>_OUTPUT_HEADER``
+#   The header file generated by bison
 #
-#   ====================================================================
-#   Example:
+# ``BISON_<Name>_OUTPUTS``
+#   The sources files generated by bison
 #
+# ``BISON_<Name>_COMPILE_FLAGS``
+#   Options used in the ``bison`` command line
 #
+# Example usage:
 #
-# ::
+# .. code-block:: cmake
 #
-#    find_package(BISON)
-#    BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
-#    add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
-#   ====================================================================
+#   find_package(BISON)
+#   BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp
+#                DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.h)
+#   add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
 
 #=============================================================================
 # Copyright 2009 Kitware, Inc.
@@ -74,6 +89,8 @@
 find_program(BISON_EXECUTABLE NAMES bison win_bison DOC "path to the bison executable")
 mark_as_advanced(BISON_EXECUTABLE)
 
+include(CMakeParseArguments)
+
 if(BISON_EXECUTABLE)
   # the bison commands should be executed with the C locale, otherwise
   # the message (which are parsed) may be translated
@@ -128,6 +145,12 @@ if(BISON_EXECUTABLE)
     list(APPEND BISON_TARGET_cmdopt ${BISON_TARGET_extraopts})
   endmacro()
 
+  # internal macro
+  macro(BISON_TARGET_option_defines Header)
+    set(BISON_TARGET_output_header "${Header}")
+    list(APPEND BISON_TARGET_cmdopt --defines=${BISON_TARGET_output_header})
+  endmacro()
+
   #============================================================
   # BISON_TARGET (public macro)
   #============================================================
@@ -136,51 +159,61 @@ if(BISON_EXECUTABLE)
     set(BISON_TARGET_output_header "")
     set(BISON_TARGET_cmdopt "")
     set(BISON_TARGET_outputs "${BisonOutput}")
-    if(NOT ${ARGC} EQUAL 3 AND NOT ${ARGC} EQUAL 5 AND NOT ${ARGC} EQUAL 7)
+
+    # Parsing parameters
+    set(BISON_TARGET_PARAM_OPTIONS)
+    set(BISON_TARGET_PARAM_ONE_VALUE_KEYWORDS
+      VERBOSE
+      COMPILE_FLAGS
+      DEFINES_FILE
+      )
+    set(BISON_TARGET_PARAM_MULTI_VALUE_KEYWORDS)
+    cmake_parse_arguments(
+        BISON_TARGET_ARG
+        "${BISON_TARGET_PARAM_OPTIONS}"
+        "${BISON_TARGET_PARAM_ONE_VALUE_KEYWORDS}"
+        "${BISON_TARGET_PARAM_MULTI_VALUE_KEYWORDS}"
+        ${ARGN}
+    )
+
+    if(NOT "${BISON_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
       message(SEND_ERROR "Usage")
     else()
-      # Parsing parameters
-      if(${ARGC} GREATER 5 OR ${ARGC} EQUAL 5)
-        if("${ARGV3}" STREQUAL "VERBOSE")
-          BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV4}")
-        endif()
-        if("${ARGV3}" STREQUAL "COMPILE_FLAGS")
-          BISON_TARGET_option_extraopts("${ARGV4}")
-        endif()
+      if(NOT "${BISON_TARGET_ARG_VERBOSE}" STREQUAL "")
+        BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${BISON_TARGET_ARG_VERBOSE}")
       endif()
-
-      if(${ARGC} EQUAL 7)
-        if("${ARGV5}" STREQUAL "VERBOSE")
-          BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV6}")
-        endif()
-
-        if("${ARGV5}" STREQUAL "COMPILE_FLAGS")
-          BISON_TARGET_option_extraopts("${ARGV6}")
-        endif()
+      if(NOT "${BISON_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "")
+        BISON_TARGET_option_extraopts("${BISON_TARGET_ARG_COMPILE_FLAGS}")
+      endif()
+      if(NOT "${BISON_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
+        BISON_TARGET_option_defines("${BISON_TARGET_ARG_DEFINES_FILE}")
       endif()
 
-      # Header's name generated by bison (see option -d)
-      list(APPEND BISON_TARGET_cmdopt "-d")
-      string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${ARGV2}")
-      string(REPLACE "c" "h" _fileext ${_fileext})
-      string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}"
-          BISON_${Name}_OUTPUT_HEADER "${ARGV2}")
-      list(APPEND BISON_TARGET_outputs "${BISON_${Name}_OUTPUT_HEADER}")
+      if("${BISON_TARGET_output_header}" STREQUAL "")
+        # Header's name generated by bison (see option -d)
+        list(APPEND BISON_TARGET_cmdopt "-d")
+        string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${BisonOutput}")
+        string(REPLACE "c" "h" _fileext ${_fileext})
+        string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}"
+            BISON_TARGET_output_header "${BisonOutput}")
+      endif()
+      list(APPEND BISON_TARGET_outputs "${BISON_TARGET_output_header}")
 
       add_custom_command(OUTPUT ${BISON_TARGET_outputs}
         ${BISON_TARGET_extraoutputs}
         COMMAND ${BISON_EXECUTABLE}
-        ARGS ${BISON_TARGET_cmdopt} -o ${ARGV2} ${ARGV1}
-        DEPENDS ${ARGV1}
+        ARGS ${BISON_TARGET_cmdopt} -o ${BisonOutput} ${BisonInput}
+        DEPENDS ${BisonInput}
         COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}"
         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 
       # define target variables
       set(BISON_${Name}_DEFINED TRUE)
-      set(BISON_${Name}_INPUT ${ARGV1})
+      set(BISON_${Name}_INPUT ${BisonInput})
       set(BISON_${Name}_OUTPUTS ${BISON_TARGET_outputs})
       set(BISON_${Name}_COMPILE_FLAGS ${BISON_TARGET_cmdopt})
       set(BISON_${Name}_OUTPUT_SOURCE "${BisonOutput}")
+      set(BISON_${Name}_OUTPUT_HEADER "${BISON_TARGET_output_header}")
 
     endif()
   endmacro()
diff --git a/Modules/FindBZip2.cmake b/Modules/FindBZip2.cmake
index b479332..6af42dd 100644
--- a/Modules/FindBZip2.cmake
+++ b/Modules/FindBZip2.cmake
@@ -56,11 +56,13 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(BZip2
                                   VERSION_VAR BZIP2_VERSION_STRING)
 
 if (BZIP2_FOUND)
-   include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
+   include(${CMAKE_CURRENT_LIST_DIR}/CheckSymbolExists.cmake)
    include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
    cmake_push_check_state()
    set(CMAKE_REQUIRED_QUIET ${BZip2_FIND_QUIETLY})
-   CHECK_LIBRARY_EXISTS("${BZIP2_LIBRARIES}" BZ2_bzCompressInit "" BZIP2_NEED_PREFIX)
+   set(CMAKE_REQUIRED_INCLUDES ${BZIP2_INCLUDE_DIR})
+   set(CMAKE_REQUIRED_LIBRARIES ${BZIP2_LIBRARIES})
+   CHECK_SYMBOL_EXISTS(BZ2_bzCompressInit "bzlib.h" BZIP2_NEED_PREFIX)
    cmake_pop_check_state()
 endif ()
 
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 05b552a..33e6a49 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -512,13 +512,15 @@ else()
   # The user has not requested an exact version.  Among known
   # versions, find those that are acceptable to the user request.
   set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
-    "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55" "1.54.0" "1.54"
-    "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51"
+
+    "1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55"
+    "1.54.0" "1.54" "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51"
     "1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1"
     "1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42"
     "1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37"
     "1.36.1" "1.36.0" "1.36" "1.35.1" "1.35.0" "1.35" "1.34.1" "1.34.0"
     "1.34" "1.33.1" "1.33.0" "1.33")
+
   set(_boost_TEST_VERSIONS)
   if(Boost_FIND_VERSION)
     set(_Boost_FIND_VERSION_SHORT "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index e8e1fb1..1fc582f 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -468,17 +468,31 @@ set(CUDA_NVCC_FLAGS "" CACHE STRING "Semi-colon delimit multiple arguments.")
 if(CMAKE_GENERATOR MATCHES "Visual Studio")
   set(CUDA_HOST_COMPILER "$(VCInstallDir)bin" CACHE FILEPATH "Host side compiler used by NVCC")
 else()
-  # Using cc which is symlink to clang may let NVCC think it is GCC and issue
-  # unhandled -dumpspecs option to clang. Also in case neither
-  # CMAKE_C_COMPILER is defined (project does not use C language) nor
-  # CUDA_HOST_COMPILER is specified manually we should skip -ccbin and let
-  # nvcc use its own default C compiler.
-  if(DEFINED CMAKE_C_COMPILER AND NOT DEFINED CUDA_HOST_COMPILER)
-    get_filename_component(c_compiler_realpath "${CMAKE_C_COMPILER}" REALPATH)
+  if(APPLE
+      AND "${CMAKE_C_COMPILER_ID}" MATCHES "Clang"
+      AND "${CMAKE_C_COMPILER}" MATCHES "/cc$")
+    # Using cc which is symlink to clang may let NVCC think it is GCC and issue
+    # unhandled -dumpspecs option to clang. Also in case neither
+    # CMAKE_C_COMPILER is defined (project does not use C language) nor
+    # CUDA_HOST_COMPILER is specified manually we should skip -ccbin and let
+    # nvcc use its own default C compiler.
+    # Only care about this on APPLE with clang to avoid
+    # following symlinks to things like ccache
+    if(DEFINED CMAKE_C_COMPILER AND NOT DEFINED CUDA_HOST_COMPILER)
+      get_filename_component(c_compiler_realpath "${CMAKE_C_COMPILER}" REALPATH)
+      # if the real path does not end up being clang then
+      # go back to using CMAKE_C_COMPILER
+      if(NOT "${c_compiler_realpath}" MATCHES "/clang$")
+        set(c_compiler_realpath "${CMAKE_C_COMPILER}")
+      endif()
+    else()
+      set(c_compiler_realpath "")
+    endif()
+    set(CUDA_HOST_COMPILER "${c_compiler_realpath}" CACHE FILEPATH "Host side compiler used by NVCC")
   else()
-    set(c_compiler_realpath "")
+    set(CUDA_HOST_COMPILER "${CMAKE_C_COMPILER}"
+      CACHE FILEPATH "Host side compiler used by NVCC")
   endif()
-  set(CUDA_HOST_COMPILER "${c_compiler_realpath}" CACHE FILEPATH "Host side compiler used by NVCC")
 endif()
 
 # Propagate the host flags to the host compiler via -Xcompiler
@@ -1570,9 +1584,8 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options
     # we work around that issue by compiling the intermediate link object as a
     # pre-link custom command in that situation.
     set(do_obj_build_rule TRUE)
-    if (MSVC_VERSION GREATER 1599)
-      # VS 2010 and 2012 have this problem.  If future versions fix this issue,
-      # it should still work, it just won't be as nice as the other method.
+    if (MSVC_VERSION GREATER 1599 AND MSVC_VERSION LESS 1800)
+      # VS 2010 and 2012 have this problem.
       set(do_obj_build_rule FALSE)
     endif()
 
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index 3bd6f1e..9f6e666 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -31,6 +31,12 @@
 # Find module will then look in this path when searching for HDF5
 # executables, paths, and libraries.
 #
+# Both the serial and parallel HDF5 wrappers are considered and the first
+# directory to contain either one will be used.  In the event that both appear
+# in the same directory the serial version is preferentially selected. This
+# behavior can be reversed by setting the variable HDF5_PREFER_PARALLEL to
+# true.
+#
 # In addition to finding the includes and libraries required to compile
 # an HDF5 client application, this module also makes an effort to find
 # tools that come with the HDF5 distribution that may be useful for
@@ -103,28 +109,43 @@ else()
     endforeach()
 endif()
 
+# Determine whether to search for serial or parallel executable first
+if(HDF5_PREFER_PARALLEL)
+  set(HDF5_C_COMPILER_NAMES h5pcc h5cc)
+  set(HDF5_CXX_COMPILER_NAMES h5pc++ h5c++)
+  set(HDF5_Fortran_COMPILER_NAMES h5pfc h5fc)
+else()
+  set(HDF5_C_COMPILER_NAMES h5cc h5pcc)
+  set(HDF5_CXX_COMPILER_NAMES h5c++ h5pc++)
+  set(HDF5_Fortran_COMPILER_NAMES h5fc h5pfc)
+endif()
+
 # try to find the HDF5 wrapper compilers
 find_program( HDF5_C_COMPILER_EXECUTABLE
-    NAMES h5cc h5pcc
+    NAMES ${HDF5_C_COMPILER_NAMES} NAMES_PER_DIR
     HINTS ENV HDF5_ROOT
     PATH_SUFFIXES bin Bin
     DOC "HDF5 Wrapper compiler.  Used only to detect HDF5 compile flags." )
 mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE )
 
 find_program( HDF5_CXX_COMPILER_EXECUTABLE
-    NAMES h5c++ h5pc++
+    NAMES ${HDF5_CXX_COMPILER_NAMES} NAMES_PER_DIR
     HINTS ENV HDF5_ROOT
     PATH_SUFFIXES bin Bin
     DOC "HDF5 C++ Wrapper compiler.  Used only to detect HDF5 compile flags." )
 mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE )
 
 find_program( HDF5_Fortran_COMPILER_EXECUTABLE
-    NAMES h5fc h5pfc
+    NAMES ${HDF5_Fortran_COMPILER_NAMES} NAMES_PER_DIR
     HINTS ENV HDF5_ROOT
     PATH_SUFFIXES bin Bin
     DOC "HDF5 Fortran Wrapper compiler.  Used only to detect HDF5 compile flags." )
 mark_as_advanced( HDF5_Fortran_COMPILER_EXECUTABLE )
 
+unset(HDF5_C_COMPILER_NAMES)
+unset(HDF5_CXX_COMPILER_NAMES)
+unset(HDF5_Fortran_COMPILER_NAMES)
+
 find_program( HDF5_DIFF_EXECUTABLE
     NAMES h5diff
     HINTS ENV HDF5_ROOT
@@ -225,6 +246,8 @@ if( NOT HDF5_FOUND )
     _HDF5_invoke_compiler( C HDF5_C_COMPILE_LINE HDF5_C_RETURN_VALUE )
     _HDF5_invoke_compiler( CXX HDF5_CXX_COMPILE_LINE HDF5_CXX_RETURN_VALUE )
     _HDF5_invoke_compiler( Fortran HDF5_Fortran_COMPILE_LINE HDF5_Fortran_RETURN_VALUE )
+    set(HDF5_HL_COMPILE_LINE ${HDF5_C_COMPILE_LINE})
+    set(HDF5_Fortran_HL_COMPILE_LINE ${HDF5_Fortran_COMPILE_LINE})
 
     # seed the initial lists of libraries to find with items we know we need
     set( HDF5_C_LIBRARY_NAMES_INIT hdf5 )
@@ -232,7 +255,7 @@ if( NOT HDF5_FOUND )
     set( HDF5_CXX_LIBRARY_NAMES_INIT hdf5_cpp ${HDF5_C_LIBRARY_NAMES_INIT} )
     set( HDF5_Fortran_LIBRARY_NAMES_INIT hdf5_fortran
         ${HDF5_C_LIBRARY_NAMES_INIT} )
-    set( HDF5_Fortran_HL_LIBRARY_NAMES_INIT hdf5hl_fortran
+    set( HDF5_Fortran_HL_LIBRARY_NAMES_INIT hdf5hl_fortran hdf5_hl
         ${HDF5_Fortran_LIBRARY_NAMES_INIT} )
 
     foreach( LANGUAGE ${HDF5_LANGUAGE_BINDINGS} )
@@ -284,7 +307,7 @@ if( NOT HDF5_FOUND )
             if( UNIX AND HDF5_USE_STATIC_LIBRARIES )
                 # According to bug 1643 on the CMake bug tracker, this is the
                 # preferred method for searching for a static library.
-                # See http://www.cmake.org/Bug/view.php?id=1643.  We search
+                # See https://cmake.org/Bug/view.php?id=1643.  We search
                 # first for the full static library name, but fall back to a
                 # generic search on the name if the static search fails.
                 set( THIS_LIBRARY_SEARCH_DEBUG lib${LIB}d.a ${LIB}d )
@@ -376,4 +399,3 @@ find_package_handle_standard_args( HDF5
     REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS
     VERSION_VAR   HDF5_VERSION
 )
-
diff --git a/Modules/FindIce.cmake b/Modules/FindIce.cmake
index 8493d80..3fa6cab 100644
--- a/Modules/FindIce.cmake
+++ b/Modules/FindIce.cmake
@@ -20,7 +20,14 @@
 #   Ice_SLICE_DIRS - the directories containing the Ice slice interface
 #                    definitions
 #
-# Ice programs are reported in::
+# Imported targets::
+#
+#   Ice::<C>
+#
+# Where ``<C>`` is the name of an Ice component, for example
+# ``Ice::Glacier2``.
+#
+# Ice slice programs are reported in::
 #
 #   Ice_SLICE2CPP_EXECUTABLE - path to slice2cpp executable
 #   Ice_SLICE2CS_EXECUTABLE - path to slice2cs executable
@@ -28,10 +35,49 @@
 #   Ice_SLICE2FREEZE_EXECUTABLE - path to slice2freeze executable
 #   Ice_SLICE2HTML_EXECUTABLE - path to slice2html executable
 #   Ice_SLICE2JAVA_EXECUTABLE - path to slice2java executable
+#   Ice_SLICE2JS_EXECUTABLE - path to slice2js executable
 #   Ice_SLICE2PHP_EXECUTABLE - path to slice2php executable
 #   Ice_SLICE2PY_EXECUTABLE - path to slice2py executable
 #   Ice_SLICE2RB_EXECUTABLE - path to slice2rb executable
 #
+# Ice programs are reported in::
+#
+#   Ice_GLACIER2ROUTER_EXECUTABLE - path to glacier2router executable
+#   Ice_ICEBOX_EXECUTABLE - path to icebox executable
+#   Ice_ICEBOXADMIN_EXECUTABLE - path to iceboxadmin executable
+#   Ice_ICEBOXD_EXECUTABLE - path to iceboxd executable
+#   Ice_ICEBOXNET_EXECUTABLE - path to iceboxnet executable
+#   Ice_ICEGRIDADMIN_EXECUTABLE - path to icegridadmin executable
+#   Ice_ICEGRIDNODE_EXECUTABLE - path to icegridnode executable
+#   Ice_ICEGRIDNODED_EXECUTABLE - path to icegridnoded executable
+#   Ice_ICEGRIDREGISTRY_EXECUTABLE - path to icegridregistry executable
+#   Ice_ICEGRIDREGISTRYD_EXECUTABLE - path to icegridregistryd executable
+#   Ice_ICEPATCH2CALC_EXECUTABLE - path to icepatch2calc executable
+#   Ice_ICEPATCH2CLIENT_EXECUTABLE - path to icepatch2client executable
+#   Ice_ICEPATCH2SERVER_EXECUTABLE - path to icepatch2server executable
+#   Ice_ICESERVICEINSTALL_EXECUTABLE - path to iceserviceinstall executable
+#   Ice_ICESTORMADMIN_EXECUTABLE - path to icestormadmin executable
+#   Ice_ICESTORMMIGRATE_EXECUTABLE - path to icestormmigrate executable
+#
+# Ice db programs (Windows only; standard system versions on all other
+# platforms) are reported in::
+#
+#   Ice_DB_ARCHIVE_EXECUTABLE - path to db_archive executable
+#   Ice_DB_CHECKPOINT_EXECUTABLE - path to db_checkpoint executable
+#   Ice_DB_DEADLOCK_EXECUTABLE - path to db_deadlock executable
+#   Ice_DB_DUMP_EXECUTABLE - path to db_dump executable
+#   Ice_DB_HOTBACKUP_EXECUTABLE - path to db_hotbackup executable
+#   Ice_DB_LOAD_EXECUTABLE - path to db_load executable
+#   Ice_DB_LOG_VERIFY_EXECUTABLE - path to db_log_verify executable
+#   Ice_DB_PRINTLOG_EXECUTABLE - path to db_printlog executable
+#   Ice_DB_RECOVER_EXECUTABLE - path to db_recover executable
+#   Ice_DB_STAT_EXECUTABLE - path to db_stat executable
+#   Ice_DB_TUNER_EXECUTABLE - path to db_tuner executable
+#   Ice_DB_UPGRADE_EXECUTABLE - path to db_upgrade executable
+#   Ice_DB_VERIFY_EXECUTABLE - path to db_verify executable
+#   Ice_DUMPDB_EXECUTABLE - path to dumpdb executable
+#   Ice_TRANSFORMDB_EXECUTABLE - path to transformdb executable
+#
 # Ice component libraries are reported in::
 #
 #   Ice_<C>_FOUND - ON if component was found
@@ -76,7 +122,7 @@
 # Written by Roger Leigh <rleigh at codelibre.net>
 
 #=============================================================================
-# Copyright 2014 University of Dundee
+# Copyright 2014-2015 University of Dundee
 #
 # Distributed under the OSI-approved BSD License (the "License");
 # see accompanying file Copyright.txt for details.
@@ -94,6 +140,8 @@ function(_Ice_FIND)
   # Released versions of Ice, including generic short forms
   set(ice_versions
       3
+      3.6
+      3.6.0
       3.5
       3.5.1
       3.5.0
@@ -198,19 +246,55 @@ function(_Ice_FIND)
     endforeach()
   endif()
 
+  set(db_programs
+      db_archive
+      db_checkpoint
+      db_deadlock
+      db_dump
+      db_hotbackup
+      db_load
+      db_log_verify
+      db_printlog
+      db_recover
+      db_stat
+      db_tuner
+      db_upgrade
+      db_verify
+      dumpdb
+      transformdb)
+
   set(ice_programs
+      glacier2router
+      icebox
+      iceboxadmin
+      iceboxd
+      iceboxnet
+      icegridadmin
+      icegridnode
+      icegridnoded
+      icegridregistry
+      icegridregistryd
+      icepatch2calc
+      icepatch2client
+      icepatch2server
+      iceserviceinstall
+      icestormadmin
+      icestormmigrate)
+
+  set(slice_programs
       slice2cpp
       slice2cs
       slice2freezej
       slice2freeze
       slice2html
       slice2java
+      slice2js
       slice2php
       slice2py
       slice2rb)
 
   # Find all Ice programs
-  foreach(program ${ice_programs})
+  foreach(program ${db_programs} ${ice_programs} ${slice_programs})
     string(TOUPPER "${program}" program_upcase)
     set(cache_var "Ice_${program_upcase}_EXECUTABLE")
     set(program_var "Ice_${program_upcase}_EXECUTABLE")
@@ -356,13 +440,21 @@ if(Ice_FOUND)
     set(_Ice_component_cache "Ice_${_Ice_component_upcase}_LIBRARY")
     set(_Ice_component_lib "Ice_${_Ice_component_upcase}_LIBRARIES")
     set(_Ice_component_found "${_Ice_component_upcase}_FOUND")
+    set(_Ice_imported_target "Ice::${_Ice_component}")
     if(${_Ice_component_found})
       set("${_Ice_component_lib}" "${${_Ice_component_cache}}")
+      if(NOT TARGET ${_Ice_imported_target})
+        add_library(${_Ice_imported_target} UNKNOWN IMPORTED)
+        set_target_properties(${_Ice_imported_target} PROPERTIES
+          IMPORTED_LOCATION "${${_Ice_component_cache}}"
+          INTERFACE_INCLUDE_DIRECTORIES "${Ice_INCLUDE_DIR}")
+      endif()
     endif()
     unset(_Ice_component_upcase)
     unset(_Ice_component_cache)
     unset(_Ice_component_lib)
     unset(_Ice_component_found)
+    unset(_Ice_imported_target)
   endforeach()
 endif()
 
@@ -373,15 +465,51 @@ if(Ice_DEBUG)
   message(STATUS "Ice_INCLUDE_DIR directory: ${Ice_INCLUDE_DIR}")
   message(STATUS "Ice_SLICE_DIR directory: ${Ice_SLICE_DIR}")
   message(STATUS "Ice_LIBRARIES: ${Ice_LIBRARIES}")
+
   message(STATUS "slice2cpp executable: ${Ice_SLICE2CPP_EXECUTABLE}")
   message(STATUS "slice2cs executable: ${Ice_SLICE2CS_EXECUTABLE}")
   message(STATUS "slice2freezej executable: ${Ice_SLICE2FREEZEJ_EXECUTABLE}")
   message(STATUS "slice2freeze executable: ${Ice_SLICE2FREEZE_EXECUTABLE}")
   message(STATUS "slice2html executable: ${Ice_SLICE2HTML_EXECUTABLE}")
   message(STATUS "slice2java executable: ${Ice_SLICE2JAVA_EXECUTABLE}")
+  message(STATUS "slice2js executable: ${Ice_SLICE2JS_EXECUTABLE}")
   message(STATUS "slice2php executable: ${Ice_SLICE2PHP_EXECUTABLE}")
   message(STATUS "slice2py executable: ${Ice_SLICE2PY_EXECUTABLE}")
   message(STATUS "slice2rb executable: ${Ice_SLICE2RB_EXECUTABLE}")
+  message(STATUS "glacier2router executable: ${Ice_GLACIER2ROUTER_EXECUTABLE}")
+
+  message(STATUS "icebox executable: ${Ice_ICEBOX_EXECUTABLE}")
+  message(STATUS "iceboxadmin executable: ${Ice_ICEBOXADMIN_EXECUTABLE}")
+  message(STATUS "iceboxd executable: ${Ice_ICEBOXD_EXECUTABLE}")
+  message(STATUS "iceboxnet executable: ${Ice_ICEBOXNET_EXECUTABLE}")
+  message(STATUS "icegridadmin executable: ${Ice_ICEGRIDADMIN_EXECUTABLE}")
+  message(STATUS "icegridnode executable: ${Ice_ICEGRIDNODE_EXECUTABLE}")
+  message(STATUS "icegridnoded executable: ${Ice_ICEGRIDNODED_EXECUTABLE}")
+  message(STATUS "icegridregistry executable: ${Ice_ICEGRIDREGISTRY_EXECUTABLE}")
+  message(STATUS "icegridregistryd executable: ${Ice_ICEGRIDREGISTRYD_EXECUTABLE}")
+  message(STATUS "icepatch2calc executable: ${Ice_ICEPATCH2CALC_EXECUTABLE}")
+  message(STATUS "icepatch2client executable: ${Ice_ICEPATCH2CLIENT_EXECUTABLE}")
+  message(STATUS "icepatch2server executable: ${Ice_ICEPATCH2SERVER_EXECUTABLE}")
+  message(STATUS "iceserviceinstall executable: ${Ice_ICESERVICEINSTALL_EXECUTABLE}")
+  message(STATUS "icestormadmin executable: ${Ice_ICESTORMADMIN_EXECUTABLE}")
+  message(STATUS "icestormmigrate executable: ${Ice_ICESTORMMIGRATE_EXECUTABLE}")
+
+  message(STATUS "db_archive executable: ${Ice_DB_ARCHIVE_EXECUTABLE}")
+  message(STATUS "db_checkpoint executable: ${Ice_DB_CHECKPOINT_EXECUTABLE}")
+  message(STATUS "db_deadlock executable: ${Ice_DB_DEADLOCK_EXECUTABLE}")
+  message(STATUS "db_dump executable: ${Ice_DB_DUMP_EXECUTABLE}")
+  message(STATUS "db_hotbackup executable: ${Ice_DB_HOTBACKUP_EXECUTABLE}")
+  message(STATUS "db_load executable: ${Ice_DB_LOAD_EXECUTABLE}")
+  message(STATUS "db_log_verify executable: ${Ice_DB_LOG_VERIFY_EXECUTABLE}")
+  message(STATUS "db_printlog executable: ${Ice_DB_PRINTLOG_EXECUTABLE}")
+  message(STATUS "db_recover executable: ${Ice_DB_RECOVER_EXECUTABLE}")
+  message(STATUS "db_stat executable: ${Ice_DB_STAT_EXECUTABLE}")
+  message(STATUS "db_tuner executable: ${Ice_DB_TUNER_EXECUTABLE}")
+  message(STATUS "db_upgrade executable: ${Ice_DB_UPGRADE_EXECUTABLE}")
+  message(STATUS "db_verify executable: ${Ice_DB_VERIFY_EXECUTABLE}")
+  message(STATUS "dumpdb executable: ${Ice_DUMPDB_EXECUTABLE}")
+  message(STATUS "transformdb executable: ${Ice_TRANSFORMDB_EXECUTABLE}")
+
   foreach(component ${Ice_FIND_COMPONENTS})
     string(TOUPPER "${component}" component_upcase)
     set(component_lib "Ice_${component_upcase}_LIBRARIES")
diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake
index d248fe1..cbe21d7 100644
--- a/Modules/FindJNI.cmake
+++ b/Modules/FindJNI.cmake
@@ -42,7 +42,11 @@ macro(java_append_library_directories _var)
     # 1.6.0_18 + icedtea patches. However, it would be much better to base the
     # guess on the first part of the GNU config.guess platform triplet.
     if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+      if(CMAKE_LIBRARY_ARCHITECTURE STREQUAL "x86_64-linux-gnux32")
+        set(_java_libarch "x32" "amd64" "i386")
+      else()
         set(_java_libarch "amd64" "i386")
+      endif()
     elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
         set(_java_libarch "i386")
     elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^alpha")
@@ -53,7 +57,7 @@ macro(java_append_library_directories _var)
     elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
         # mips* machines are bi-endian mostly so processor does not tell
         # endianess of the underlying system.
-        set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "mips" "mipsel" "mipseb")
+        set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "mips" "mipsel" "mipseb" "mips64" "mips64el" "mipsn32" "mipsn32el")
     elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le")
         set(_java_libarch "ppc64" "ppc64le")
     elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
@@ -152,6 +156,9 @@ JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES
   /usr/local/jre-1.7.0/lib/{libarch}
   /usr/local/jdk-1.6.0/jre/lib/{libarch}
   /usr/local/jre-1.6.0/lib/{libarch}
+  # SuSE specific paths for default JVM
+  /usr/lib64/jvm/java/jre/lib/{libarch}
+  /usr/lib64/jvm/jre/lib/{libarch}
   )
 
 set(JAVA_JVM_LIBRARY_DIRECTORIES)
@@ -160,6 +167,9 @@ foreach(dir ${JAVA_AWT_LIBRARY_DIRECTORIES})
     "${dir}"
     "${dir}/client"
     "${dir}/server"
+    # IBM SDK, Java Technology Edition, specific paths
+    "${dir}/j9vm"
+    "${dir}/default"
     )
 endforeach()
 
@@ -189,6 +199,8 @@ list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES
   # OpenBSD specific path for default JVM
   /usr/local/jdk-1.7.0/include
   /usr/local/jdk-1.6.0/include
+  # SuSE specific paths for default JVM
+  /usr/lib64/jvm/java/include
   )
 
 foreach(JAVA_PROG "${JAVA_RUNTIME}" "${JAVA_COMPILE}" "${JAVA_ARCHIVE}")
diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake
index 9e43174..9f87997 100644
--- a/Modules/FindJava.cmake
+++ b/Modules/FindJava.cmake
@@ -8,21 +8,34 @@
 # include files and libraries are.  The caller may set variable JAVA_HOME
 # to specify a Java installation prefix explicitly.
 #
+#
+# Specify one or more of the following components as you call this find module. See example below.
+#
+# ::
+#
+#   Runtime     = User just want to execute some Java byte-compiled
+#   Development = Development tools (java, javac, javah and javadoc), includes Runtime component
+#   IdlJ        = idl compiler for Java
+#   JarSigner   = signer tool for jar
+#
+#
 # This module sets the following result variables:
 #
 # ::
 #
-#   Java_JAVA_EXECUTABLE    = the full path to the Java runtime
-#   Java_JAVAC_EXECUTABLE   = the full path to the Java compiler
-#   Java_JAVAH_EXECUTABLE   = the full path to the Java header generator
-#   Java_JAVADOC_EXECUTABLE = the full path to the Java documention generator
-#   Java_JAR_EXECUTABLE     = the full path to the Java archiver
-#   Java_VERSION_STRING     = Version of java found, eg. 1.6.0_12
-#   Java_VERSION_MAJOR      = The major version of the package found.
-#   Java_VERSION_MINOR      = The minor version of the package found.
-#   Java_VERSION_PATCH      = The patch version of the package found.
-#   Java_VERSION_TWEAK      = The tweak version of the package found (after '_')
-#   Java_VERSION            = This is set to: $major.$minor.$patch(.$tweak)
+#   Java_JAVA_EXECUTABLE      = the full path to the Java runtime
+#   Java_JAVAC_EXECUTABLE     = the full path to the Java compiler
+#   Java_JAVAH_EXECUTABLE     = the full path to the Java header generator
+#   Java_JAVADOC_EXECUTABLE   = the full path to the Java documention generator
+#   Java_IDLJ_EXECUTABLE      = the full path to the Java idl compiler
+#   Java_JAR_EXECUTABLE       = the full path to the Java archiver
+#   Java_JARSIGNER_EXECUTABLE = the full path to the Java jar signer
+#   Java_VERSION_STRING       = Version of java found, eg. 1.6.0_12
+#   Java_VERSION_MAJOR        = The major version of the package found.
+#   Java_VERSION_MINOR        = The minor version of the package found.
+#   Java_VERSION_PATCH        = The patch version of the package found.
+#   Java_VERSION_TWEAK        = The tweak version of the package found (after '_')
+#   Java_VERSION              = This is set to: $major.$minor.$patch(.$tweak)
 #
 #
 #
@@ -184,28 +197,61 @@ find_program(Java_JAVADOC_EXECUTABLE
   PATHS ${_JAVA_PATHS}
 )
 
+find_program(Java_IDLJ_EXECUTABLE
+  NAMES idlj
+  HINTS ${_JAVA_HINTS}
+  PATHS ${_JAVA_PATHS}
+)
+
+find_program(Java_JARSIGNER_EXECUTABLE
+  NAMES jarsigner
+  HINTS ${_JAVA_HINTS}
+  PATHS ${_JAVA_PATHS}
+)
+
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 if(Java_FIND_COMPONENTS)
+  set(_JAVA_REQUIRED_VARS)
   foreach(component ${Java_FIND_COMPONENTS})
     # User just want to execute some Java byte-compiled
-    if(component STREQUAL "Runtime")
-      find_package_handle_standard_args(Java
-        REQUIRED_VARS Java_JAVA_EXECUTABLE
-        VERSION_VAR Java_VERSION
-        )
+    If(component STREQUAL "Runtime")
+      list(APPEND _JAVA_REQUIRED_VARS Java_JAVA_EXECUTABLE)
+      if(Java_JAVA_EXECUTABLE)
+        set(Java_Runtime_FOUND TRUE)
+      endif()
     elseif(component STREQUAL "Development")
-      find_package_handle_standard_args(Java
-        REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
-                      Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE
-        VERSION_VAR Java_VERSION
-        )
+      list(APPEND _JAVA_REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAVAC_EXECUTABLE
+                                      Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE)
+      if(Java_JAVA_EXECUTABLE AND Java_JAVAC_EXECUTABLE
+          AND Java_JAVAH_EXECUTABLE AND Java_JAVADOC_EXECUTABLE)
+        set(Java_Development_FOUND TRUE)
+      endif()
+    elseif(component STREQUAL "IdlJ")
+      list(APPEND _JAVA_REQUIRED_VARS Java_IDLJ_EXECUTABLE)
+      if(Java_IdlJ_EXECUTABLE)
+        set(Java_Extra_FOUND TRUE)
+      endif()
+    elseif(component STREQUAL "JarSigner")
+      list(APPEND _JAVA_REQUIRED_VARS Java_JARSIGNER_EXECUTABLE)
+      if(Java_IDLJ_EXECUTABLE)
+        set(Java_JarSigner_FOUND TRUE)
+      endif()
     else()
       message(FATAL_ERROR "Comp: ${component} is not handled")
     endif()
-    set(Java_${component}_FOUND TRUE)
   endforeach()
+  list (REMOVE_DUPLICATES _JAVA_REQUIRED_VARS)
+  find_package_handle_standard_args(Java
+    REQUIRED_VARS ${_JAVA_REQUIRED_VARS} HANDLE_COMPONENTS
+    VERSION_VAR Java_VERSION
+    )
+  if(Java_FOUND)
+    foreach(component ${Java_FIND_COMPONENTS})
+      set(Java_${component}_FOUND TRUE)
+    endforeach()
+  endif()
 else()
-  # Check for everything
+  # Check for Development
   find_package_handle_standard_args(Java
     REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
                   Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE
@@ -220,6 +266,8 @@ mark_as_advanced(
   Java_JAVAC_EXECUTABLE
   Java_JAVAH_EXECUTABLE
   Java_JAVADOC_EXECUTABLE
+  Java_IDLJ_EXECUTABLE
+  Java_JARSIGNER_EXECUTABLE
   )
 
 # LEGACY
diff --git a/Modules/FindKDE4.cmake b/Modules/FindKDE4.cmake
index 3c2c309..5530166 100644
--- a/Modules/FindKDE4.cmake
+++ b/Modules/FindKDE4.cmake
@@ -105,7 +105,7 @@ if (KDE4_DATA_DIR)
    endif ()
 
    # use FindKDE4Internal.cmake to do the rest
-   find_package(KDE4Internal ${_req} ${_quiet})
+   find_package(KDE4Internal ${_req} ${_quiet} NO_POLICY_SCOPE)
 else ()
    if (KDE4_FIND_REQUIRED)
       message(FATAL_ERROR "ERROR: cmake/modules/FindKDE4Internal.cmake not found in ${_data_DIR}")
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 06ecfaa..48adf3c 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -102,7 +102,6 @@
 
 # include this to handle the QUIETLY and REQUIRED arguments
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/GetPrerequisites.cmake)
 
 #
 # This part detects MPI compilers, attempting to wade through the mess of compiler names in
@@ -578,14 +577,13 @@ foreach (lang C CXX Fortran)
   if (CMAKE_${lang}_COMPILER_WORKS)
     # If the user supplies a compiler *name* instead of an absolute path, assume that we need to find THAT compiler.
     if (MPI_${lang}_COMPILER)
-      is_file_executable(MPI_${lang}_COMPILER MPI_COMPILER_IS_EXECUTABLE)
-      if (NOT MPI_COMPILER_IS_EXECUTABLE)
+      if (NOT IS_ABSOLUTE "${MPI_${lang}_COMPILER}")
         # Get rid of our default list of names and just search for the name the user wants.
         set(_MPI_${lang}_COMPILER_NAMES ${MPI_${lang}_COMPILER})
         set(MPI_${lang}_COMPILER "MPI_${lang}_COMPILER-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
-        # If the user specifies a compiler, we don't want to try to search libraries either.
-        set(try_libs FALSE)
       endif()
+      # If the user specifies a compiler, we don't want to try to search libraries either.
+      set(try_libs FALSE)
     else()
       set(try_libs TRUE)
     endif()
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index a47a69c..7a36719 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -229,6 +229,7 @@ if(NOT MATLAB_ADDITIONAL_VERSIONS)
 endif()
 
 set(MATLAB_VERSIONS_MAPPING
+  "R2015b=8.6"
   "R2015a=8.5"
   "R2014b=8.4"
   "R2014a=8.3"
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index 3adc269..d75e8ab 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -2,26 +2,41 @@
 # FindOpenSSL
 # -----------
 #
-# Try to find the OpenSSL encryption library
+# Find the OpenSSL encryption library.
 #
-# Once done this will define
+# Imported Targets
+# ^^^^^^^^^^^^^^^^
 #
-# ::
+# This module defines the following :prop_tgt:`IMPORTED` targets:
 #
-#   OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
+# ``OpenSSL::SSL``
+#   The OpenSSL ``ssl`` library, if found.
+# ``OpenSSL::Crypto``
+#   The OpenSSL ``crypto`` library, if found.
 #
+# Result Variables
+# ^^^^^^^^^^^^^^^^
 #
+# This module will set the following variables in your project:
 #
-# Read-Only variables:
+# ``OPENSSL_FOUND``
+#   System has the OpenSSL library.
+# ``OPENSSL_INCLUDE_DIR``
+#   The OpenSSL include directory.
+# ``OPENSSL_CRYPTO_LIBRARY``
+#   The OpenSSL crypto library.
+# ``OPENSSL_SSL_LIBRARY``
+#   The OpenSSL SSL library.
+# ``OPENSSL_LIBRARIES``
+#   All OpenSSL libraries.
+# ``OPENSSL_VERSION``
+#   This is set to ``$major.$minor.$revision$patch`` (e.g. ``0.9.8s``).
 #
-# ::
+# Hints
+# ^^^^^
 #
-#   OPENSSL_FOUND - System has the OpenSSL library
-#   OPENSSL_INCLUDE_DIR - The OpenSSL include directory
-#   OPENSSL_CRYPTO_LIBRARY - The OpenSSL crypto library
-#   OPENSSL_SSL_LIBRARY - The OpenSSL SSL library
-#   OPENSSL_LIBRARIES - All OpenSSL libraries
-#   OPENSSL_VERSION - This is set to $major.$minor.$revision$patch (eg. 0.9.8s)
+# Set ``OPENSSL_ROOT_DIR`` to the root directory of an OpenSSL installation.
+# Set ``OPENSSL_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries.
 
 #=============================================================================
 # Copyright 2006-2009 Kitware, Inc.
@@ -43,6 +58,16 @@ if (UNIX)
   pkg_check_modules(_OPENSSL QUIET openssl)
 endif ()
 
+# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
+if(OPENSSL_USE_STATIC_LIBS)
+  set(_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  if(WIN32)
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  else()
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
+  endif()
+endif()
+
 if (WIN32)
   # http://www.slproweb.com/products/Win32OpenSSL.html
   set(_OPENSSL_ROOT_HINTS
@@ -99,15 +124,29 @@ if(WIN32 AND NOT CYGWIN)
     # We are using the libraries located in the VC subdir instead of the parent directory eventhough :
     # libeay32MD.lib is identical to ../libeay32.lib, and
     # ssleay32MD.lib is identical to ../ssleay32.lib
+    # enable OPENSSL_USE_STATIC_LIBS to use the static libs located in lib/VC/static
+
+    if(OPENSSL_USE_STATIC_LIBS)
+      set(_OPENSSL_PATH_SUFFIXES
+        "lib"
+        "VC/static"
+        "lib/VC/static"
+        )
+    else()
+      set(_OPENSSL_PATH_SUFFIXES
+        "lib"
+        "VC"
+        "lib/VC"
+        )
+    endif ()
+
     find_library(LIB_EAY_DEBUG
       NAMES
         libeay32MDd
         libeay32d
       ${_OPENSSL_ROOT_HINTS_AND_PATHS}
       PATH_SUFFIXES
-        "lib"
-        "VC"
-        "lib/VC"
+        ${_OPENSSL_PATH_SUFFIXES}
     )
 
     find_library(LIB_EAY_RELEASE
@@ -116,9 +155,7 @@ if(WIN32 AND NOT CYGWIN)
         libeay32
       ${_OPENSSL_ROOT_HINTS_AND_PATHS}
       PATH_SUFFIXES
-        "lib"
-        "VC"
-        "lib/VC"
+        ${_OPENSSL_PATH_SUFFIXES}
     )
 
     find_library(SSL_EAY_DEBUG
@@ -127,9 +164,7 @@ if(WIN32 AND NOT CYGWIN)
         ssleay32d
       ${_OPENSSL_ROOT_HINTS_AND_PATHS}
       PATH_SUFFIXES
-        "lib"
-        "VC"
-        "lib/VC"
+        ${_OPENSSL_PATH_SUFFIXES}
     )
 
     find_library(SSL_EAY_RELEASE
@@ -139,9 +174,7 @@ if(WIN32 AND NOT CYGWIN)
         ssl
       ${_OPENSSL_ROOT_HINTS_AND_PATHS}
       PATH_SUFFIXES
-        "lib"
-        "VC"
-        "lib/VC"
+        ${_OPENSSL_PATH_SUFFIXES}
     )
 
     set(LIB_EAY_LIBRARY_DEBUG "${LIB_EAY_DEBUG}")
@@ -155,9 +188,9 @@ if(WIN32 AND NOT CYGWIN)
 
     mark_as_advanced(LIB_EAY_LIBRARY_DEBUG LIB_EAY_LIBRARY_RELEASE
                      SSL_EAY_LIBRARY_DEBUG SSL_EAY_LIBRARY_RELEASE)
-    set( OPENSSL_SSL_LIBRARY ${SSL_EAY_LIBRARY} )
-    set( OPENSSL_CRYPTO_LIBRARY ${LIB_EAY_LIBRARY} )
-    set( OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY} )
+    set(OPENSSL_SSL_LIBRARY ${SSL_EAY_LIBRARY} )
+    set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY_LIBRARY} )
+    set(OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY} )
   elseif(MINGW)
     # same player, for MinGW
     set(LIB_EAY_NAMES libeay32)
@@ -185,9 +218,9 @@ if(WIN32 AND NOT CYGWIN)
     )
 
     mark_as_advanced(SSL_EAY LIB_EAY)
-    set( OPENSSL_SSL_LIBRARY ${SSL_EAY} )
-    set( OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} )
-    set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
+    set(OPENSSL_SSL_LIBRARY ${SSL_EAY} )
+    set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} )
+    set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
     unset(LIB_EAY_NAMES)
     unset(SSL_EAY_NAMES)
   else()
@@ -213,9 +246,9 @@ if(WIN32 AND NOT CYGWIN)
     )
 
     mark_as_advanced(SSL_EAY LIB_EAY)
-    set( OPENSSL_SSL_LIBRARY ${SSL_EAY} )
-    set( OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} )
-    set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
+    set(OPENSSL_SSL_LIBRARY ${SSL_EAY} )
+    set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} )
+    set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
   endif()
 else()
 
@@ -338,3 +371,71 @@ else ()
 endif ()
 
 mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
+
+if(OPENSSL_FOUND)
+  if(NOT TARGET OpenSSL::Crypto AND
+      (EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR
+        EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR
+        EXISTS "${LIB_EAY_LIBRARY_RELEASE}")
+      )
+    add_library(OpenSSL::Crypto UNKNOWN IMPORTED)
+    set_target_properties(OpenSSL::Crypto PROPERTIES
+      INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}")
+    if(EXISTS "${OPENSSL_CRYPTO_LIBRARY}")
+      set_target_properties(OpenSSL::Crypto PROPERTIES
+        IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+        IMPORTED_LOCATION "${OPENSSL_CRYPTO_LIBRARY}")
+    endif()
+    if(EXISTS "${LIB_EAY_LIBRARY_DEBUG}")
+      set_property(TARGET OpenSSL::Crypto APPEND PROPERTY
+        IMPORTED_CONFIGURATIONS DEBUG)
+      set_target_properties(OpenSSL::Crypto PROPERTIES
+        IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+        IMPORTED_LOCATION_DEBUG "${LIB_EAY_LIBRARY_DEBUG}")
+    endif()
+    if(EXISTS "${LIB_EAY_LIBRARY_RELEASE}")
+      set_property(TARGET OpenSSL::Crypto APPEND PROPERTY
+        IMPORTED_CONFIGURATIONS RELEASE)
+      set_target_properties(OpenSSL::Crypto PROPERTIES
+        IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+        IMPORTED_LOCATION_RELEASE "${LIB_EAY_LIBRARY_RELEASE}")
+    endif()
+  endif()
+  if(NOT TARGET OpenSSL::SSL AND
+      (EXISTS "${OPENSSL_SSL_LIBRARY}" OR
+        EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR
+        EXISTS "${SSL_EAY_LIBRARY_RELEASE}")
+      )
+    add_library(OpenSSL::SSL UNKNOWN IMPORTED)
+    set_target_properties(OpenSSL::SSL PROPERTIES
+      INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}")
+    if(EXISTS "${OPENSSL_SSL_LIBRARY}")
+      set_target_properties(OpenSSL::SSL PROPERTIES
+        IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+        IMPORTED_LOCATION "${OPENSSL_SSL_LIBRARY}")
+    endif()
+    if(EXISTS "${SSL_EAY_LIBRARY_DEBUG}")
+      set_property(TARGET OpenSSL::SSL APPEND PROPERTY
+        IMPORTED_CONFIGURATIONS DEBUG)
+      set_target_properties(OpenSSL::SSL PROPERTIES
+        IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+        IMPORTED_LOCATION_DEBUG "${SSL_EAY_LIBRARY_DEBUG}")
+    endif()
+    if(EXISTS "${SSL_EAY_LIBRARY_RELEASE}")
+      set_property(TARGET OpenSSL::SSL APPEND PROPERTY
+        IMPORTED_CONFIGURATIONS RELEASE)
+      set_target_properties(OpenSSL::SSL PROPERTIES
+        IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+        IMPORTED_LOCATION_RELEASE "${SSL_EAY_LIBRARY_RELEASE}")
+    endif()
+    if(TARGET OpenSSL::Crypto)
+      set_target_properties(OpenSSL::SSL PROPERTIES
+        INTERFACE_LINK_LIBRARIES OpenSSL::Crypto)
+    endif()
+  endif()
+endif()
+
+# Restore the original find library ordering
+if(OPENSSL_USE_STATIC_LIBS)
+  set(CMAKE_FIND_LIBRARY_SUFFIXES ${_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+endif()
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index 1be38af..fe2dbea 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -42,7 +42,7 @@ valid filepaths.
     (recommended).  Not valid in the full signature.
 
   ``FOUND_VAR <result-var>``
-    Obselete.  Specifies either ``<PackageName>_FOUND`` or
+    Obsolete.  Specifies either ``<PackageName>_FOUND`` or
     ``<PACKAGENAME>_FOUND`` as the result variable.  This exists only
     for compatibility with older versions of CMake and is now ignored.
     Result variables of both names are always set for compatibility.
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index 53c17f1..e822b9c 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -70,14 +70,14 @@ macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp)
   execute_process(
     COMMAND ${PKG_CONFIG_EXECUTABLE} ${ARGN} ${_pkglist}
     OUTPUT_VARIABLE _pkgconfig_invoke_result
-    RESULT_VARIABLE _pkgconfig_failed)
+    RESULT_VARIABLE _pkgconfig_failed
+    OUTPUT_STRIP_TRAILING_WHITESPACE)
 
   if (_pkgconfig_failed)
     set(_pkgconfig_${_varname} "")
     _pkgconfig_unset(${_prefix}_${_varname})
   else()
     string(REGEX REPLACE "[\r\n]"                  " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
-    string(REGEX REPLACE " +$"                     ""  _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
 
     if (NOT ${_regexp} STREQUAL "")
       string(REGEX REPLACE "${_regexp}" " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
@@ -91,6 +91,26 @@ macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp)
   endif()
 endmacro()
 
+#[========================================[.rst:
+.. command:: pkg_get_variable
+
+  Retrieves the value of a variable from a package::
+
+    pkg_get_variable(<RESULT> <MODULE> <VARIABLE>)
+
+  For example:
+
+  .. code-block:: cmake
+
+    pkg_get_variable(GI_GIRDIR gobject-introspection-1.0 girdir)
+#]========================================]
+function (pkg_get_variable result pkg variable)
+  _pkgconfig_invoke("${pkg}" "prefix" "result" "" "--variable=${variable}")
+  set("${result}"
+    "${prefix_result}"
+    PARENT_SCOPE)
+endfunction ()
+
 # Invokes pkgconfig two times; once without '--static' and once with
 # '--static'
 macro(_pkgconfig_invoke_dyn _pkglist _prefix _varname cleanup_regexp)
@@ -109,7 +129,7 @@ macro(_pkgconfig_parse_options _result _is_req _is_silent _no_cmake_path _no_cma
       set(${_no_cmake_path} 1)
       set(${_no_cmake_environment_path} 1)
     endif()
-  elseif(${CMAKE_MINIMUM_REQUIRED_VERSION} VERSION_LESS 3.1)
+  elseif(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 3.1)
     set(${_no_cmake_path} 1)
     set(${_no_cmake_environment_path} 1)
   endif()
@@ -192,9 +212,9 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma
     # give out status message telling checked module
     if (NOT ${_is_silent})
       if (_pkg_check_modules_cnt EQUAL 1)
-        message(STATUS "checking for module '${_pkg_check_modules_list}'")
+        message(STATUS "Checking for module '${_pkg_check_modules_list}'")
       else()
-        message(STATUS "checking for modules '${_pkg_check_modules_list}'")
+        message(STATUS "Checking for modules '${_pkg_check_modules_list}'")
       endif()
     endif()
 
@@ -327,7 +347,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma
       # evaluate result and tell failures
       if (_pkgconfig_retval)
         if(NOT ${_is_silent})
-          message(STATUS "  package '${_pkg_check_modules_pkg}' not found")
+          message(STATUS "  Package '${_pkg_check_modules_pkg}' not found")
         endif()
 
         set(_pkg_check_modules_failed 1)
@@ -356,12 +376,12 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma
         endif()
 
         _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" VERSION    ""   --modversion )
-        _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" PREFIX     ""   --variable=prefix )
-        _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" INCLUDEDIR ""   --variable=includedir )
-        _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" LIBDIR     ""   --variable=libdir )
+        pkg_get_variable("${_pkg_check_prefix}_PREFIX" ${_pkg_check_modules_pkg} "prefix")
+        pkg_get_variable("${_pkg_check_prefix}_INCLUDEDIR" ${_pkg_check_modules_pkg} "includedir")
+        pkg_get_variable("${_pkg_check_prefix}_LIBDIR" ${_pkg_check_modules_pkg} "libdir")
 
         if (NOT ${_is_silent})
-          message(STATUS "  found ${_pkg_check_modules_pkg}, version ${_pkgconfig_VERSION}")
+          message(STATUS "  Found ${_pkg_check_modules_pkg}, version ${_pkgconfig_VERSION}")
         endif ()
       endforeach()
 
@@ -529,7 +549,7 @@ macro(pkg_search_module _prefix _module0)
     _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path "${_module0}" ${ARGN})
 
     if (NOT ${_pkg_is_silent})
-      message(STATUS "checking for one of the modules '${_pkg_modules_alt}'")
+      message(STATUS "Checking for one of the modules '${_pkg_modules_alt}'")
     endif ()
 
     # iterate through all modules and stop at the first working one.
diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake
index 3ce2c73..d05d3da 100644
--- a/Modules/FindPostgreSQL.cmake
+++ b/Modules/FindPostgreSQL.cmake
@@ -81,7 +81,7 @@ set(PostgreSQL_ROOT_DIR_MESSAGE "Set the PostgreSQL_ROOT system variable to wher
 
 
 set(PostgreSQL_KNOWN_VERSIONS ${PostgreSQL_ADDITIONAL_VERSIONS}
-    "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0")
+    "9.5" "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0")
 
 # Define additional search paths for root directories.
 set( PostgreSQL_ROOT_DIRECTORIES
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index f01bd41..4a68cd1 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -9,8 +9,9 @@
 # ``PROTOBUF_SRC_ROOT_FOLDER``
 #   When compiling with MSVC, if this cache variable is set
 #   the protobuf-default VS project build locations
-#   (vsprojects/Debug & vsprojects/Release) will be searched
-#   for libraries and binaries.
+#   (vsprojects/Debug and vsprojects/Release
+#   or vsprojects/x64/Debug and vsprojects/x64/Release)
+#   will be searched for libraries and binaries.
 # ``PROTOBUF_IMPORT_DIRS``
 #   List of additional directories to be searched for
 #   imported .proto files.
@@ -56,17 +57,18 @@
 #   include_directories(${PROTOBUF_INCLUDE_DIRS})
 #   include_directories(${CMAKE_CURRENT_BINARY_DIR})
 #   protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
+#   protobuf_generate_python(PROTO_PY foo.proto)
 #   add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
 #   target_link_libraries(bar ${PROTOBUF_LIBRARIES})
 #
 # .. note::
-#   The PROTOBUF_GENERATE_CPP macro and add_executable() or
-#   add_library() calls only work properly within the same
-#   directory.
+#   The ``protobuf_generate_cpp`` and ``protobuf_generate_python``
+#   functions and :command:`add_executable` or :command:`add_library`
+#   calls only work properly within the same directory.
 #
 # .. command:: protobuf_generate_cpp
 #
-#   Add custom commands to process ``.proto`` files::
+#   Add custom commands to process ``.proto`` files to C++::
 #
 #     protobuf_generate_cpp (<SRCS> <HDRS> [<ARGN>...])
 #
@@ -76,6 +78,17 @@
 #     Variable to define with autogenerated header files
 #   ``ARGN``
 #     ``.proto`` files
+#
+# .. command:: protobuf_generate_python
+#
+#   Add custom commands to process ``.proto`` files to Python::
+#
+#     protobuf_generate_python (<PY> [<ARGN>...])
+#
+#   ``PY``
+#     Variable to define with autogenerated Python files
+#   ``ARGN``
+#     ``.proto`` filess
 
 #=============================================================================
 # Copyright 2009 Kitware, Inc.
@@ -146,18 +159,69 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
   set(${HDRS} ${${HDRS}} PARENT_SCOPE)
 endfunction()
 
+function(PROTOBUF_GENERATE_PYTHON SRCS)
+  if(NOT ARGN)
+    message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
+    return()
+  endif()
+
+  if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
+    # Create an include path for each file specified
+    foreach(FIL ${ARGN})
+      get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+      get_filename_component(ABS_PATH ${ABS_FIL} PATH)
+      list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
+      if(${_contains_already} EQUAL -1)
+          list(APPEND _protobuf_include_path -I ${ABS_PATH})
+      endif()
+    endforeach()
+  else()
+    set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+  endif()
+
+  if(DEFINED PROTOBUF_IMPORT_DIRS)
+    foreach(DIR ${PROTOBUF_IMPORT_DIRS})
+      get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
+      list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
+      if(${_contains_already} EQUAL -1)
+          list(APPEND _protobuf_include_path -I ${ABS_PATH})
+      endif()
+    endforeach()
+  endif()
+
+  set(${SRCS})
+  foreach(FIL ${ARGN})
+    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+    get_filename_component(FIL_WE ${FIL} NAME_WE)
+
+    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py")
+    add_custom_command(
+      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py"
+      COMMAND  ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
+      DEPENDS ${ABS_FIL} ${PROTOBUF_PROTOC_EXECUTABLE}
+      COMMENT "Running Python protocol buffer compiler on ${FIL}"
+      VERBATIM )
+  endforeach()
+
+  set(${SRCS} ${${SRCS}} PARENT_SCOPE)
+endfunction()
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+  set(_PROTOBUF_ARCH_DIR x64/)
+endif()
+
 # Internal function: search for normal library as well as a debug one
 #    if the debug one is specified also include debug/optimized keywords
 #    in *_LIBRARIES variable
 function(_protobuf_find_libraries name filename)
    find_library(${name}_LIBRARY
        NAMES ${filename}
-       PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Release)
+       PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release)
    mark_as_advanced(${name}_LIBRARY)
 
    find_library(${name}_LIBRARY_DEBUG
        NAMES ${filename}
-       PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug)
+       PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug)
    mark_as_advanced(${name}_LIBRARY_DEBUG)
 
    if(NOT ${name}_LIBRARY_DEBUG)
@@ -234,8 +298,8 @@ find_program(PROTOBUF_PROTOC_EXECUTABLE
     NAMES protoc
     DOC "The Google Protocol Buffers Compiler"
     PATHS
-    ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Release
-    ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug
+    ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release
+    ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug
 )
 mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE)
 
diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake
index 8784e18..879192e 100644
--- a/Modules/FindPythonInterp.cmake
+++ b/Modules/FindPythonInterp.cmake
@@ -51,7 +51,7 @@ unset(_Python_NAMES)
 
 set(_PYTHON1_VERSIONS 1.6 1.5)
 set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
 
 if(PythonInterp_FIND_VERSION)
     if(PythonInterp_FIND_VERSION_COUNT GREATER 1)
diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake
index cc875ad..68e1228 100644
--- a/Modules/FindPythonLibs.cmake
+++ b/Modules/FindPythonLibs.cmake
@@ -49,13 +49,41 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
+# Use the executable's path as a hint
+set(_Python_LIBRARY_PATH_HINT)
+if(PYTHON_EXECUTABLE)
+  if(WIN32)
+    get_filename_component(_Python_PREFIX ${PYTHON_EXECUTABLE} PATH)
+    if(_Python_PREFIX)
+      set(_Python_LIBRARY_PATH_HINT ${_Python_PREFIX}/libs)
+    endif()
+    unset(_Python_PREFIX)
+  else()
+    get_filename_component(_Python_PREFIX ${PYTHON_EXECUTABLE} PATH)
+    get_filename_component(_Python_PREFIX ${_Python_PREFIX} PATH)
+    if(_Python_PREFIX)
+      set(_Python_LIBRARY_PATH_HINT ${_Python_PREFIX}/lib)
+    endif()
+    unset(_Python_PREFIX)
+  endif()
+endif()
+
 include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindFrameworks.cmake)
 # Search for the python framework on Apple.
 CMAKE_FIND_FRAMEWORKS(Python)
 
+# Save CMAKE_FIND_FRAMEWORK
+if(DEFINED CMAKE_FIND_FRAMEWORK)
+  set(_PythonLibs_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
+else()
+  unset(_PythonLibs_CMAKE_FIND_FRAMEWORK)
+endif()
+# To avoid picking up the system Python.h pre-maturely.
+set(CMAKE_FIND_FRAMEWORK LAST)
+
 set(_PYTHON1_VERSIONS 1.6 1.5)
 set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
 
 if(PythonLibs_FIND_VERSION)
     if(PythonLibs_FIND_VERSION_COUNT GREATER 1)
@@ -103,6 +131,7 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
   if(WIN32)
     find_library(PYTHON_DEBUG_LIBRARY
       NAMES python${_CURRENT_VERSION_NO_DOTS}_d python
+      HINTS ${_Python_LIBRARY_PATH_HINT}
       PATHS
       [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
       [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
@@ -111,14 +140,24 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
       )
   endif()
 
+  set(PYTHON_FRAMEWORK_LIBRARIES)
+  if(Python_FRAMEWORKS AND NOT PYTHON_LIBRARY)
+    foreach(dir ${Python_FRAMEWORKS})
+      list(APPEND PYTHON_FRAMEWORK_LIBRARIES
+           ${dir}/Versions/${_CURRENT_VERSION}/lib)
+    endforeach()
+  endif()
   find_library(PYTHON_LIBRARY
     NAMES
-    python${_CURRENT_VERSION_NO_DOTS}
-    python${_CURRENT_VERSION}mu
-    python${_CURRENT_VERSION}m
-    python${_CURRENT_VERSION}u
-    python${_CURRENT_VERSION}
+      python${_CURRENT_VERSION_NO_DOTS}
+      python${_CURRENT_VERSION}mu
+      python${_CURRENT_VERSION}m
+      python${_CURRENT_VERSION}u
+      python${_CURRENT_VERSION}
+    HINTS
+      ${_Python_LIBRARY_PATH_HINT}
     PATHS
+      ${PYTHON_FRAMEWORK_LIBRARIES}
       [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
       [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
     # Avoid finding the .dll in the PATH.  We want the .lib.
@@ -133,33 +172,42 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
     PATH_SUFFIXES python${_CURRENT_VERSION}/config
   )
 
-  # For backward compatibility, honour value of PYTHON_INCLUDE_PATH, if
-  # PYTHON_INCLUDE_DIR is not set.
-  if(DEFINED PYTHON_INCLUDE_PATH AND NOT DEFINED PYTHON_INCLUDE_DIR)
-    set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}" CACHE PATH
-      "Path to where Python.h is found" FORCE)
-  endif()
+  # Don't search for include dir until library location is known
+  if(PYTHON_LIBRARY)
 
-  set(PYTHON_FRAMEWORK_INCLUDES)
-  if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR)
-    foreach(dir ${Python_FRAMEWORKS})
-      set(PYTHON_FRAMEWORK_INCLUDES ${PYTHON_FRAMEWORK_INCLUDES}
-        ${dir}/Versions/${_CURRENT_VERSION}/include/python${_CURRENT_VERSION})
-    endforeach()
-  endif()
+    # Use the library's install prefix as a hint
+    set(_Python_INCLUDE_PATH_HINT)
+    get_filename_component(_Python_PREFIX ${PYTHON_LIBRARY} PATH)
+    get_filename_component(_Python_PREFIX ${_Python_PREFIX} PATH)
+    if(_Python_PREFIX)
+      set(_Python_INCLUDE_PATH_HINT ${_Python_PREFIX}/include)
+    endif()
+    unset(_Python_PREFIX)
+
+    # Add framework directories to the search paths
+    set(PYTHON_FRAMEWORK_INCLUDES)
+    if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR)
+      foreach(dir ${Python_FRAMEWORKS})
+        list(APPEND PYTHON_FRAMEWORK_INCLUDES
+          ${dir}/Versions/${_CURRENT_VERSION}/include)
+      endforeach()
+    endif()
 
-  find_path(PYTHON_INCLUDE_DIR
-    NAMES Python.h
-    PATHS
-      ${PYTHON_FRAMEWORK_INCLUDES}
-      [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
-      [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
-    PATH_SUFFIXES
-      python${_CURRENT_VERSION}mu
-      python${_CURRENT_VERSION}m
-      python${_CURRENT_VERSION}u
-      python${_CURRENT_VERSION}
-  )
+    find_path(PYTHON_INCLUDE_DIR
+      NAMES Python.h
+      HINTS
+        ${_Python_INCLUDE_PATH_HINT}
+      PATHS
+        ${PYTHON_FRAMEWORK_INCLUDES}
+        [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
+        [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
+      PATH_SUFFIXES
+        python${_CURRENT_VERSION}mu
+        python${_CURRENT_VERSION}m
+        python${_CURRENT_VERSION}u
+        python${_CURRENT_VERSION}
+    )
+  endif()
 
   # For backward compatibility, set PYTHON_INCLUDE_PATH.
   set(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}")
@@ -177,6 +225,9 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
   endif()
 endforeach()
 
+unset(_Python_INCLUDE_PATH_HINT)
+unset(_Python_LIBRARY_PATH_HINT)
+
 mark_as_advanced(
   PYTHON_DEBUG_LIBRARY
   PYTHON_LIBRARY
@@ -201,6 +252,14 @@ SELECT_LIBRARY_CONFIGURATIONS(PYTHON)
 # for historical reasons.
 unset(PYTHON_FOUND)
 
+# Restore CMAKE_FIND_FRAMEWORK
+if(DEFINED _PythonLibs_CMAKE_FIND_FRAMEWORK)
+  set(CMAKE_FIND_FRAMEWORK ${_PythonLibs_CMAKE_FIND_FRAMEWORK})
+  unset(_PythonLibs_CMAKE_FIND_FRAMEWORK)
+else()
+  unset(CMAKE_FIND_FRAMEWORK)
+endif()
+
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs
                                   REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS
diff --git a/Modules/FindTIFF.cmake b/Modules/FindTIFF.cmake
index a67d24d..ed092ea 100644
--- a/Modules/FindTIFF.cmake
+++ b/Modules/FindTIFF.cmake
@@ -34,7 +34,19 @@
 find_path(TIFF_INCLUDE_DIR tiff.h)
 
 set(TIFF_NAMES ${TIFF_NAMES} tiff libtiff tiff3 libtiff3)
-find_library(TIFF_LIBRARY NAMES ${TIFF_NAMES} )
+foreach(name ${TIFF_NAMES})
+  list(APPEND TIFF_NAMES_DEBUG "${name}d")
+endforeach()
+
+if(NOT TIFF_LIBRARY)
+  find_library(TIFF_LIBRARY_RELEASE NAMES ${TIFF_NAMES})
+  find_library(TIFF_LIBRARY_DEBUG NAMES ${TIFF_NAMES_DEBUG})
+  include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+  select_library_configurations(TIFF)
+  mark_as_advanced(TIFF_LIBRARY_RELEASE TIFF_LIBRARY_DEBUG)
+endif()
+unset(TIFF_NAMES)
+unset(TIFF_NAMES_DEBUG)
 
 if(TIFF_INCLUDE_DIR AND EXISTS "${TIFF_INCLUDE_DIR}/tiffvers.h")
     file(STRINGS "${TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index a0bc4d1..c607923 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -39,7 +39,7 @@
 
 #=============================================================================
 # Copyright 2002-2009 Kitware, Inc.
-# Copyright 2011-2014 Rolf Eike Beer <eike at sf-mail.de>
+# Copyright 2011-2015 Rolf Eike Beer <eike at sf-mail.de>
 #
 # Distributed under the OSI-approved BSD License (the "License");
 # see accompanying file Copyright.txt for details.
@@ -51,15 +51,23 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include (CheckIncludeFiles)
 include (CheckLibraryExists)
 include (CheckSymbolExists)
 set(Threads_FOUND FALSE)
 set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
 set(CMAKE_REQUIRED_QUIET ${Threads_FIND_QUIETLY})
 
+if(CMAKE_C_COMPILER_LOADED)
+  include (CheckIncludeFile)
+elseif(CMAKE_CXX_COMPILER_LOADED)
+  include (CheckIncludeFileCXX)
+else()
+  message(FATAL_ERROR "FindThreads only works if either C or CXX language is enabled")
+endif()
+
 # Do we have sproc?
 if(CMAKE_SYSTEM_NAME MATCHES IRIX AND NOT CMAKE_THREAD_PREFER_PTHREAD)
+  include (CheckIncludeFiles)
   CHECK_INCLUDE_FILES("sys/types.h;sys/prctl.h"  CMAKE_HAVE_SPROC_H)
 endif()
 
@@ -83,11 +91,18 @@ macro(_check_pthreads_flag)
     # If we did not found -lpthread, -lpthread, or -lthread, look for -pthread
     if(NOT DEFINED THREADS_HAVE_PTHREAD_ARG)
       message(STATUS "Check if compiler accepts -pthread")
+      if(CMAKE_C_COMPILER_LOADED)
+        set(_threads_src ${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c)
+      elseif(CMAKE_CXX_COMPILER_LOADED)
+        set(_threads_src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindThreads/CheckForPthreads.cxx)
+        configure_file(${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c "${_threads_src}" COPYONLY)
+      endif()
       try_run(THREADS_PTHREAD_ARG THREADS_HAVE_PTHREAD_ARG
         ${CMAKE_BINARY_DIR}
-        ${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c
+        ${_threads_src}
         CMAKE_FLAGS -DLINK_LIBRARIES:STRING=-pthread
         COMPILE_OUTPUT_VARIABLE OUTPUT)
+      unset(_threads_src)
 
       if(THREADS_HAVE_PTHREAD_ARG)
         if(THREADS_PTHREAD_ARG STREQUAL "2")
@@ -120,7 +135,11 @@ if(CMAKE_HAVE_SPROC_H AND NOT CMAKE_THREAD_PREFER_PTHREAD)
   set(CMAKE_USE_SPROC_INIT 1)
 else()
   # Do we have pthreads?
-  CHECK_INCLUDE_FILES("pthread.h" CMAKE_HAVE_PTHREAD_H)
+  if(CMAKE_C_COMPILER_LOADED)
+    CHECK_INCLUDE_FILE("pthread.h" CMAKE_HAVE_PTHREAD_H)
+  else()
+    CHECK_INCLUDE_FILE_CXX("pthread.h" CMAKE_HAVE_PTHREAD_H)
+  endif()
   if(CMAKE_HAVE_PTHREAD_H)
 
     #
diff --git a/Modules/FindXercesC.cmake b/Modules/FindXercesC.cmake
index 5a8ea9d..cf84826 100644
--- a/Modules/FindXercesC.cmake
+++ b/Modules/FindXercesC.cmake
@@ -61,10 +61,18 @@ find_path(XercesC_INCLUDE_DIR
           DOC "Xerces-C++ include directory")
 mark_as_advanced(XercesC_INCLUDE_DIR)
 
-# Find all XercesC libraries
-find_library(XercesC_LIBRARY "xerces-c"
-  DOC "Xerces-C++ libraries")
-mark_as_advanced(XercesC_LIBRARY)
+if(NOT XercesC_LIBRARY)
+  # Find all XercesC libraries
+  find_library(XercesC_LIBRARY_RELEASE
+               NAMES "xerces-c" "xerces-c_3"
+               DOC "Xerces-C++ libraries (release)")
+  find_library(XercesC_LIBRARY_DEBUG
+               NAMES "xerces-cd" "xerces-c_3D" "xerces-c_3_1D"
+               DOC "Xerces-C++ libraries (debug)")
+  include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+  select_library_configurations(XercesC)
+  mark_as_advanced(XercesC_LIBRARY_RELEASE XercesC_LIBRARY_DEBUG)
+endif()
 
 if(XercesC_INCLUDE_DIR)
   _XercesC_GET_VERSION("${XercesC_INCLUDE_DIR}/xercesc/util/XercesVersion.hpp")
diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake
index d4a27d5..a57f450 100644
--- a/Modules/FindZLIB.cmake
+++ b/Modules/FindZLIB.cmake
@@ -74,14 +74,28 @@ set(_ZLIB_SEARCH_NORMAL
   )
 list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL)
 
-set(ZLIB_NAMES z zlib zdll zlib1 zlibd zlibd1)
+set(ZLIB_NAMES z zlib zdll zlib1)
+set(ZLIB_NAMES_DEBUG zlibd zlibd1)
 
 # Try each search configuration.
 foreach(search ${_ZLIB_SEARCHES})
-  find_path(ZLIB_INCLUDE_DIR NAMES zlib.h        ${${search}} PATH_SUFFIXES include)
-  find_library(ZLIB_LIBRARY  NAMES ${ZLIB_NAMES} ${${search}} PATH_SUFFIXES lib)
+  find_path(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}} PATH_SUFFIXES include)
 endforeach()
 
+# Allow ZLIB_LIBRARY to be set manually, as the location of the zlib library
+if(NOT ZLIB_LIBRARY)
+  foreach(search ${_ZLIB_SEARCHES})
+    find_library(ZLIB_LIBRARY_RELEASE NAMES ${ZLIB_NAMES} ${${search}} PATH_SUFFIXES lib)
+    find_library(ZLIB_LIBRARY_DEBUG NAMES ${ZLIB_NAMES_DEBUG} ${${search}} PATH_SUFFIXES lib)
+  endforeach()
+
+  include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+  select_library_configurations(ZLIB)
+endif()
+
+unset(ZLIB_NAMES)
+unset(ZLIB_NAMES_DEBUG)
+
 mark_as_advanced(ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
 
 if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
@@ -112,12 +126,33 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_D
 
 if(ZLIB_FOUND)
     set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
-    set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
+
+    if(NOT ZLIB_LIBRARIES)
+      set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
+    endif()
 
     if(NOT TARGET ZLIB::ZLIB)
       add_library(ZLIB::ZLIB UNKNOWN IMPORTED)
       set_target_properties(ZLIB::ZLIB PROPERTIES
-        IMPORTED_LOCATION "${ZLIB_LIBRARY}"
         INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}")
+
+      if(ZLIB_LIBRARY_RELEASE)
+        set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
+          IMPORTED_CONFIGURATIONS RELEASE)
+        set_target_properties(ZLIB::ZLIB PROPERTIES
+          IMPORTED_LOCATION_RELEASE "${ZLIB_LIBRARY_RELEASE}")
+      endif()
+
+      if(ZLIB_LIBRARY_DEBUG)
+        set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
+          IMPORTED_CONFIGURATIONS DEBUG)
+        set_target_properties(ZLIB::ZLIB PROPERTIES
+          IMPORTED_LOCATION_DEBUG "${ZLIB_LIBRARY_DEBUG}")
+      endif()
+
+      if(NOT ZLIB_LIBRARY_RELEASE AND NOT ZLIB_LIBRARY_DEBUG)
+        set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
+          IMPORTED_LOCATION "${ZLIB_LIBRARY}")
+      endif()
     endif()
 endif()
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake
index 9a70678..9037594 100644
--- a/Modules/FindwxWidgets.cmake
+++ b/Modules/FindwxWidgets.cmake
@@ -193,8 +193,8 @@ set(wxWidgets_CXX_FLAGS    "")
 # to prevent UsewxWidgets.cmake from using SYSTEM.
 #
 # See cmake mailing list discussions for more info:
-#   http://www.cmake.org/pipermail/cmake/2008-April/021115.html
-#   http://www.cmake.org/pipermail/cmake/2008-April/021146.html
+#   https://cmake.org/pipermail/cmake/2008-April/021115.html
+#   https://cmake.org/pipermail/cmake/2008-April/021146.html
 #
 if(APPLE OR CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
   set(wxWidgets_INCLUDE_DIRS_NO_SYSTEM 1)
@@ -302,6 +302,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
     # Find wxWidgets multilib base libraries.
     find_library(WX_base${_DBG}
       NAMES
+      wxbase31${_UCD}${_DBG}
       wxbase30${_UCD}${_DBG}
       wxbase29${_UCD}${_DBG}
       wxbase28${_UCD}${_DBG}
@@ -315,6 +316,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
     foreach(LIB net odbc xml)
       find_library(WX_${LIB}${_DBG}
         NAMES
+        wxbase31${_UCD}${_DBG}_${LIB}
         wxbase30${_UCD}${_DBG}_${LIB}
         wxbase29${_UCD}${_DBG}_${LIB}
         wxbase28${_UCD}${_DBG}_${LIB}
@@ -330,6 +332,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
     # Find wxWidgets monolithic library.
     find_library(WX_mono${_DBG}
       NAMES
+      wxmsw${_UNV}31${_UCD}${_DBG}
       wxmsw${_UNV}30${_UCD}${_DBG}
       wxmsw${_UNV}29${_UCD}${_DBG}
       wxmsw${_UNV}28${_UCD}${_DBG}
@@ -346,6 +349,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
                 stc ribbon propgrid webview)
       find_library(WX_${LIB}${_DBG}
         NAMES
+        wxmsw${_UNV}31${_UCD}${_DBG}_${LIB}
         wxmsw${_UNV}30${_UCD}${_DBG}_${LIB}
         wxmsw${_UNV}29${_UCD}${_DBG}_${LIB}
         wxmsw${_UNV}28${_UCD}${_DBG}_${LIB}
@@ -386,7 +390,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
 
     # Clear wxWidgets multilib libraries.
     foreach(LIB core adv aui html media xrc dbgrid gl qa richtext
-                stc ribbon propgrid)
+                webview stc ribbon propgrid)
       WX_CLEAR_LIB(WX_${LIB}${_DBG})
     endforeach()
   endmacro()
@@ -741,7 +745,7 @@ else()
     #-----------------------------------------------------------------
     # Support cross-compiling, only search in the target platform.
     find_program(wxWidgets_CONFIG_EXECUTABLE
-      NAMES wx-config wx-config-3.0 wx-config-2.9 wx-config-2.8
+      NAMES wx-config wx-config-3.1 wx-config-3.0 wx-config-2.9 wx-config-2.8
       DOC "Location of wxWidgets library configuration provider binary (wx-config)."
       ONLY_CMAKE_FIND_ROOT_PATH
       )
@@ -857,6 +861,28 @@ else()
   endif()
 endif()
 
+# Check if a specfic version was requested by find_package().
+if(wxWidgets_FOUND)
+  find_file(_filename wx/version.h PATHS ${wxWidgets_INCLUDE_DIRS} NO_DEFAULT_PATH)
+  dbg_msg("_filename:  ${_filename}")
+
+  if(NOT _filename)
+    message(FATAL_ERROR "wxWidgets wx/version.h file not found in ${wxWidgets_INCLUDE_DIRS}.")
+  endif()
+
+  file(READ ${_filename} _wx_version_h)
+
+  string(REGEX REPLACE "^(.*\n)?#define +wxMAJOR_VERSION +([0-9]+).*"
+    "\\2" wxWidgets_VERSION_MAJOR "${_wx_version_h}" )
+  string(REGEX REPLACE "^(.*\n)?#define +wxMINOR_VERSION +([0-9]+).*"
+    "\\2" wxWidgets_VERSION_MINOR "${_wx_version_h}" )
+  string(REGEX REPLACE "^(.*\n)?#define +wxRELEASE_NUMBER +([0-9]+).*"
+    "\\2" wxWidgets_VERSION_PATCH "${_wx_version_h}" )
+  set(wxWidgets_VERSION_STRING
+    "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}.${wxWidgets_VERSION_PATCH}" )
+  dbg_msg("wxWidgets_VERSION_STRING:    ${wxWidgets_VERSION_STRING}")
+endif()
+
 # Debug output:
 DBG_MSG("wxWidgets_FOUND           : ${wxWidgets_FOUND}")
 DBG_MSG("wxWidgets_INCLUDE_DIRS    : ${wxWidgets_INCLUDE_DIRS}")
@@ -867,10 +893,13 @@ DBG_MSG("wxWidgets_USE_FILE        : ${wxWidgets_USE_FILE}")
 
 #=====================================================================
 #=====================================================================
+
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(wxWidgets DEFAULT_MSG wxWidgets_FOUND)
-# Maintain consistency with all other variables.
-set(wxWidgets_FOUND ${WXWIDGETS_FOUND})
+
+find_package_handle_standard_args(wxWidgets
+  REQUIRED_VARS wxWidgets_LIBRARIES wxWidgets_INCLUDE_DIRS
+  VERSION_VAR   wxWidgets_VERSION_STRING
+  )
 
 #=====================================================================
 # Macros for use in wxWidgets apps.
diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake
index c61e7e9..b42084e 100644
--- a/Modules/GNUInstallDirs.cmake
+++ b/Modules/GNUInstallDirs.cmake
@@ -4,59 +4,104 @@
 #
 # Define GNU standard installation directories
 #
-# Provides install directory variables as defined for GNU software:
+# Provides install directory variables as defined by the
+# `GNU Coding Standards`_.
 #
-#   http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+# .. _`GNU Coding Standards`: https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
 #
 # Inclusion of this module defines the following variables:
 #
 # ``CMAKE_INSTALL_<dir>``
-#   destination for files of a given type
+#
+#   Destination for files of a given type.  This value may be passed to
+#   the ``DESTINATION`` options of :command:`install` commands for the
+#   corresponding file type.
+#
 # ``CMAKE_INSTALL_FULL_<dir>``
-#   corresponding absolute path
 #
-# where <dir> is one of:
+#   The absolute path generated from the corresponding ``CMAKE_INSTALL_<dir>``
+#   value.  If the value is not already an absolute path, an absolute path
+#   is constructed typically by prepending the value of the
+#   :variable:`CMAKE_INSTALL_PREFIX` variable.  However, there are some
+#   `special cases`_ as documented below.
+#
+# where ``<dir>`` is one of:
 #
 # ``BINDIR``
-#   user executables (bin)
+#   user executables (``bin``)
 # ``SBINDIR``
-#   system admin executables (sbin)
+#   system admin executables (``sbin``)
 # ``LIBEXECDIR``
-#   program executables (libexec)
+#   program executables (``libexec``)
 # ``SYSCONFDIR``
-#   read-only single-machine data (etc)
+#   read-only single-machine data (``etc``)
 # ``SHAREDSTATEDIR``
-#   modifiable architecture-independent data (com)
+#   modifiable architecture-independent data (``com``)
 # ``LOCALSTATEDIR``
-#   modifiable single-machine data (var)
+#   modifiable single-machine data (``var``)
 # ``LIBDIR``
-#   object code libraries (lib or lib64 or lib/<multiarch-tuple> on Debian)
+#   object code libraries (``lib`` or ``lib64``
+#   or ``lib/<multiarch-tuple>`` on Debian)
 # ``INCLUDEDIR``
-#   C header files (include)
+#   C header files (``include``)
 # ``OLDINCLUDEDIR``
-#   C header files for non-gcc (/usr/include)
+#   C header files for non-gcc (``/usr/include``)
 # ``DATAROOTDIR``
-#   read-only architecture-independent data root (share)
+#   read-only architecture-independent data root (``share``)
 # ``DATADIR``
-#   read-only architecture-independent data (DATAROOTDIR)
+#   read-only architecture-independent data (``DATAROOTDIR``)
 # ``INFODIR``
-#   info documentation (DATAROOTDIR/info)
+#   info documentation (``DATAROOTDIR/info``)
 # ``LOCALEDIR``
-#   locale-dependent data (DATAROOTDIR/locale)
+#   locale-dependent data (``DATAROOTDIR/locale``)
 # ``MANDIR``
-#   man documentation (DATAROOTDIR/man)
+#   man documentation (``DATAROOTDIR/man``)
 # ``DOCDIR``
-#   documentation root (DATAROOTDIR/doc/PROJECT_NAME)
+#   documentation root (``DATAROOTDIR/doc/PROJECT_NAME``)
+#
+# If the includer does not define a value the above-shown default will be
+# used and the value will appear in the cache for editing by the user.
+#
+# Special Cases
+# ^^^^^^^^^^^^^
+#
+# The following values of :variable:`CMAKE_INSTALL_PREFIX` are special:
+#
+# ``/``
+#
+#   For ``<dir>`` other than the ``SYSCONFDIR`` and ``LOCALSTATEDIR``,
+#   the value of ``CMAKE_INSTALL_<dir>`` is prefixed with ``usr/`` if
+#   it is not user-specified as an absolute path.  For example, the
+#   ``INCLUDEDIR`` value ``include`` becomes ``usr/include``.
+#   This is required by the `GNU Coding Standards`_, which state:
+#
+#     When building the complete GNU system, the prefix will be empty
+#     and ``/usr`` will be a symbolic link to ``/``.
+#
+# ``/usr``
 #
-# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION
-# options of install() commands for the corresponding file type.  If the
-# includer does not define a value the above-shown default will be used
-# and the value will appear in the cache for editing by the user.  Each
-# CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
-# from the corresponding destination by prepending (if necessary) the
-# value of CMAKE_INSTALL_PREFIX.
+#   For ``<dir>`` equal to ``SYSCONFDIR`` or ``LOCALSTATEDIR``, the
+#   ``CMAKE_INSTALL_FULL_<dir>`` is computed by prepending just ``/``
+#   to the value of ``CMAKE_INSTALL_<dir>`` if it is not user-specified
+#   as an absolute path.  For example, the ``SYSCONFDIR`` value ``etc``
+#   becomes ``/etc``.  This is required by the `GNU Coding Standards`_.
+#
+# ``/opt/...``
+#
+#   For ``<dir>`` equal to ``SYSCONFDIR`` or ``LOCALSTATEDIR``, the
+#   ``CMAKE_INSTALL_FULL_<dir>`` is computed by *appending* the prefix
+#   to the value of ``CMAKE_INSTALL_<dir>`` if it is not user-specified
+#   as an absolute path.  For example, the ``SYSCONFDIR`` value ``etc``
+#   becomes ``/etc/opt/...``.  This is defined by the
+#   `Filesystem Hierarchy Standard`_.
+#
+# .. _`Filesystem Hierarchy Standard`: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
 
 #=============================================================================
+# Copyright 2015 Alex Turbov <i.zaufi at gmail.com>
 # Copyright 2011 Nikita Krupen'ko <krnekit at gmail.com>
 # Copyright 2011 Kitware, Inc.
 #
@@ -274,8 +319,35 @@ foreach(dir
     MANDIR
     DOCDIR
     )
-  if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
-    set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+  if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_${dir}}")
+    # Handle special cases:
+    # - CMAKE_INSTALL_PREFIX == /
+    # - CMAKE_INSTALL_PREFIX == /usr
+    # - CMAKE_INSTALL_PREFIX == /opt/...
+    if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/")
+      if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
+        set(CMAKE_INSTALL_FULL_${dir} "/${CMAKE_INSTALL_${dir}}")
+      else()
+        if (NOT "${CMAKE_INSTALL_${dir}}" MATCHES "^usr/")
+          set(CMAKE_INSTALL_${dir} "usr/${CMAKE_INSTALL_${dir}}")
+        endif()
+        set(CMAKE_INSTALL_FULL_${dir} "/${CMAKE_INSTALL_${dir}}")
+      endif()
+    elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
+      if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
+        set(CMAKE_INSTALL_FULL_${dir} "/${CMAKE_INSTALL_${dir}}")
+      else()
+        set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+      endif()
+    elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/opt/.*")
+      if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
+        set(CMAKE_INSTALL_FULL_${dir} "/${CMAKE_INSTALL_${dir}}${CMAKE_INSTALL_PREFIX}")
+      else()
+        set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+      endif()
+    else()
+      set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+    endif()
   else()
     set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
   endif()
diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake
index aab29ea..8205425 100644
--- a/Modules/GenerateExportHeader.cmake
+++ b/Modules/GenerateExportHeader.cmake
@@ -268,7 +268,7 @@ macro(_DO_SET_MACRO_VALUES TARGET_LIBRARY)
   get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE)
 
   if(NOT ${type} STREQUAL "STATIC_LIBRARY")
-    if(WIN32)
+    if(WIN32 OR CYGWIN)
       set(DEFINE_EXPORT "__declspec(dllexport)")
       set(DEFINE_IMPORT "__declspec(dllimport)")
     elseif(COMPILER_HAS_HIDDEN_VISIBILITY AND USE_COMPILER_HIDDEN_VISIBILITY)
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index 23d486e..e4018b6 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -229,9 +229,14 @@ function(is_file_executable file result_var)
 
     if(file_cmd)
       execute_process(COMMAND "${file_cmd}" "${file_full}"
+        RESULT_VARIABLE file_rv
         OUTPUT_VARIABLE file_ov
+        ERROR_VARIABLE file_ev
         OUTPUT_STRIP_TRAILING_WHITESPACE
         )
+      if(NOT file_rv STREQUAL "0")
+        message(FATAL_ERROR "${file_cmd} failed: ${file_rv}\n${file_ev}")
+      endif()
 
       # Replace the name of the file in the output with a placeholder token
       # (the string " _file_full_ ") so that just in case the path name of
@@ -543,11 +548,21 @@ function(gp_resolved_file_type original_file file exepath dirs type_var)
 
         if(CYGPATH_EXECUTABLE)
           execute_process(COMMAND ${CYGPATH_EXECUTABLE} -W
+                          RESULT_VARIABLE env_rv
                           OUTPUT_VARIABLE env_windir
+                          ERROR_VARIABLE env_ev
                           OUTPUT_STRIP_TRAILING_WHITESPACE)
+          if(NOT env_rv STREQUAL "0")
+            message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -W failed: ${env_rv}\n${env_ev}")
+          endif()
           execute_process(COMMAND ${CYGPATH_EXECUTABLE} -S
+                          RESULT_VARIABLE env_rv
                           OUTPUT_VARIABLE env_sysdir
+                          ERROR_VARIABLE env_ev
                           OUTPUT_STRIP_TRAILING_WHITESPACE)
+          if(NOT env_rv STREQUAL "0")
+            message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -S failed: ${env_rv}\n${env_ev}")
+          endif()
           string(TOLOWER "${env_windir}" windir)
           string(TOLOWER "${env_sysdir}" sysroot)
 
@@ -685,6 +700,8 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
     return()
   endif()
 
+  set(gp_cmd_maybe_filter)      # optional command to pre-filter gp_tool results
+
   if(gp_tool STREQUAL "ldd")
     set(gp_cmd_args "")
     set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$")
@@ -709,6 +726,11 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
     set(gp_regex_error "")
     set(gp_regex_fallback "")
     set(gp_regex_cmp_count 1)
+    # objdump generaates copious output so we create a grep filter to pre-filter results
+    find_program(gp_grep_cmd grep)
+    if(gp_grep_cmd)
+      set(gp_cmd_maybe_filter COMMAND ${gp_grep_cmd} "^[[:blank:]]*DLL Name: ")
+    endif()
   else()
     message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
     message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
@@ -765,8 +787,19 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
   #
   execute_process(
     COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
+    ${gp_cmd_maybe_filter}
+    RESULT_VARIABLE gp_rv
     OUTPUT_VARIABLE gp_cmd_ov
+    ERROR_VARIABLE gp_ev
     )
+  if(NOT gp_rv STREQUAL "0")
+    if(gp_tool STREQUAL "dumpbin")
+      # dumpbin error messages seem to go to stdout
+      message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}\n${gp_cmd_ov}")
+    else()
+      message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}")
+    endif()
+  endif()
 
   if(gp_tool STREQUAL "ldd")
     set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
@@ -791,8 +824,13 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
   if(gp_tool STREQUAL "otool")
     execute_process(
       COMMAND otool -D ${target}
+      RESULT_VARIABLE otool_rv
       OUTPUT_VARIABLE gp_install_id_ov
+      ERROR_VARIABLE otool_ev
       )
+    if(NOT otool_rv STREQUAL "0")
+      message(FATAL_ERROR "otool -D failed: ${otool_rv}\n${otool_ev}")
+    endif()
     # second line is install name
     string(REGEX REPLACE ".*:\n" "" gp_install_id "${gp_install_id_ov}")
     if(gp_install_id)
diff --git a/Modules/Internal/FeatureTesting.cmake b/Modules/Internal/FeatureTesting.cmake
index abd9a26..86b89b2 100644
--- a/Modules/Internal/FeatureTesting.cmake
+++ b/Modules/Internal/FeatureTesting.cmake
@@ -5,7 +5,7 @@ macro(record_compiler_features lang compile_flags feature_list)
   string(TOLOWER ${lang} lang_lc)
   file(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin")
   file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "
-  const char features[] = {\"\"\n")
+  const char features[] = {\"\\n\"\n")
 
   get_property(known_features GLOBAL PROPERTY CMAKE_${lang}_KNOWN_FEATURES)
 
diff --git a/Modules/Platform/ARTOS-GNU-C.cmake b/Modules/Platform/ARTOS-GNU-C.cmake
new file mode 100644
index 0000000..967d0e7
--- /dev/null
+++ b/Modules/Platform/ARTOS-GNU-C.cmake
@@ -0,0 +1,9 @@
+# Define ARTOS to select proper behaviour and tell preprocessor to accept C++ style comments.
+set(CMAKE_C_FLAGS_INIT "-DARTOS -Xp -+")
+# ac doesn't support -g properly and doesn't support the normal gcc optimization options. Just use the defaults set by ac.
+set(CMAKE_C_FLAGS_DEBUG_INIT "")
+set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-DNDEBUG")
+set(CMAKE_C_FLAGS_RELEASE_INIT "-DNDEBUG")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-DNDEBUG")
+# Most projects expect the stdio functions to be available.
+set(CMAKE_C_STANDARD_LIBRARIES_INIT "stdio.a")
diff --git a/Modules/Platform/ARTOS.cmake b/Modules/Platform/ARTOS.cmake
new file mode 100644
index 0000000..f9365d6
--- /dev/null
+++ b/Modules/Platform/ARTOS.cmake
@@ -0,0 +1,17 @@
+# Support for ARTOS RTOS (locamation.com)
+set(CMAKE_LINK_LIBRARY_SUFFIX "")
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+set(CMAKE_SHARED_LIBRARY_PREFIX "")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".a")
+set(CMAKE_EXECUTABLE_SUFFIX ".x")
+set(CMAKE_DL_LIBS "")
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+
+# ARTOS does not support shared libs
+set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+
+set(CMAKE_C_LINK_SHARED_LIBRARY )
+set(CMAKE_C_LINK_MODULE_LIBRARY )
diff --git a/Modules/Platform/BlueGeneQ-base.cmake b/Modules/Platform/BlueGeneQ-base.cmake
index fa8dc52..9372166 100644
--- a/Modules/Platform/BlueGeneQ-base.cmake
+++ b/Modules/Platform/BlueGeneQ-base.cmake
@@ -112,8 +112,8 @@ macro(__BlueGeneQ_common_setup compiler_id lang)
   foreach(dir ${CMAKE_SYSTEM_INCLUDE_PATH})
     set(BGQ_SYSTEM_INCLUDES "${BGQ_SYSTEM_INCLUDES} -I${dir}")
   endforeach()
-  set(CMAKE_C_COMPILE_OBJECT   "<CMAKE_C_COMPILER>   <DEFINES> ${BGQ_SYSTEM_INCLUDES} <FLAGS> -o <OBJECT> -c <SOURCE>")
-  set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <FLAGS> -o <OBJECT> -c <SOURCE>")
+  set(CMAKE_C_COMPILE_OBJECT   "<CMAKE_C_COMPILER>   <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+  set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 
   #
   # Code below does setup for shared libraries.  That this is done
diff --git a/Modules/Platform/CYGWIN-windres.cmake b/Modules/Platform/CYGWIN-windres.cmake
index 01d6be3..7d787dd 100644
--- a/Modules/Platform/CYGWIN-windres.cmake
+++ b/Modules/Platform/CYGWIN-windres.cmake
@@ -1 +1 @@
-set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <FLAGS> <DEFINES> <SOURCE> <OBJECT>")
+set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> <INCLUDES> <FLAGS> <SOURCE> <OBJECT>")
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index 62fb985..a08411b 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -100,6 +100,10 @@ elseif("${CMAKE_GENERATOR}" MATCHES Xcode
         "Instead using SDK:\n \"${_CMAKE_OSX_SYSROOT_DEFAULT}\"."
         )
     endif()
+    if(NOT CMAKE_OSX_DEPLOYMENT_TARGET AND _CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_DEPLOYMENT_TARGET)
+      set(CMAKE_OSX_DEPLOYMENT_TARGET ${_CURRENT_OSX_VERSION} CACHE STRING
+        "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value." FORCE)
+    endif()
   else()
     # Assume developer files are in root (such as Xcode 4.5 command-line tools).
     set(_CMAKE_OSX_SYSROOT_DEFAULT "")
diff --git a/Modules/Platform/Darwin-NAG-Fortran.cmake b/Modules/Platform/Darwin-NAG-Fortran.cmake
index 4c28e62..e3ac9b5 100644
--- a/Modules/Platform/Darwin-NAG-Fortran.cmake
+++ b/Modules/Platform/Darwin-NAG-Fortran.cmake
@@ -16,7 +16,7 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-Wl,-v") # Runs gcc under the hood.
 
 # Need -fpp explicitly on case-insensitive filesystem.
 set(CMAKE_Fortran_COMPILE_OBJECT
-  "<CMAKE_Fortran_COMPILER> -fpp -o <OBJECT> <DEFINES> <FLAGS> -c <SOURCE>")
+  "<CMAKE_Fortran_COMPILER> -fpp -o <OBJECT> <DEFINES> <INCLUDES> <FLAGS> -c <SOURCE>")
 
 set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-Wl,-compatibility_version -Wl,")
 set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-Wl,-current_version -Wl,")
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index 4e4810a..bb085ac 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -53,7 +53,7 @@ set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -Wl,-headerpad_max_install_
 set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -Wl,-headerpad_max_install_names")
 set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,")
 set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,")
-set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".tbd" ".dylib" ".so" ".a")
 
 # hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old build tree
 # (where install_name_tool was hardcoded) and where CMAKE_INSTALL_NAME_TOOL isn't in the cache
diff --git a/Modules/Platform/Euros.cmake b/Modules/Platform/Euros.cmake
new file mode 100644
index 0000000..4c7b182
--- /dev/null
+++ b/Modules/Platform/Euros.cmake
@@ -0,0 +1,19 @@
+# Support for EUROS RTOS (euros-embedded.com)
+set(CMAKE_LINK_LIBRARY_SUFFIX "")
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
+set(CMAKE_SHARED_LIBRARY_PREFIX "")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".lib")
+set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+set(CMAKE_DL_LIBS "")
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
+
+# EUROS RTOS does not support shared libs
+set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+
+set(CMAKE_CXX_LINK_SHARED_LIBRARY )
+set(CMAKE_CXX_LINK_MODULE_LIBRARY )
+set(CMAKE_C_LINK_SHARED_LIBRARY )
+set(CMAKE_C_LINK_MODULE_LIBRARY )
diff --git a/Modules/Platform/GHS-MULTI-Initialize.cmake b/Modules/Platform/GHS-MULTI-Initialize.cmake
index 342ad21..9eb7a8a 100644
--- a/Modules/Platform/GHS-MULTI-Initialize.cmake
+++ b/Modules/Platform/GHS-MULTI-Initialize.cmake
@@ -13,13 +13,35 @@
 #  License text for the above reference.)
 
 #Setup Greenhills MULTI specific compilation information
-find_path(GHS_INT_DIRECTORY INTEGRITY.ld PATHS
-  "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\GreenHillsSoftware6433c345;InstallLocation]" #int1122
-  "C:/ghs/int1122"
-  "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\GreenHillsSoftware289b6625;InstallLocation]" #int1104
-  "C:/ghs/int1104"
-  DOC "Path to integrity directory"
-  )
+
+if (NOT GHS_INT_DIRECTORY)
+  #Assume the C:/ghs/int#### directory that is latest is prefered
+  set(GHS_EXPECTED_ROOT "C:/ghs")
+  if (EXISTS ${GHS_EXPECTED_ROOT})
+    FILE(GLOB GHS_CANDIDATE_INT_DIRS RELATIVE
+      ${GHS_EXPECTED_ROOT} ${GHS_EXPECTED_ROOT}/*)
+    string(REGEX MATCHALL  "int[0-9][0-9][0-9][0-9]" GHS_CANDIDATE_INT_DIRS
+      ${GHS_CANDIDATE_INT_DIRS})
+    if (GHS_CANDIDATE_INT_DIRS)
+      list(SORT GHS_CANDIDATE_INT_DIRS)
+      list(GET GHS_CANDIDATE_INT_DIRS -1 GHS_INT_DIRECTORY)
+      string(CONCAT GHS_INT_DIRECTORY ${GHS_EXPECTED_ROOT} "/"
+        ${GHS_INT_DIRECTORY})
+    endif ()
+  endif ()
+
+  #Try to look for known registry values
+  if (NOT GHS_INT_DIRECTORY)
+    find_path(GHS_INT_DIRECTORY INTEGRITY.ld PATHS
+      "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\GreenHillsSoftware6433c345;InstallLocation]" #int1122
+      "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\GreenHillsSoftware289b6625;InstallLocation]" #int1104
+      )
+  endif ()
+
+  set(GHS_INT_DIRECTORY ${GHS_INT_DIRECTORY} CACHE PATH
+    "Path to integrity directory")
+endif ()
+
 set(GHS_OS_DIR ${GHS_INT_DIRECTORY} CACHE PATH "OS directory")
 set(GHS_PRIMARY_TARGET "arm_integrity.tgt" CACHE STRING "target for compilation")
 set(GHS_BSP_NAME "simarm" CACHE STRING "BSP name")
diff --git a/Modules/Platform/Generic-SDCC-C.cmake b/Modules/Platform/Generic-SDCC-C.cmake
index 588bf32..a1ca812 100644
--- a/Modules/Platform/Generic-SDCC-C.cmake
+++ b/Modules/Platform/Generic-SDCC-C.cmake
@@ -38,7 +38,7 @@ if(NOT DEFINED CMAKE_EXE_LINKER_FLAGS_INIT)
 endif()
 
 # compile a C file into an object file
-set(CMAKE_C_COMPILE_OBJECT  "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+set(CMAKE_C_COMPILE_OBJECT  "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 
 # link object files to an executable
 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <OBJECTS> --out-fmt-ihx -o  <TARGET> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
diff --git a/Modules/Platform/HP-UX-HP-C.cmake b/Modules/Platform/HP-UX-HP-C.cmake
index 1000935..7610383 100644
--- a/Modules/Platform/HP-UX-HP-C.cmake
+++ b/Modules/Platform/HP-UX-HP-C.cmake
@@ -1,6 +1,6 @@
 include(Platform/HP-UX-HP)
 __hpux_compiler_hp(C)
 
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> -Aa -Ae <FLAGS> -o <OBJECT>   -c <SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> -Aa -Ae <INCLUDES> <FLAGS> -o <OBJECT>   -c <SOURCE>")
diff --git a/Modules/Platform/HP-UX-HP-CXX.cmake b/Modules/Platform/HP-UX-HP-CXX.cmake
index dfa1e4e..6d90191 100644
--- a/Modules/Platform/HP-UX-HP-CXX.cmake
+++ b/Modules/Platform/HP-UX-HP-CXX.cmake
@@ -1,9 +1,9 @@
 include(Platform/HP-UX-HP)
 __hpux_compiler_hp(CXX)
 
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
 set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE
-  "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+  "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE>"
   "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
   "rm -f `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.o"
   )
diff --git a/Modules/Platform/HP-UX-HP-Fortran.cmake b/Modules/Platform/HP-UX-HP-Fortran.cmake
index e5c5d10..12007e4 100644
--- a/Modules/Platform/HP-UX-HP-Fortran.cmake
+++ b/Modules/Platform/HP-UX-HP-Fortran.cmake
@@ -1,5 +1,5 @@
 include(Platform/HP-UX-HP)
 __hpux_compiler_hp(Fortran)
 
-set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Platform/HP-UX.cmake b/Modules/Platform/HP-UX.cmake
index 65cc731..88932ad 100644
--- a/Modules/Platform/HP-UX.cmake
+++ b/Modules/Platform/HP-UX.cmake
@@ -1,9 +1,11 @@
 set(CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH /usr/lib)
 
-set(CMAKE_SHARED_LIBRARY_SUFFIX ".sl")          # .so
+if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "ia64")
+  set(CMAKE_SHARED_LIBRARY_SUFFIX ".sl")          # .so
+  set(CMAKE_FIND_LIBRARY_SUFFIXES ".sl" ".so" ".a")
+  set(CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES ".so")
+endif()
 set(CMAKE_DL_LIBS "dld")
-set(CMAKE_FIND_LIBRARY_SUFFIXES ".sl" ".so" ".a")
-set(CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES ".so")
 
 # The HP linker needs to find transitive shared library dependencies
 # in the -L path.  Therefore the runtime path must be added to the
@@ -33,18 +35,11 @@ list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
 # Initialize C and CXX link type selection flags.  These flags are
 # used when building a shared library, shared module, or executable
 # that links to other libraries to select whether to use the static or
-# shared versions of the libraries.  Note that C modules and shared
-# libs are built using ld directly so we leave off the "-Wl," portion.
-foreach(type SHARED_LIBRARY SHARED_MODULE)
-  set(CMAKE_${type}_LINK_STATIC_C_FLAGS "-a archive")
-  set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-a default")
-endforeach()
-foreach(type EXE)
-  set(CMAKE_${type}_LINK_STATIC_C_FLAGS "-Wl,-a,archive")
-  set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-a,default")
-endforeach()
+# shared versions of the libraries.
 foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
-  set(CMAKE_${type}_LINK_STATIC_CXX_FLAGS "-Wl,-a,archive")
-  set(CMAKE_${type}_LINK_DYNAMIC_CXX_FLAGS "-Wl,-a,default")
+  foreach(lang C CXX)
+    set(CMAKE_${type}_LINK_STATIC_${lang}_FLAGS "-Wl,-a,archive")
+    set(CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS "-Wl,-a,default")
+  endforeach()
 endforeach()
 
diff --git a/Modules/Platform/IRIX64.cmake b/Modules/Platform/IRIX64.cmake
index 5acbd81..ee9b96e 100644
--- a/Modules/Platform/IRIX64.cmake
+++ b/Modules/Platform/IRIX64.cmake
@@ -44,17 +44,17 @@ endif()
 include(Platform/UnixPaths)
 
 if(NOT CMAKE_COMPILER_IS_GNUCC)
-  set (CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+  set (CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
   set (CMAKE_C_CREATE_ASSEMBLY_SOURCE
-    "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+    "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE>"
     "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
     )
 endif()
 
 if(NOT CMAKE_COMPILER_IS_GNUCXX)
-  set (CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+  set (CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
   set (CMAKE_CXX_CREATE_ASSEMBLY_SOURCE
-    "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+    "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE>"
     "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
     )
 endif()
diff --git a/Modules/Platform/Linux-CCur-Fortran.cmake b/Modules/Platform/Linux-CCur-Fortran.cmake
new file mode 100644
index 0000000..ceecc2f
--- /dev/null
+++ b/Modules/Platform/Linux-CCur-Fortran.cmake
@@ -0,0 +1 @@
+include(Platform/Linux-GNU-Fortran)
diff --git a/Modules/Platform/Linux-GNU-Fortran.cmake b/Modules/Platform/Linux-GNU-Fortran.cmake
index 68e9540..85e1226 100644
--- a/Modules/Platform/Linux-GNU-Fortran.cmake
+++ b/Modules/Platform/Linux-GNU-Fortran.cmake
@@ -1,2 +1,3 @@
 include(Platform/Linux-GNU)
 __linux_compiler_gnu(Fortran)
+set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "")
diff --git a/Modules/Platform/SunOS.cmake b/Modules/Platform/SunOS.cmake
index aaa79c4..77946f2 100644
--- a/Modules/Platform/SunOS.cmake
+++ b/Modules/Platform/SunOS.cmake
@@ -7,14 +7,6 @@ if(CMAKE_SYSTEM MATCHES "SunOS-4")
    set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
 endif()
 
-if(CMAKE_COMPILER_IS_GNUCXX)
-  if(CMAKE_COMPILER_IS_GNUCC)
-    set(CMAKE_CXX_CREATE_SHARED_LIBRARY
-        "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS>  <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
-  else()
-    # Take default rule from CMakeDefaultMakeRuleVariables.cmake.
-  endif()
-endif()
 include(Platform/UnixPaths)
 
 # Add the compiler's implicit link directories.
diff --git a/Modules/Platform/Windows-Embarcadero.cmake b/Modules/Platform/Windows-Embarcadero.cmake
index 26b3c0c..5295a48 100644
--- a/Modules/Platform/Windows-Embarcadero.cmake
+++ b/Modules/Platform/Windows-Embarcadero.cmake
@@ -74,6 +74,12 @@ set (CMAKE_MODULE_LINKER_FLAGS_INIT ${CMAKE_SHARED_LINKER_FLAGS_INIT})
 set (CMAKE_MODULE_LINKER_FLAGS_DEBUG_INIT ${CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT})
 set (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT})
 
+# The Borland link tool does not support multiple concurrent
+# invocations within a single working directory.
+if(NOT DEFINED CMAKE_JOB_POOL_LINK)
+  set(CMAKE_JOB_POOL_LINK BCC32LinkPool)
+  set_property(GLOBAL APPEND PROPERTY JOB_POOLS BCC32LinkPool=1)
+endif()
 
 macro(__embarcadero_language lang)
   set(CMAKE_${lang}_COMPILE_OPTIONS_DLL "${_tD}") # Note: This variable is a ';' separated list
@@ -84,7 +90,7 @@ macro(__embarcadero_language lang)
   # place <DEFINES> outside the response file because Borland refuses
   # to parse quotes from the response file.
   set(CMAKE_${lang}_COMPILE_OBJECT
-    "<CMAKE_${lang}_COMPILER> ${_tR} <DEFINES> -DWIN32 -o<OBJECT> <FLAGS> ${_COMPILE_${lang}} <SOURCE>"
+    "<CMAKE_${lang}_COMPILER> ${_tR} -DWIN32 <DEFINES> <INCLUDES> <FLAGS> -o<OBJECT> ${_COMPILE_${lang}} <SOURCE>"
     )
 
   set(CMAKE_${lang}_LINK_EXECUTABLE
@@ -95,7 +101,7 @@ macro(__embarcadero_language lang)
   # place <DEFINES> outside the response file because Borland refuses
   # to parse quotes from the response file.
   set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE
-    "cpp32 <DEFINES> -DWIN32 <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>"
+    "cpp32 -DWIN32 <DEFINES> <INCLUDES> <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>"
     )
   # Borland >= 5.6 allows -P option for cpp32, <= 5.5 does not
 
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index b97409c..d8a423e 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -65,7 +65,7 @@ macro(__windows_compiler_gnu lang)
 
   if(MSYS OR MINGW)
     # Create archiving rules to support large object file lists for static libraries.
-    set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> cq <TARGET> <LINK_FLAGS> <OBJECTS>")
+    set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
     set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
     set(CMAKE_${lang}_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
 
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 13fe8bc..b421b0d 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -46,8 +46,10 @@ else()
   set(_PLATFORM_LINK_FLAGS "")
 endif()
 
+set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1)
 if(CMAKE_GENERATOR MATCHES "Visual Studio 6")
    set (CMAKE_NO_BUILD_TYPE 1)
+   set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 0) # not implemented for VS6
 endif()
 if(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio")
   set (CMAKE_NO_BUILD_TYPE 1)
@@ -177,7 +179,9 @@ elseif(WINDOWS_PHONE OR WINDOWS_STORE)
   set(_PLATFORM_DEFINES "/DWIN32")
   set(_FLAGS_C " /DUNICODE /D_UNICODE")
   set(_FLAGS_CXX " /DUNICODE /D_UNICODE /GR /EHsc")
-  if(WINDOWS_PHONE)
+  if(WINDOWS_STORE AND MSVC_VERSION GREATER 1899)
+    set(CMAKE_C_STANDARD_LIBRARIES_INIT "WindowsApp.lib")
+  elseif(WINDOWS_PHONE)
     set(CMAKE_C_STANDARD_LIBRARIES_INIT "WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib")
   elseif(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM" OR _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM")
     set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib")
@@ -230,6 +234,7 @@ elseif(MSVC_Fortran_ARCHITECTURE_ID)
   set(_MACHINE_ARCH_FLAG "/machine:${MSVC_Fortran_ARCHITECTURE_ID}")
 endif()
 set(CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT} ${_MACHINE_ARCH_FLAG}")
+set(CMAKE_STATIC_LINKER_FLAGS_INIT "${CMAKE_STATIC_LINKER_FLAGS_INIT} ${_MACHINE_ARCH_FLAG}")
 unset(_MACHINE_ARCH_FLAG)
 
 # add /debug and /INCREMENTAL:YES to DEBUG and RELWITHDEBINFO also add pdbtype
@@ -271,8 +276,8 @@ set (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZER
 macro(__windows_compiler_msvc lang)
   if(NOT MSVC_VERSION LESS 1400)
     # for 2005 make sure the manifest is put in the dll with mt
-    set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll ")
-    set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe ")
+    set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
+    set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
   endif()
   set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
     "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
@@ -281,11 +286,11 @@ macro(__windows_compiler_msvc lang)
   set(CMAKE_${lang}_CREATE_STATIC_LIBRARY  "<CMAKE_LINKER> /lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
 
   set(CMAKE_${lang}_COMPILE_OBJECT
-    "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> /Fo<OBJECT> /Fd<TARGET_COMPILE_PDB>${_FS_${lang}} -c <SOURCE>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <INCLUDES> <FLAGS> /Fo<OBJECT> /Fd<TARGET_COMPILE_PDB>${_FS_${lang}} -c <SOURCE>${CMAKE_END_TEMP_FILE}")
   set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE
-    "<CMAKE_${lang}_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> -E <SOURCE>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_${lang}_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE>${CMAKE_END_TEMP_FILE}")
   set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE
-    "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> /FoNUL /FAs /Fa<ASSEMBLY_SOURCE> /c <SOURCE>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <INCLUDES> <FLAGS> /FoNUL /FAs /Fa<ASSEMBLY_SOURCE> /c <SOURCE>${CMAKE_END_TEMP_FILE}")
 
   set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1)
   set(CMAKE_${lang}_LINK_EXECUTABLE
diff --git a/Modules/Platform/Windows-wcl386.cmake b/Modules/Platform/Windows-wcl386.cmake
index 88f9bf7..3bc5444 100644
--- a/Modules/Platform/Windows-wcl386.cmake
+++ b/Modules/Platform/Windows-wcl386.cmake
@@ -58,19 +58,19 @@ set(CMAKE_CXX_LINK_EXECUTABLE ${CMAKE_C_LINK_EXECUTABLE})
 
 # compile a C++ file into an object file
 set(CMAKE_CXX_COMPILE_OBJECT
-    "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} <FLAGS> -d+ <DEFINES> -fo<OBJECT> -c -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
 
 # compile a C file into an object file
 set(CMAKE_C_COMPILE_OBJECT
-    "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} <FLAGS> -d+ <DEFINES> -fo<OBJECT> -c -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
 
 # preprocess a C source file
 set(CMAKE_C_CREATE_PREPROCESSED_SOURCE
-    "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} <FLAGS> -d+ <DEFINES> -fo<PREPROCESSED_SOURCE> -pl -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
 
 # preprocess a C++ source file
 set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE
-    "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} <FLAGS> -d+ <DEFINES> -fo<PREPROCESSED_SOURCE> -pl -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
 
 set(CMAKE_CXX_CREATE_SHARED_LIBRARY
  "wlink ${CMAKE_START_TEMP_FILE} ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> option implib=<TARGET_IMPLIB> file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
diff --git a/Modules/Platform/Windows-windres.cmake b/Modules/Platform/Windows-windres.cmake
index 01d6be3..7d787dd 100644
--- a/Modules/Platform/Windows-windres.cmake
+++ b/Modules/Platform/Windows-windres.cmake
@@ -1 +1 @@
-set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <FLAGS> <DEFINES> <SOURCE> <OBJECT>")
+set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> <INCLUDES> <FLAGS> <SOURCE> <OBJECT>")
diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake
index 8f21adf..2c5d5ae 100644
--- a/Modules/ProcessorCount.cmake
+++ b/Modules/ProcessorCount.cmake
@@ -171,17 +171,30 @@ function(ProcessorCount var)
   endif()
 
   if(NOT count)
-    # Sun (systems where uname -X emits "NumCPU" in its output):
-    find_program(ProcessorCount_cmd_uname uname)
-    mark_as_advanced(ProcessorCount_cmd_uname)
-    if(ProcessorCount_cmd_uname)
-      execute_process(COMMAND ${ProcessorCount_cmd_uname} -X
+    # Sun (systems where psrinfo tool is available)
+    find_program(ProcessorCount_cmd_psrinfo psrinfo PATHS /usr/sbin /sbin)
+    mark_as_advanced(ProcessorCount_cmd_psrinfo)
+    if (ProcessorCount_cmd_psrinfo)
+      execute_process(COMMAND ${ProcessorCount_cmd_psrinfo} -p -v
         ERROR_QUIET
         OUTPUT_STRIP_TRAILING_WHITESPACE
-        OUTPUT_VARIABLE uname_X_output)
-      string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}")
+        OUTPUT_VARIABLE psrinfo_output)
+      string(REGEX MATCH "([0-9]+) virtual processor" procs "${psrinfo_output}")
       set(count "${CMAKE_MATCH_1}")
-      #message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'")
+      #message("ProcessorCount: trying psrinfo -p -v '${ProcessorCount_cmd_prvinfo}'")
+    else()
+      # Sun (systems where uname -X emits "NumCPU" in its output):
+      find_program(ProcessorCount_cmd_uname uname)
+      mark_as_advanced(ProcessorCount_cmd_uname)
+      if(ProcessorCount_cmd_uname)
+        execute_process(COMMAND ${ProcessorCount_cmd_uname} -X
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE
+          OUTPUT_VARIABLE uname_X_output)
+        string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}")
+        set(count "${CMAKE_MATCH_1}")
+        #message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'")
+      endif()
     endif()
   endif()
 
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index 5eb0ca8..dced6ec 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -21,7 +21,8 @@
 #
 # This command creates a <target_name>.jar.  It compiles the given
 # source files (source) and adds the given resource files (resource) to
-# the jar file.  If only resource files are given then just a jar file
+# the jar file.  Source files can be java files or listing files
+# (prefixed by '@').  If only resource files are given then just a jar file
 # is created.  The list of include jars are added to the classpath when
 # compiling the java sources and also to the dependencies of the target.
 # INCLUDE_JARS also accepts other target names created by add_jar.  For
@@ -210,14 +211,16 @@
 #
 # ::
 #
-#  install_jar(TARGET_NAME DESTINATION)
+#  install_jar(target_name destination)
+#  install_jar(target_name DESTINATION destination [COMPONENT component])
 #
 # This command installs the TARGET_NAME files to the given DESTINATION.
 # It should be called in the same scope as add_jar() or it will fail.
 #
 # ::
 #
-#  install_jni_symlink(TARGET_NAME DESTINATION)
+#  install_jni_symlink(target_name destination)
+#  install_jni_symlink(target_name DESTINATION destination [COMPONENT component])
 #
 # This command installs the TARGET_NAME JNI symlinks to the given
 # DESTINATION.  It should be called in the same scope as add_jar() or it
@@ -306,6 +309,65 @@
 #
 #
 # if you don't set the INSTALLPATH.
+#
+# ::
+#
+#  create_javah(TARGET <target>
+#               GENERATED_FILES <VAR>
+#               CLASSES <class>...
+#               [CLASSPATH <classpath>...]
+#               [DEPENDS <depend>...]
+#               [OUTPUT_NAME <path>|OUTPUT_DIR <path>]
+#               )
+#
+# Create C header files from java classes. These files provide the connective glue
+# that allow your Java and C code to interact.
+#
+# There are two main signatures for create_javah.  The first signature
+# returns generated files throught variable specified by GENERATED_FILES option:
+#
+# ::
+#
+#    Example:
+#    Create_javah(GENERATED_FILES files_headers
+#      CLASSES org.cmake.HelloWorld
+#      CLASSPATH hello.jar
+#    )
+#
+#
+#
+# The second signature for create_javah creates a target which encapsulates
+# header files generation.
+#
+# ::
+#
+#    Example:
+#    Create_javah(TARGET target_headers
+#      CLASSES org.cmake.HelloWorld
+#      CLASSPATH hello.jar
+#    )
+#
+#
+#
+# Both signatures share same options.
+#
+#  ``CLASSES <class>...``
+#    Specifies Java classes used to generate headers.
+#
+#  ``CLASSPATH <classpath>...``
+#    Specifies various paths to look up classes. Here .class files, jar files or targets
+#    created by command add_jar can be used.
+#
+#  ``DEPENDS <depend>...``
+#    Targets on which the javah target depends
+#
+#  ``OUTPUT_NAME <path>``
+#    Concatenates the resulting header files for all the classes listed by option CLASSES
+#    into <path>. Same behavior as option '-o' of javah tool.
+#
+#  ``OUTPUT_DIR <path>``
+#    Sets the directory where the header files will be generated. Same behavior as option
+#    '-d' of javah tool. If not specified, ${CMAKE_CURRENT_BINARY_DIR} is used as output directory.
 
 #=============================================================================
 # Copyright 2013 OpenGamma Ltd. <graham at opengamma.com>
@@ -423,6 +485,7 @@ function(add_jar _TARGET_NAME)
 
     set(_JAVA_CLASS_FILES)
     set(_JAVA_COMPILE_FILES)
+    set(_JAVA_COMPILE_FILELISTS)
     set(_JAVA_DEPENDS)
     set(_JAVA_COMPILE_DEPENDS)
     set(_JAVA_RESOURCE_FILES)
@@ -433,7 +496,11 @@ function(add_jar _TARGET_NAME)
         get_filename_component(_JAVA_PATH ${_JAVA_SOURCE_FILE} PATH)
         get_filename_component(_JAVA_FULL ${_JAVA_SOURCE_FILE} ABSOLUTE)
 
-        if (_JAVA_EXT MATCHES ".java")
+        if (_JAVA_SOURCE_FILE MATCHES "^@(.+)$")
+            get_filename_component(_JAVA_FULL ${CMAKE_MATCH_1} ABSOLUTE)
+            list(APPEND _JAVA_COMPILE_FILELISTS ${_JAVA_FULL})
+
+        elseif (_JAVA_EXT MATCHES ".java")
             file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${_add_jar_OUTPUT_DIR} ${_JAVA_FULL})
             file(RELATIVE_PATH _JAVA_REL_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${_JAVA_FULL})
             string(LENGTH ${_JAVA_REL_BINARY_PATH} _BIN_LEN)
@@ -492,11 +559,21 @@ function(add_jar _TARGET_NAME)
         file(WRITE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist "")
     endif()
 
-    if (_JAVA_COMPILE_FILES)
-        # Create the list of files to compile.
-        set(_JAVA_SOURCES_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_sources)
-        string(REPLACE ";" "\"\n\"" _JAVA_COMPILE_STRING "\"${_JAVA_COMPILE_FILES}\"")
-        file(WRITE ${_JAVA_SOURCES_FILE} ${_JAVA_COMPILE_STRING})
+    if (_JAVA_COMPILE_FILES OR _JAVA_COMPILE_FILELISTS)
+        set (_JAVA_SOURCES_FILELISTS)
+
+        if (_JAVA_COMPILE_FILES)
+            # Create the list of files to compile.
+            set(_JAVA_SOURCES_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_sources)
+            string(REPLACE ";" "\"\n\"" _JAVA_COMPILE_STRING "\"${_JAVA_COMPILE_FILES}\"")
+            file(WRITE ${_JAVA_SOURCES_FILE} ${_JAVA_COMPILE_STRING})
+            list (APPEND _JAVA_SOURCES_FILELISTS "@${_JAVA_SOURCES_FILE}")
+        endif()
+        if (_JAVA_COMPILE_FILELISTS)
+            foreach (_JAVA_FILELIST IN LISTS _JAVA_COMPILE_FILELISTS)
+                list (APPEND _JAVA_SOURCES_FILELISTS "@${_JAVA_FILELIST}")
+            endforeach()
+        endif()
 
         # Compile the java files and create a list of class files
         add_custom_command(
@@ -506,9 +583,9 @@ function(add_jar _TARGET_NAME)
                 ${CMAKE_JAVA_COMPILE_FLAGS}
                 -classpath "${CMAKE_JAVA_INCLUDE_PATH_FINAL}"
                 -d ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
-                @${_JAVA_SOURCES_FILE}
+                ${_JAVA_SOURCES_FILELISTS}
             COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
-            DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_DEPENDS}
+            DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS}
             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
             COMMENT "Building Java objects for ${_TARGET_NAME}.jar"
         )
@@ -613,7 +690,26 @@ function(add_jar _TARGET_NAME)
 
 endfunction()
 
-function(INSTALL_JAR _TARGET_NAME _DESTINATION)
+function(INSTALL_JAR _TARGET_NAME)
+    if (ARGC EQUAL 2)
+      set (_DESTINATION ${ARGV1})
+    else()
+      cmake_parse_arguments(_install_jar
+        ""
+        "DESTINATION;COMPONENT"
+        ""
+        ${ARGN})
+      if (_install_jar_DESTINATION)
+        set (_DESTINATION ${_install_jar_DESTINATION})
+      else()
+        message(SEND_ERROR "install_jar: ${_TARGET_NAME}: DESTINATION must be specified.")
+      endif()
+
+      if (_install_jar_COMPONENT)
+        set (_COMPONENT COMPONENT ${_install_jar_COMPONENT})
+      endif()
+    endif()
+
     get_property(__FILES
         TARGET
             ${_TARGET_NAME}
@@ -627,13 +723,33 @@ function(INSTALL_JAR _TARGET_NAME _DESTINATION)
                 ${__FILES}
             DESTINATION
                 ${_DESTINATION}
+            ${_COMPONENT}
         )
     else ()
-        message(SEND_ERROR "The target ${_TARGET_NAME} is not known in this scope.")
+        message(SEND_ERROR "install_jar: The target ${_TARGET_NAME} is not known in this scope.")
     endif ()
 endfunction()
 
-function(INSTALL_JNI_SYMLINK _TARGET_NAME _DESTINATION)
+function(INSTALL_JNI_SYMLINK _TARGET_NAME)
+    if (ARGC EQUAL 2)
+      set (_DESTINATION ${ARGV1})
+    else()
+      cmake_parse_arguments(_install_jni_symlink
+        ""
+        "DESTINATION;COMPONENT"
+        ""
+        ${ARGN})
+      if (_install_jni_symlink_DESTINATION)
+        set (_DESTINATION ${_install_jni_symlink_DESTINATION})
+      else()
+        message(SEND_ERROR "install_jni_symlink: ${_TARGET_NAME}: DESTINATION must be specified.")
+      endif()
+
+      if (_install_jni_symlink_COMPONENT)
+        set (_COMPONENT COMPONENT ${_install_jni_symlink_COMPONENT})
+      endif()
+    endif()
+
     get_property(__SYMLINK
         TARGET
             ${_TARGET_NAME}
@@ -647,9 +763,10 @@ function(INSTALL_JNI_SYMLINK _TARGET_NAME _DESTINATION)
                 ${__SYMLINK}
             DESTINATION
                 ${_DESTINATION}
+            ${_COMPONENT}
         )
     else ()
-        message(SEND_ERROR "The target ${_TARGET_NAME} is not known in this scope.")
+        message(SEND_ERROR "install_jni_symlink: The target ${_TARGET_NAME} is not known in this scope.")
     endif ()
 endfunction()
 
@@ -1073,3 +1190,101 @@ function(create_javadoc _target)
         DESTINATION ${_javadoc_installpath}
     )
 endfunction()
+
+function (create_javah)
+    cmake_parse_arguments(_create_javah
+      ""
+      "TARGET;GENERATED_FILES;OUTPUT_NAME;OUTPUT_DIR"
+      "CLASSES;CLASSPATH;DEPENDS"
+      ${ARGN})
+
+    # ckeck parameters
+    if (NOT _create_javah_TARGET AND NOT _create_javah_GENERATED_FILES)
+      message (FATAL_ERROR "create_javah: TARGET or GENERATED_FILES must be specified.")
+    endif()
+    if (_create_javah_OUTPUT_NAME AND _create_javah_OUTPUT_DIR)
+      message (FATAL_ERROR "create_javah: OUTPUT_NAME and OUTPUT_DIR are mutually exclusive.")
+    endif()
+
+    if (NOT _create_javah_CLASSES)
+      message (FATAL_ERROR "create_javah: CLASSES is a required parameter.")
+    endif()
+
+    set (_output_files)
+    if (WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
+      set(_classpath_sep ";")
+    else ()
+      set(_classpath_sep ":")
+    endif()
+
+    # handle javah options
+    set (_javah_options)
+
+    if (_create_javah_CLASSPATH)
+      # CLASSPATH can specify directories, jar files or targets created with add_jar command
+      set (_classpath)
+      foreach (_path IN LISTS _create_javah_CLASSPATH)
+        if (TARGET ${_path})
+          get_target_property (_jar_path ${_path} JAR_FILE)
+          if (_jar_path)
+            list (APPEND _classpath "${_jar_path}")
+            list (APPEND _create_javah_DEPENDS "${_path}")
+          else()
+            message(SEND_ERROR "create_javah: CLASSPATH target ${_path} is not a jar.")
+          endif()
+        elseif (EXISTS "${_path}")
+          list (APPEND _classpath "${_path}")
+          if (NOT IS_DIRECTORY "${_path}")
+            list (APPEND _create_javah_DEPENDS "${_path}")
+          endif()
+        else()
+          message(SEND_ERROR "create_javah: CLASSPATH entry ${_path} does not exist.")
+        endif()
+      endforeach()
+      string (REPLACE ";" "${_classpath_sep}" _classpath "${_classpath}")
+      list (APPEND _javah_options -classpath ${_classpath})
+    endif()
+
+    if (_create_javah_OUTPUT_DIR)
+      list (APPEND _javah_options -d "${_create_javah_OUTPUT_DIR}")
+    endif()
+
+    if (_create_javah_OUTPUT_NAME)
+      list (APPEND _javah_options -o "${_create_javah_OUTPUT_NAME}")
+      set (_output_files "${_create_javah_OUTPUT_NAME}")
+
+      get_filename_component (_create_javah_OUTPUT_DIR "${_create_javah_OUTPUT_NAME}" DIRECTORY)
+      get_filename_component (_create_javah_OUTPUT_DIR "${_create_javah_OUTPUT_DIR}" ABSOLUTE)
+    endif()
+
+    if (NOT _create_javah_OUTPUT_DIR)
+      set (_create_javah_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+    endif()
+
+    if (NOT _create_javah_OUTPUT_NAME)
+      # compute output names
+      foreach (_class IN LISTS _create_javah_CLASSES)
+        string (REPLACE "." "_" _c_header "${_class}")
+        set (_c_header  "${_create_javah_OUTPUT_DIR}/${_c_header}.h")
+        list (APPEND _output_files "${_c_header}")
+      endforeach()
+    endif()
+
+    # finalize custom command arguments
+    if (_create_javah_DEPENDS)
+      list (INSERT _create_javah_DEPENDS 0 DEPENDS)
+    endif()
+
+    add_custom_command (OUTPUT ${_output_files}
+      COMMAND "${Java_JAVAH_EXECUTABLE}" ${_javah_options} -jni ${_create_javah_CLASSES}
+      ${_create_javah_DEPENDS}
+      WORKING_DIRECTORY ${_create_javah_OUTPUT_DIR}
+      COMMENT "Building C header files from classes...")
+
+    if (_create_javah_TARGET)
+      add_custom_target (${_create_javah_TARGET} ALL DEPENDS ${_output_files})
+    endif()
+    if (_create_javah_GENERATED_FILES)
+      set (${_create_javah_GENERATED_FILES} ${_output_files} PARENT_SCOPE)
+    endif()
+endfunction()
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 96b0b35..d757f65 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -153,10 +153,12 @@ macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
   else()
     set(swig_outdir ${CMAKE_CURRENT_BINARY_DIR})
   endif()
-  SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
-    swig_extra_generated_files
-    "${swig_outdir}"
-    "${swig_source_file_fullname}")
+  if (NOT SWIG_MODULE_${name}_NOPROXY)
+    SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
+      swig_extra_generated_files
+      "${swig_outdir}"
+      "${swig_source_file_fullname}")
+  endif()
   set(swig_generated_file_fullname
     "${swig_outdir}/${swig_source_file_name_we}")
   # add the language into the name of the file (i.e. TCL_wrap)
diff --git a/Modules/UseVTK40.cmake b/Modules/UseVTK40.cmake
deleted file mode 100644
index d6bdaaa..0000000
--- a/Modules/UseVTK40.cmake
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-
-#=============================================================================
-# Copyright 2002-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-# This is an implementation detail for using VTK 4.0 with the
-# FindVTK.cmake module.  Do not include directly by name.  This should
-# be included only when FindVTK.cmake sets the VTK_USE_FILE variable
-# to point here.
-
-# Add compiler flags needed to use VTK.
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${VTK_REQUIRED_C_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${VTK_REQUIRED_CXX_FLAGS}")
-
-# Add include directories needed to use VTK.
-include_directories(${VTK_INCLUDE_DIRS})
-
-# Add link directories needed to use VTK.
-link_directories(${VTK_LIBRARY_DIRS})
diff --git a/Modules/UseVTKBuildSettings40.cmake b/Modules/UseVTKBuildSettings40.cmake
deleted file mode 100644
index 474f67c..0000000
--- a/Modules/UseVTKBuildSettings40.cmake
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-
-#=============================================================================
-# Copyright 2002-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-# Implementation detail for FindVTK.cmake to let it provide a
-# VTK_BUILD_SETTINGS_FILE for VTK 4.0.
-
-set(CMAKE_BUILD_SETTING_CMAKE_MAJOR_VERSION "${VTK40_CMAKE_MAJOR_VERSION}")
-set(CMAKE_BUILD_SETTING_CMAKE_MINOR_VERSION "${VTK40_CMAKE_MINOR_VERSION}")
-set(CMAKE_BUILD_SETTING_PROJECT_NAME "VTK")
-
-set(CMAKE_BUILD_SETTING_C_COMPILER "${VTK40_CMAKE_C_COMPILER}")
-set(CMAKE_BUILD_SETTING_C_FLAGS "${VTK40_CMAKE_C_FLAGS}")
-set(CMAKE_BUILD_SETTING_C_FLAGS_DEBUG "${VTK40_CMAKE_C_FLAGS_DEBUG}")
-set(CMAKE_BUILD_SETTING_C_FLAGS_RELEASE "${VTK40_CMAKE_C_FLAGS_RELEASE}")
-set(CMAKE_BUILD_SETTING_C_FLAGS_MINSIZEREL "${VTK40_CMAKE_C_FLAGS_MINSIZEREL}")
-set(CMAKE_BUILD_SETTING_C_FLAGS_RELWITHDEBINFO "${VTK40_CMAKE_C_FLAGS_RELWITHDEBINFO}")
-
-set(CMAKE_BUILD_SETTING_CXX_COMPILER "${VTK40_CMAKE_CXX_COMPILER}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS "${VTK40_CMAKE_CXX_FLAGS}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS_DEBUG "${VTK40_CMAKE_CXX_FLAGS_DEBUG}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS_RELEASE "${VTK40_CMAKE_CXX_FLAGS_RELEASE}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS_MINSIZEREL "${VTK40_CMAKE_CXX_FLAGS_MINSIZEREL}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS_RELWITHDEBINFO "${VTK40_CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
-
-set(CMAKE_BUILD_SETTING_BUILD_TYPE "${VTK40_CMAKE_BUILD_TYPE}")
-set(CMAKE_BUILD_SETTING_BUILD_TOOL "${VTK40_CMAKE_BUILD_TOOL}")
diff --git a/Modules/UseVTKConfig40.cmake b/Modules/UseVTKConfig40.cmake
deleted file mode 100644
index c5022e4..0000000
--- a/Modules/UseVTKConfig40.cmake
+++ /dev/null
@@ -1,409 +0,0 @@
-#
-
-#=============================================================================
-# Copyright 2002-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-# This is an implementation detail for using VTK 4.0 with the
-# FindVTK.cmake module.  Do not include directly.
-
-# Hard-code the version number since it isn't provided by VTK 4.0.
-set(VTK_MAJOR_VERSION 4)
-set(VTK_MINOR_VERSION 0)
-set(VTK_BUILD_VERSION 2)
-
-# Provide a new UseVTK file that doesn't do a full LOAD_CACHE.
-set(VTK_USE_FILE ${CMAKE_ROOT}/Modules/UseVTK40.cmake)
-
-# Provide a build settings file.
-set(VTK_BUILD_SETTINGS_FILE ${CMAKE_ROOT}/Modules/UseVTKBuildSettings40.cmake)
-
-# There are no CMake extensions for VTK 4.0.
-set(VTK_CMAKE_EXTENSIONS_DIR "")
-
-# grep "VTK40_" UseVTKConfig40.cmake |sed 's/.*VTK40_\([A-Za-z0-9_]*\).*/  \1/'
-load_cache(${VTK_DIR} READ_WITH_PREFIX VTK40_
-  BUILD_SHARED_LIBS
-  CMAKE_BUILD_TOOL
-  CMAKE_BUILD_TYPE
-  CMAKE_CACHE_MAJOR_VERSION
-  CMAKE_CACHE_MINOR_VERSION
-  CMAKE_CXX_COMPILER
-  CMAKE_CXX_FLAGS
-  CMAKE_CXX_FLAGS_DEBUG
-  CMAKE_CXX_FLAGS_MINSIZEREL
-  CMAKE_CXX_FLAGS_RELEASE
-  CMAKE_CXX_FLAGS_RELWITHDEBINFO
-  CMAKE_C_COMPILER
-  CMAKE_C_FLAGS
-  CMAKE_C_FLAGS_DEBUG
-  CMAKE_C_FLAGS_MINSIZEREL
-  CMAKE_C_FLAGS_RELEASE
-  CMAKE_C_FLAGS_RELWITHDEBINFO
-  CMAKE_INSTALL_PREFIX
-  CMAKE_Xutil_INCLUDE_PATH
-  EXECUTABLE_OUTPUT_PATH
-  JAVA_INCLUDE_PATH2
-  LIBRARY_OUTPUT_PATH
-  MPIRUN
-  MPI_INCLUDE_PATH
-  MPI_POSTFLAGS
-  MPI_PREFLAGS
-  OPENGL_INCLUDE_DIR
-  OSMESA_INCLUDE_PATH
-  PYTHON_INCLUDE_PATH
-  TCL_INCLUDE_PATH
-  VLI_INCLUDE_PATH_FOR_VG500
-  VLI_INCLUDE_PATH_FOR_VP1000
-  VTK_BINARY_DIR
-  VTK_DEBUG_LEAKS
-  VTK_HAVE_VG500
-  VTK_HAVE_VP1000
-  VTK_MANGLE_MESA
-  VTK_OPENGL_HAS_OSMESA
-  VTK_PARSE_JAVA_EXE
-  VTK_SOURCE_DIR
-  VTK_USE_64BIT_IDS
-  VTK_USE_ANSI_STDLIB
-  VTK_USE_HYBRID
-  VTK_USE_MATROX_IMAGING
-  VTK_USE_MPI
-  VTK_USE_PARALLEL
-  VTK_USE_PATENTED
-  VTK_USE_RENDERING
-  VTK_USE_VIDEO_FOR_WINDOWS
-  VTK_USE_VOLUMEPRO
-  VTK_USE_X
-  VTK_WRAP_JAVA
-  VTK_WRAP_JAVA_EXE
-  VTK_WRAP_PYTHON
-  VTK_WRAP_PYTHON_EXE
-  VTK_WRAP_TCL
-  VTK_WRAP_TCL_EXE
-  vtkCommonJava_LIB_DEPENDS
-  vtkCommonPython_LIB_DEPENDS
-  vtkCommonTCL_LIB_DEPENDS
-  vtkCommon_LIB_DEPENDS
-  vtkFilteringJava_LIB_DEPENDS
-  vtkFilteringPython_LIB_DEPENDS
-  vtkFilteringTCL_LIB_DEPENDS
-  vtkFiltering_LIB_DEPENDS
-  vtkGraphicsJava_LIB_DEPENDS
-  vtkGraphicsPython_LIB_DEPENDS
-  vtkGraphicsTCL_LIB_DEPENDS
-  vtkGraphics_LIB_DEPENDS
-  vtkHybridJava_LIB_DEPENDS
-  vtkHybridPython_LIB_DEPENDS
-  vtkHybridTCL_LIB_DEPENDS
-  vtkHybrid_LIB_DEPENDS
-  vtkIOJava_LIB_DEPENDS
-  vtkIOPython_LIB_DEPENDS
-  vtkIOTCL_LIB_DEPENDS
-  vtkIO_LIB_DEPENDS
-  vtkImagingJava_LIB_DEPENDS
-  vtkImagingPython_LIB_DEPENDS
-  vtkImagingTCL_LIB_DEPENDS
-  vtkImaging_LIB_DEPENDS
-  vtkParallelJava_LIB_DEPENDS
-  vtkParallelPython_LIB_DEPENDS
-  vtkParallelTCL_LIB_DEPENDS
-  vtkParallel_LIB_DEPENDS
-  vtkPatentedJava_LIB_DEPENDS
-  vtkPatentedPython_LIB_DEPENDS
-  vtkPatentedTCL_LIB_DEPENDS
-  vtkPatented_LIB_DEPENDS
-  vtkRenderingJava_LIB_DEPENDS
-  vtkRenderingPythonTkWidgets_LIB_DEPENDS
-  vtkRenderingPython_LIB_DEPENDS
-  vtkRenderingTCL_LIB_DEPENDS
-  vtkRendering_LIB_DEPENDS
-  vtkjpeg_LIB_DEPENDS
-  vtkpng_LIB_DEPENDS
-  vtkzlib_LIB_DEPENDS
-)
-
-# Copy needed settings from the VTK 4.0 cache.
-set(VTK_BUILD_SHARED ${VTK40_BUILD_SHARED_LIBS})
-set(VTK_DEBUG_LEAKS ${VTK40_VTK_DEBUG_LEAKS})
-set(VTK_HAVE_VG500 ${VTK40_VTK_HAVE_VG500})
-set(VTK_HAVE_VP1000 ${VTK40_VTK_HAVE_VP1000})
-set(VTK_USE_MANGLED_MESA ${VTK40_VTK_MANGLE_MESA})
-set(VTK_MPIRUN_EXE ${VTK40_MPIRUN})
-set(VTK_MPI_POSTFLAGS ${VTK40_MPI_POSTFLAGS})
-set(VTK_MPI_PREFLAGS ${VTK40_MPI_PREFLAGS})
-set(VTK_OPENGL_HAS_OSMESA ${VTK40_VTK_OPENGL_HAS_OSMESA})
-set(VTK_USE_64BIT_IDS ${VTK40_VTK_USE_64BIT_IDS})
-set(VTK_USE_ANSI_STDLIB ${VTK40_VTK_USE_ANSI_STDLIB})
-set(VTK_USE_HYBRID ${VTK40_VTK_USE_HYBRID})
-set(VTK_USE_MATROX_IMAGING ${VTK40_VTK_USE_MATROX_IMAGING})
-set(VTK_USE_MPI ${VTK40_VTK_USE_MPI})
-set(VTK_USE_PARALLEL ${VTK40_VTK_USE_PARALLEL})
-set(VTK_USE_PATENTED ${VTK40_VTK_USE_PATENTED})
-set(VTK_USE_RENDERING ${VTK40_VTK_USE_RENDERING})
-set(VTK_USE_VIDEO_FOR_WINDOWS ${VTK40_VTK_USE_VIDEO_FOR_WINDOWS})
-set(VTK_USE_VOLUMEPRO ${VTK40_VTK_USE_VOLUMEPRO})
-set(VTK_USE_X ${VTK40_VTK_USE_X})
-set(VTK_WRAP_JAVA ${VTK40_VTK_WRAP_JAVA})
-set(VTK_WRAP_PYTHON ${VTK40_VTK_WRAP_PYTHON})
-set(VTK_WRAP_TCL ${VTK40_VTK_WRAP_TCL})
-
-# Create the list of available kits.
-set(VTK_KITS COMMON FILTERING GRAPHICS IMAGING IO)
-if(VTK_USE_RENDERING)
-  set(VTK_KITS ${VTK_KITS} RENDERING)
-endif()
-if(VTK_USE_HYBRID)
-  set(VTK_KITS ${VTK_KITS} HYBRID)
-endif()
-if(VTK_USE_PARALLEL)
-  set(VTK_KITS ${VTK_KITS} PARALLEL)
-endif()
-if(VTK_USE_PATENTED)
-  set(VTK_KITS ${VTK_KITS} PATENTED)
-endif()
-
-# Create the list of available languages.
-set(VTK_LANGUAGES "")
-if(VTK_WRAP_TCL)
-  set(VTK_LANGUAGES ${VTK_LANGUAGES} TCL)
-endif()
-if(VTK_WRAP_PYTHON)
-  set(VTK_LANGUAGES ${VTK_LANGUAGES} PYTHON)
-endif()
-if(VTK_WRAP_JAVA)
-  set(VTK_LANGUAGES ${VTK_LANGUAGES} JAVA)
-endif()
-
-# Include directories for other projects installed on the system and
-# used by VTK.
-set(VTK_INCLUDE_DIRS_SYS "")
-if(VTK_USE_RENDERING)
-  set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
-      ${VTK40_OPENGL_INCLUDE_PATH} ${VTK40_OPENGL_INCLUDE_DIR})
-  if(VTK_USE_X)
-    set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
-        ${VTK40_CMAKE_Xlib_INCLUDE_PATH} ${VTK40_CMAKE_Xutil_INCLUDE_PATH})
-  endif()
-endif()
-
-if(VTK_OPENGL_HAS_OSMESA)
-  set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
-      ${VTK40_OSMESA_INCLUDE_PATH})
-endif()
-
-if(VTK_USE_MPI)
-  set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS} ${VTK40_MPI_INCLUDE_PATH})
-endif()
-
-if(VTK_WRAP_TCL)
-  set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS} ${VTK40_TCL_INCLUDE_PATH})
-endif()
-
-if(VTK_WRAP_PYTHON)
-  set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS} ${VTK40_PYTHON_INCLUDE_PATH})
-endif()
-
-if(VTK_WRAP_JAVA)
-  set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
-      ${VTK40_JAVA_INCLUDE_PATH} ${VTK40_JAVA_INCLUDE_PATH2})
-endif()
-
-if(VTK_HAVE_VG500)
-  set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
-      ${VTK40_VLI_INCLUDE_PATH_FOR_VG500})
-endif()
-
-if(VTK_HAVE_VP1000)
-  set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
-      ${VTK40_VLI_INCLUDE_PATH_FOR_VP1000})
-endif()
-
-# See if this is a build tree or install tree.
-if(EXISTS ${VTK_DIR}/Common)
-  # This is a VTK 4.0 build tree.
-
-  set(VTK_LIBRARY_DIRS ${VTK40_LIBRARY_OUTPUT_PATH})
-
-  # Determine the include directories needed.
-  set(VTK_INCLUDE_DIRS ${VTK40_VTK_BINARY_DIR})
-  if(VTK_USE_PARALLEL)
-    set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Parallel)
-  endif()
-  if(VTK_USE_HYBRID)
-    set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Hybrid)
-  endif()
-  if(VTK_USE_PATENTED)
-    set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Patented)
-  endif()
-  if(VTK_USE_RENDERING)
-    set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Rendering)
-  endif()
-
-  # These directories are always needed.
-  set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS}
-    ${VTK40_VTK_SOURCE_DIR}/IO
-    ${VTK40_VTK_SOURCE_DIR}/Imaging
-    ${VTK40_VTK_SOURCE_DIR}/Graphics
-    ${VTK40_VTK_SOURCE_DIR}/Filtering
-    ${VTK40_VTK_SOURCE_DIR}/Common)
-
-  # Give access to a few utilities.
-  set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS}
-    ${VTK40_VTK_BINARY_DIR}/Utilities/png
-    ${VTK40_VTK_SOURCE_DIR}/Utilities/png
-    ${VTK40_VTK_BINARY_DIR}/Utilities/zlib
-    ${VTK40_VTK_SOURCE_DIR}/Utilities/zlib)
-
-  # Executable locations.
-  if(VTK_WRAP_TCL)
-    set(VTK_TCL_EXE ${VTK40_EXECUTABLE_OUTPUT_PATH}/vtk)
-    set(VTK_WRAP_TCL_EXE ${VTK40_VTK_WRAP_TCL_EXE})
-    set(VTK_TCL_HOME ${VTK40_VTK_SOURCE_DIR}/Wrapping/Tcl)
-  endif()
-  if(VTK_WRAP_PYTHON)
-    set(VTK_WRAP_PYTHON_EXE ${VTK40_VTK_WRAP_PYTHON_EXE})
-  endif()
-  if(VTK_WRAP_JAVA)
-    set(VTK_PARSE_JAVA_EXE ${VTK40_VTK_PARSE_JAVA_EXE})
-    set(VTK_WRAP_JAVA_EXE ${VTK40_VTK_WRAP_JAVA_EXE})
-  endif()
-
-else()
-  # This is a VTK 4.0 install tree.
-
-  set(VTK_INCLUDE_DIRS ${VTK_DIR})
-  set(VTK_LIBRARY_DIRS ${VTK40_CMAKE_INSTALL_PREFIX}/lib/vtk)
-
-  # Executable locations.
-  if(VTK_WRAP_TCL)
-    set(VTK_TCL_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtk)
-    set(VTK_WRAP_TCL_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtkWrapTcl)
-    set(VTK_TCL_HOME ${VTK40_CMAKE_INSTALL_PREFIX}/lib/vtk/tcl)
-  endif()
-  if(VTK_WRAP_PYTHON)
-    set(VTK_WRAP_PYTHON_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtkWrapPython)
-  endif()
-  if(VTK_WRAP_JAVA)
-    set(VTK_PARSE_JAVA_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtkParseJava)
-    set(VTK_WRAP_JAVA_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtkWrapJava)
-  endif()
-endif()
-
-# Add the system include directories last.
-set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK_INCLUDE_DIRS_SYS})
-
-# Find the required C and C++ compiler flags.
-if(CMAKE_COMPILER_IS_GNUCXX)
-  if(WIN32)
-    # The platform is gcc on cygwin.
-    set(VTK_REQUIRED_CXX_FLAGS "${VTK_REQUIRED_CXX_FLAGS} -mwin32")
-    set(VTK_REQUIRED_C_FLAGS "${VTK_REQUIRED_C_FLAGS} -mwin32")
-  endif()
-else()
-  if(CMAKE_ANSI_CFLAGS)
-    set(VTK_REQUIRED_C_FLAGS "${VTK_REQUIRED_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
-  endif()
-  if(CMAKE_SYSTEM MATCHES "OSF1-V")
-     set(VTK_REQUIRED_CXX_FLAGS
-         "${VTK_REQUIRED_CXX_FLAGS} -timplicit_local -no_implicit_include")
-  endif()
-endif()
-
-if(VTK_USE_X)
-  if(CMAKE_X_CFLAGS)
-    set(VTK_REQUIRED_C_FLAGS "${VTK_REQUIRED_C_FLAGS} ${CMAKE_X_CFLAGS}")
-    set(VTK_REQUIRED_CXX_FLAGS "${VTK_REQUIRED_CXX_FLAGS} ${CMAKE_X_CFLAGS}")
-  endif()
-endif()
-
-# Copy library dependencies.
-set(vtkCommonJava_LIB_DEPENDS "${VTK40_vtkCommonJava_LIB_DEPENDS}")
-set(vtkCommonPython_LIB_DEPENDS "${VTK40_vtkCommonPython_LIB_DEPENDS}")
-set(vtkCommonTCL_LIB_DEPENDS "${VTK40_vtkCommonTCL_LIB_DEPENDS}")
-set(vtkCommon_LIB_DEPENDS "${VTK40_vtkCommon_LIB_DEPENDS}")
-set(vtkFilteringJava_LIB_DEPENDS "${VTK40_vtkFilteringJava_LIB_DEPENDS}")
-set(vtkFilteringPython_LIB_DEPENDS "${VTK40_vtkFilteringPython_LIB_DEPENDS}")
-set(vtkFilteringTCL_LIB_DEPENDS "${VTK40_vtkFilteringTCL_LIB_DEPENDS}")
-set(vtkFiltering_LIB_DEPENDS "${VTK40_vtkFiltering_LIB_DEPENDS}")
-set(vtkGraphicsJava_LIB_DEPENDS "${VTK40_vtkGraphicsJava_LIB_DEPENDS}")
-set(vtkGraphicsPython_LIB_DEPENDS "${VTK40_vtkGraphicsPython_LIB_DEPENDS}")
-set(vtkGraphicsTCL_LIB_DEPENDS "${VTK40_vtkGraphicsTCL_LIB_DEPENDS}")
-set(vtkGraphics_LIB_DEPENDS "${VTK40_vtkGraphics_LIB_DEPENDS}")
-set(vtkHybridJava_LIB_DEPENDS "${VTK40_vtkHybridJava_LIB_DEPENDS}")
-set(vtkHybridPython_LIB_DEPENDS "${VTK40_vtkHybridPython_LIB_DEPENDS}")
-set(vtkHybridTCL_LIB_DEPENDS "${VTK40_vtkHybridTCL_LIB_DEPENDS}")
-set(vtkHybrid_LIB_DEPENDS "${VTK40_vtkHybrid_LIB_DEPENDS}")
-set(vtkIOJava_LIB_DEPENDS "${VTK40_vtkIOJava_LIB_DEPENDS}")
-set(vtkIOPython_LIB_DEPENDS "${VTK40_vtkIOPython_LIB_DEPENDS}")
-set(vtkIOTCL_LIB_DEPENDS "${VTK40_vtkIOTCL_LIB_DEPENDS}")
-set(vtkIO_LIB_DEPENDS "${VTK40_vtkIO_LIB_DEPENDS}")
-set(vtkImagingJava_LIB_DEPENDS "${VTK40_vtkImagingJava_LIB_DEPENDS}")
-set(vtkImagingPython_LIB_DEPENDS "${VTK40_vtkImagingPython_LIB_DEPENDS}")
-set(vtkImagingTCL_LIB_DEPENDS "${VTK40_vtkImagingTCL_LIB_DEPENDS}")
-set(vtkImaging_LIB_DEPENDS "${VTK40_vtkImaging_LIB_DEPENDS}")
-set(vtkParallelJava_LIB_DEPENDS "${VTK40_vtkParallelJava_LIB_DEPENDS}")
-set(vtkParallelPython_LIB_DEPENDS "${VTK40_vtkParallelPython_LIB_DEPENDS}")
-set(vtkParallelTCL_LIB_DEPENDS "${VTK40_vtkParallelTCL_LIB_DEPENDS}")
-set(vtkParallel_LIB_DEPENDS "${VTK40_vtkParallel_LIB_DEPENDS}")
-set(vtkPatentedJava_LIB_DEPENDS "${VTK40_vtkPatentedJava_LIB_DEPENDS}")
-set(vtkPatentedPython_LIB_DEPENDS "${VTK40_vtkPatentedPython_LIB_DEPENDS}")
-set(vtkPatentedTCL_LIB_DEPENDS "${VTK40_vtkPatentedTCL_LIB_DEPENDS}")
-set(vtkPatented_LIB_DEPENDS "${VTK40_vtkPatented_LIB_DEPENDS}")
-set(vtkRenderingJava_LIB_DEPENDS "${VTK40_vtkRenderingJava_LIB_DEPENDS}")
-set(vtkRenderingPythonTkWidgets_LIB_DEPENDS "${VTK40_vtkRenderingPythonTkWidgets_LIB_DEPENDS}")
-set(vtkRenderingPython_LIB_DEPENDS "${VTK40_vtkRenderingPython_LIB_DEPENDS}")
-set(vtkRenderingTCL_LIB_DEPENDS "${VTK40_vtkRenderingTCL_LIB_DEPENDS}")
-set(vtkRendering_LIB_DEPENDS "${VTK40_vtkRendering_LIB_DEPENDS}")
-set(vtkjpeg_LIB_DEPENDS "${VTK40_vtkjpeg_LIB_DEPENDS}")
-set(vtkpng_LIB_DEPENDS "${VTK40_vtkpng_LIB_DEPENDS}")
-set(vtkzlib_LIB_DEPENDS "${VTK40_vtkzlib_LIB_DEPENDS}")
-
-# List of VTK configuration variables set above.
-# grep "^[ ]*set(VTK" UseVTKConfig40.cmake |sed 's/[ ]*set(\([^ ]*\) .*/  \1/'
-set(VTK_SETTINGS
-  VTK_BUILD_SHARED
-  VTK_BUILD_VERSION
-  VTK_DEBUG_LEAKS
-  VTK_HAVE_VG500
-  VTK_HAVE_VP1000
-  VTK_INCLUDE_DIRS
-  VTK_KITS
-  VTK_LANGUAGES
-  VTK_LIBRARY_DIRS
-  VTK_MAJOR_VERSION
-  VTK_MANGLE_MESA
-  VTK_MINOR_VERSION
-  VTK_MPIRUN_EXE
-  VTK_MPI_POSTFLAGS
-  VTK_MPI_PREFLAGS
-  VTK_OPENGL_HAS_OSMESA
-  VTK_PARSE_JAVA_EXE
-  VTK_TCL_EXE
-  VTK_TCL_HOME
-  VTK_USE_64BIT_IDS
-  VTK_USE_ANSI_STDLIB
-  VTK_USE_HYBRID
-  VTK_USE_MATROX_IMAGING
-  VTK_USE_MPI
-  VTK_USE_PARALLEL
-  VTK_USE_PATENTED
-  VTK_USE_RENDERING
-  VTK_USE_VIDEO_FOR_WINDOWS
-  VTK_USE_VOLUMEPRO
-  VTK_USE_X
-  VTK_WRAP_JAVA
-  VTK_WRAP_JAVA_EXE
-  VTK_WRAP_PYTHON
-  VTK_WRAP_PYTHON_EXE
-  VTK_WRAP_TCL
-  VTK_WRAP_TCL_EXE
-)
diff --git a/Modules/readme.txt b/Modules/readme.txt
index b40f3d0..1e0c13b 100644
--- a/Modules/readme.txt
+++ b/Modules/readme.txt
@@ -1,4 +1,4 @@
 See the "Find Modules" section of the cmake-developer(7) manual page.
 
 For more information about how to contribute modules to CMake, see this page:
-http://www.cmake.org/Wiki/CMake:Module_Maintainers
+https://cmake.org/Wiki/CMake:Module_Maintainers
diff --git a/README.rst b/README.rst
index e8524f8..5e7a323 100644
--- a/README.rst
+++ b/README.rst
@@ -8,8 +8,8 @@ CMake is a cross-platform, open-source build system generator.
 For full documentation visit the `CMake Home Page`_ and the
 `CMake Documentation Page`_.
 
-.. _`CMake Home Page`: http://www.cmake.org
-.. _`CMake Documentation Page`: http://www.cmake.org/cmake/help/documentation.html
+.. _`CMake Home Page`: https://cmake.org
+.. _`CMake Documentation Page`: https://cmake.org/cmake/help/documentation.html
 
 CMake is maintained and supported by `Kitware`_ and developed in
 collaboration with a productive community of contributors.
@@ -37,7 +37,7 @@ it should not be a major problem to port CMake to this platform.
 Subscribe and post to the `CMake Users List`_ to ask if others have
 had experience with the platform.
 
-.. _`CMake Users List`: http://www.cmake.org/mailman/listinfo/cmake
+.. _`CMake Users List`: https://cmake.org/mailman/listinfo/cmake
 
 Building CMake from Scratch
 ---------------------------
@@ -63,7 +63,7 @@ You need to download and install a binary release of CMake in order to build
 CMake.  You can get these releases from the `CMake Download Page`_ .  Then
 proceed with the instructions below.
 
-.. _`CMake Download Page`: http://www.cmake.org/cmake/resources/software.html
+.. _`CMake Download Page`: https://cmake.org/cmake/resources/software.html
 
 Building CMake with CMake
 -------------------------
@@ -73,7 +73,7 @@ run the installed CMake on the sources of this CMake with your preferred
 options and generators. Then build it and install it.
 For instructions how to do this, see documentation on `Running CMake`_.
 
-.. _`Running CMake`: http://www.cmake.org/cmake/help/runningcmake.html
+.. _`Running CMake`: https://cmake.org/cmake/help/runningcmake.html
 
 Reporting Bugs
 ==============
@@ -82,14 +82,14 @@ If you have found a bug:
 
 1. If you have a patch, please read the `CONTRIBUTING.rst`_ document.
 
-2. Otherwise, please join the the `CMake Users List`_ and ask about
+2. Otherwise, please join the `CMake Users List`_ and ask about
    the expected and observed behaviors to determine if it is really
    a bug.
 
 3. Finally, if the issue is not resolved by the above steps, open
    an entry in the `CMake Issue Tracker`_.
 
-.. _`CMake Issue Tracker`: http://www.cmake.org/Bug
+.. _`CMake Issue Tracker`: https://cmake.org/Bug
 
 Contributing
 ============
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index a7adb51..ae5b03f 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -88,7 +88,7 @@ option(CMAKE_REGENERATE_YACCLEX
   "Regenerate YACC and LEXX files" OFF)
 mark_as_advanced(CMAKE_REGENERATE_YACCLEX)
 if(CMAKE_REGENERATE_YACCLEX)
-  set(parsersLexers cmDependsFortran cmCommandArgument cmExpr)
+  set(parsersLexers cmFortran cmCommandArgument cmExpr)
   find_program(YACC_EXECUTABLE
     NAMES yacc bison
     PATHS /usr/bin
@@ -165,6 +165,8 @@ set(SRCS
   cmCommandArgumentLexer.cxx
   cmCommandArgumentParser.cxx
   cmCommandArgumentParserHelper.cxx
+  cmCommonTargetGenerator.cxx
+  cmCommonTargetGenerator.h
   cmComputeComponentGraph.cxx
   cmComputeComponentGraph.h
   cmComputeLinkDepends.cxx
@@ -191,9 +193,6 @@ set(SRCS
   cmDependsC.h
   cmDependsFortran.cxx
   cmDependsFortran.h
-  cmDependsFortranLexer.cxx
-  cmDependsFortranParser.cxx
-  cmDependsFortranParser.h
   cmDependsJava.cxx
   cmDependsJava.h
   cmDependsJavaLexer.cxx
@@ -241,6 +240,11 @@ set(SRCS
   cmFileLockResult.h
   cmFileTimeComparison.cxx
   cmFileTimeComparison.h
+  cmFortranLexer.cxx
+  cmFortranLexer.h
+  cmFortranParser.cxx
+  cmFortranParser.h
+  cmFortranParserImpl.cxx
   cmGeneratedFileStream.cxx
   cmGeneratorExpressionContext.cxx
   cmGeneratorExpressionContext.h
@@ -260,6 +264,8 @@ set(SRCS
   cmGeneratorExpression.h
   cmGeneratorTarget.cxx
   cmGeneratorTarget.h
+  cmGlobalCommonGenerator.cxx
+  cmGlobalCommonGenerator.h
   cmGlobalGenerator.cxx
   cmGlobalGenerator.h
   cmGlobalGeneratorFactory.h
@@ -281,9 +287,13 @@ set(SRCS
   cmInstallTargetGenerator.cxx
   cmInstallDirectoryGenerator.h
   cmInstallDirectoryGenerator.cxx
+  cmLinkedTree.h
+  cmLinkItem.h
   cmListFileCache.cxx
   cmListFileCache.h
   cmListFileLexer.c
+  cmLocalCommonGenerator.cxx
+  cmLocalCommonGenerator.h
   cmLocalGenerator.cxx
   cmLocalGenerator.h
   cmLocalUnixMakefileGenerator3.cxx
@@ -299,6 +309,8 @@ set(SRCS
   cmMakefileUtilityTargetGenerator.cxx
   cmOSXBundleGenerator.cxx
   cmOSXBundleGenerator.h
+  cmOutputConverter.cxx
+  cmOutputConverter.h
   cmNewLineStyle.h
   cmNewLineStyle.cxx
   cmOrderDirectories.cxx
@@ -315,6 +327,8 @@ set(SRCS
   cmPropertyDefinitionMap.h
   cmPropertyMap.cxx
   cmPropertyMap.h
+  cmQtAutoGeneratorInitializer.cxx
+  cmQtAutoGeneratorInitializer.h
   cmQtAutoGenerators.cxx
   cmQtAutoGenerators.h
   cmRST.cxx
@@ -427,6 +441,7 @@ if (WIN32)
   set(SRCS ${SRCS}
     cmCallVisualStudioMacro.cxx
     cmCallVisualStudioMacro.h
+    bindexplib.cxx
     )
 
   if(NOT UNIX)
@@ -489,6 +504,10 @@ if (WIN32)
       cmGhsMultiGpj.cxx
       cmGhsMultiGpj.h
       )
+
+    # Add a manifest file to executables on Windows to allow for
+    # GetVersion to work properly on Windows 8 and above.
+    set(MANIFEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake.version.manifest)
   endif()
 endif ()
 
@@ -518,7 +537,7 @@ set(SRCS ${SRCS}
 
 if(WIN32 AND NOT CYGWIN)
   set_source_files_properties(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501)
-  add_executable(cmcldeps cmcldeps.cxx)
+  add_executable(cmcldeps cmcldeps.cxx ${MANIFEST_FILE})
   target_link_libraries(cmcldeps CMakeLib)
   install(TARGETS cmcldeps DESTINATION bin)
 endif()
@@ -543,9 +562,10 @@ if(APPLE)
   target_link_libraries(CMakeLib "-framework CoreFoundation")
 endif()
 
-if(CMAKE_BUILD_ON_VISUAL_STUDIO OR MINGW)
-  # We need the rpcrt4 library for at least the VS7-VC10 generators.
-  target_link_libraries(CMakeLib rpcrt4)
+if(WIN32 AND NOT UNIX)
+  # We need the rpcrt4 library on Windows.
+  # We need the crypt32 library on Windows for crypto/cert APIs.
+  target_link_libraries(CMakeLib rpcrt4 crypt32)
 endif()
 
 #
@@ -706,15 +726,15 @@ if(APPLE)
 endif()
 
 # Build CMake executable
-add_executable(cmake cmakemain.cxx cmcmd.cxx cmcmd.h)
+add_executable(cmake cmakemain.cxx cmcmd.cxx cmcmd.h ${MANIFEST_FILE})
 target_link_libraries(cmake CMakeLib)
 
 # Build CTest executable
-add_executable(ctest ctest.cxx)
+add_executable(ctest ctest.cxx ${MANIFEST_FILE})
 target_link_libraries(ctest CTestLib)
 
 # Build CPack executable
-add_executable(cpack CPack/cpack.cxx)
+add_executable(cpack CPack/cpack.cxx ${MANIFEST_FILE})
 target_link_libraries(cpack CPackLib)
 
 # Curses GUI
@@ -731,9 +751,17 @@ endif()
 include (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
 include (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
 
-install(TARGETS cmake ctest cpack DESTINATION bin)
+# Install tools
+
+set(_tools cmake ctest cpack)
+
 if(APPLE)
-  install(TARGETS cmakexbuild DESTINATION bin)
+  list(APPEND _tools cmakexbuild)
 endif()
 
+foreach(_tool ${_tools})
+  CMake_OPTIONAL_COMPONENT(${_tool})
+  install(TARGETS ${_tool} DESTINATION bin ${COMPONENT})
+endforeach()
+
 install(FILES cmCPluginAPI.h DESTINATION ${CMAKE_DATA_DIR}/include)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index a9785ef..0ce1696 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
-set(CMake_VERSION_MINOR 3)
-set(CMake_VERSION_PATCH 2)
+set(CMake_VERSION_MINOR 4)
+set(CMake_VERSION_PATCH 0)
 #set(CMake_VERSION_RC 0)
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 09e123c..43d34ee 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -191,7 +191,7 @@ int cmCPackIFWGenerator::PackageFiles()
       }
     }
   // TODO: set correct name for multipackages
-  if (this->packageFileNames.size() > 0)
+  if (!this->packageFileNames.empty())
     {
     ifwCmd += " " + packageFileNames[0];
     }
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index 1d7afbd..c271517 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -11,17 +11,18 @@
 ============================================================================*/
 #include <cmsys/SystemTools.hxx>
 #include <cmsys/Process.h>
-#include <cmsys/ios/iostream>
 #include <cmsys/FStream.hxx>
 
+#include <iostream>
+
 #include <CoreFoundation/CoreFoundation.h>
 
 // For the PATH_MAX constant
 #include <sys/syslimits.h>
 
 #define DebugError(x) \
-  ofs << x << cmsys_ios::endl; \
-  cmsys_ios::cout << x << cmsys_ios::endl
+  ofs << x << std::endl; \
+  std::cout << x << std::endl
 
 int main(int argc, char* argv[])
 {
@@ -77,7 +78,7 @@ int main(int argc, char* argv[])
 
   std::string scriptDirectory = cmsys::SystemTools::GetFilenamePath(
     fullScriptPath);
-  ofs << fullScriptPath.c_str() << cmsys_ios::endl;
+  ofs << fullScriptPath.c_str() << std::endl;
   std::vector<const char*> args;
   args.push_back(fullScriptPath.c_str());
   int cc;
@@ -109,7 +110,7 @@ int main(int argc, char* argv[])
         data[i] = ' ';
         }
       }
-    cmsys_ios::cout.write(data, length);
+    std::cout.write(data, length);
     }
 
   cmsysProcess_WaitForExit(cp, 0);
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index b3eb7b2..6f25e50 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -217,7 +217,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
     {
     std::string defaultRef = "WixUI_InstallDir";
 
-    if(this->Components.size())
+    if(!this->Components.empty())
       {
       defaultRef = "WixUI_FeatureTree";
       }
@@ -1005,7 +1005,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
           shortcut.workingDirectoryId = directoryId;
           shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);
 
-          if(desktopExecutables.size() &&
+          if(!desktopExecutables.empty() &&
              std::find(desktopExecutables.begin(),
                        desktopExecutables.end(),
                        executableName)
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index aeec968..fc0d3d3 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -71,7 +71,7 @@ void cmWIXAccessControlList::CreatePermissionElement(
 
   this->SourceWriter.BeginElement("Permission");
   this->SourceWriter.AddAttribute("User", user);
-  if(domain.size())
+  if(!domain.empty())
     {
     this->SourceWriter.AddAttribute("Domain", domain);
     }
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index b5202e0..5a8dc63 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -79,7 +79,7 @@ bool cmWIXPatch::CheckForUnappliedFragments()
     fragmentList += "'";
     }
 
-  if(fragmentList.size())
+  if(!fragmentList.empty())
     {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
         "Some XML patch fragments did not have matching IDs: " <<
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index 219fca8..8d38e9b 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -128,7 +128,7 @@ void cmWIXSourceWriter::AddAttribute(
 void cmWIXSourceWriter::AddAttributeUnlessEmpty(
     std::string const& key, std::string const& value)
 {
-  if(value.size())
+  if(!value.empty())
     {
     AddAttribute(key, value);
     }
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 58bd947..70de757 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -78,7 +78,7 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(cmArchiveWrite& archive,
     std::string rp = filePrefix + *fileIt;
     cmCPackLogger(cmCPackLog::LOG_DEBUG,"Adding file: "
                   << rp << std::endl);
-    archive.Add(rp);
+    archive.Add(rp, 0, 0, false);
     if (!archive)
       {
       cmCPackLogger(cmCPackLog::LOG_ERROR, "ERROR while packaging files: "
@@ -284,7 +284,7 @@ int cmCPackArchiveGenerator::PackageFiles()
     // Get the relative path to the file
     std::string rp = cmSystemTools::RelativePath(toplevel.c_str(),
                                                  fileIt->c_str());
-    archive.Add(rp);
+    archive.Add(rp, 0, 0, false);
     if(!archive)
       {
       cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem while adding file< "
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 5049a3f..04efb71 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -15,6 +15,7 @@
 #include "cmMakefile.h"
 #include "cmGeneratedFileStream.h"
 #include "cmCPackLog.h"
+#include "cmArchiveWrite.h"
 
 #include <cmsys/SystemTools.hxx>
 #include <cmsys/Glob.hxx>
@@ -94,6 +95,7 @@ int cmCPackDebGenerator::PackageOnePack(std::string initialTopLevel,
   std::string findExpr(this->GetOption("GEN_WDIR"));
   findExpr += "/*";
   gl.RecurseOn();
+  gl.SetRecurseListDirs(true);
   if ( !gl.FindFiles(findExpr) )
     {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -221,6 +223,7 @@ int cmCPackDebGenerator::PackageComponentsAllInOne()
   std::string findExpr(this->GetOption("GEN_WDIR"));
   findExpr += "/*";
   gl.RecurseOn();
+  gl.SetRecurseListDirs(true);
   if ( !gl.FindFiles(findExpr) )
     {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -388,9 +391,9 @@ int cmCPackDebGenerator::createDeb()
     {
       std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
       dirName += '/';
-        for (std::vector<std::string>::const_iterator fileIt =
-              packageFiles.begin();
-              fileIt != packageFiles.end(); ++ fileIt )
+      for (std::vector<std::string>::const_iterator fileIt =
+           packageFiles.begin();
+           fileIt != packageFiles.end(); ++ fileIt )
         {
         totalSize += cmSystemTools::FileLength(*fileIt);
         }
@@ -401,8 +404,9 @@ int cmCPackDebGenerator::createDeb()
     out << std::endl;
     }
 
-  std::string cmd(this->GetOption("GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE"));
+  const std::string strGenWDIR(this->GetOption("GEN_WDIR"));
 
+  cmArchiveWrite::Compress tar_compression_type = cmArchiveWrite::CompressGZip;
   const char* debian_compression_type =
       this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE");
   if(!debian_compression_type)
@@ -410,108 +414,136 @@ int cmCPackDebGenerator::createDeb()
     debian_compression_type = "gzip";
     }
 
-  std::string cmake_tar = " ", compression_modifier = "a", compression_suffix;
+  std::string compression_suffix;
   if(!strcmp(debian_compression_type, "lzma")) {
       compression_suffix = ".lzma";
+      tar_compression_type = cmArchiveWrite::CompressLZMA;
   } else if(!strcmp(debian_compression_type, "xz")) {
       compression_suffix = ".xz";
+      tar_compression_type = cmArchiveWrite::CompressXZ;
   } else if(!strcmp(debian_compression_type, "bzip2")) {
       compression_suffix = ".bz2";
-      compression_modifier = "j";
-      cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
+      tar_compression_type = cmArchiveWrite::CompressBZip2;
   } else if(!strcmp(debian_compression_type, "gzip")) {
       compression_suffix = ".gz";
-      compression_modifier = "z";
-      cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
+      tar_compression_type = cmArchiveWrite::CompressGZip;
   } else if(!strcmp(debian_compression_type, "none")) {
       compression_suffix = "";
-      compression_modifier = "";
-      cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
+      tar_compression_type = cmArchiveWrite::CompressNone;
   } else {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
                     "Error unrecognized compression type: "
                     << debian_compression_type << std::endl);
   }
 
-  cmd += cmake_tar + "tar c" + compression_modifier + "f data.tar"
-      + compression_suffix;
 
-  // now add all directories which have to be compressed
-  // collect all top level install dirs for that
-  // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would give /usr and /opt
-    size_t topLevelLength = std::string(this->GetOption("GEN_WDIR")).length();
-    cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \""
-          << this->GetOption("GEN_WDIR")
-          << "\", length = " << topLevelLength
+  std::string filename_data_tar = strGenWDIR
+      + "/data.tar" + compression_suffix;
+
+  // atomic file generation for data.tar
+  {
+    cmGeneratedFileStream fileStream_data_tar;
+    fileStream_data_tar.Open(filename_data_tar.c_str(), false, true);
+    if(!fileStream_data_tar)
+      {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+          "Error opening the file \"" << filename_data_tar << "\" for writing"
           << std::endl);
-  std::set<std::string> installDirs;
+      return 0;
+      }
+    cmArchiveWrite data_tar(fileStream_data_tar, tar_compression_type, "paxr");
+
+    // uid/gid should be the one of the root user, and this root user has
+    // always uid/gid equal to 0.
+    data_tar.SetUIDAndGID(0u, 0u);
+    data_tar.SetUNAMEAndGNAME("root", "root");
+
+    // now add all directories which have to be compressed
+    // collect all top level install dirs for that
+    // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would
+    // give /usr and /opt
+    size_t topLevelLength = strGenWDIR.length();
+    cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \""
+            << strGenWDIR
+            << "\", length = " << topLevelLength
+            << std::endl);
+    std::set<std::string> orderedFiles;
+
+    // we have to reconstruct the parent folders as well
+
     for (std::vector<std::string>::const_iterator fileIt =
-        packageFiles.begin();
-        fileIt != packageFiles.end(); ++ fileIt )
-    {
-      cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
-          << std::endl);
-    std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
-    std::string relativeDir = fileIt->substr(topLevelLength,
-                                             slashPos - topLevelLength);
-      cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
-      << "\"" << std::endl);
-    if (installDirs.find(relativeDir) == installDirs.end())
+         packageFiles.begin();
+         fileIt != packageFiles.end(); ++ fileIt )
       {
-      installDirs.insert(relativeDir);
-      cmd += " .";
-      cmd += relativeDir;
+      std::string currentPath = *fileIt;
+      while(currentPath != strGenWDIR)
+        {
+        // the last one IS strGenWDIR, but we do not want this one:
+        // XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application
+        // should not add XXX/application
+        orderedFiles.insert(currentPath);
+        currentPath = cmSystemTools::CollapseCombinedPath(currentPath, "..");
+        }
       }
-    }
 
-  std::string output;
-    int retval = -1;
-  int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
-      &retval, this->GetOption("GEN_WDIR"), this->GeneratorVerbose, 0);
 
-    if ( !res || retval )
-    {
-    std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
-    tmpFile += "/Deb.log";
-    cmGeneratedFileStream ofs(tmpFile.c_str());
-    ofs << "# Run command: " << cmd << std::endl
-      << "# Working directory: " << toplevel << std::endl
-      << "# Output:" << std::endl
-      << output << std::endl;
-    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: "
-      << cmd << std::endl
-      << "Please check " << tmpFile << " for errors" << std::endl);
-    return 0;
-    }
+    for (std::set<std::string>::const_iterator fileIt =
+         orderedFiles.begin();
+         fileIt != orderedFiles.end(); ++ fileIt )
+      {
+      cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
+                    << std::endl);
+      std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
+      std::string relativeDir = fileIt->substr(topLevelLength,
+                                               slashPos - topLevelLength);
+      cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
+                    << "\"" << std::endl);
+
+      // do not recurse because the loop will do it
+      if(!data_tar.Add(*fileIt, topLevelLength, ".", false))
+        {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "Problem adding file to tar:" << std::endl
+                      << "#top level directory: "
+                      << strGenWDIR << std::endl
+                      << "#file: " << *fileIt << std::endl
+                      << "#error:" << data_tar.GetError() << std::endl);
+        return 0;
+        }
+      }
+  } // scope for file generation
 
-  std::string md5filename;
-    md5filename = this->GetOption("GEN_WDIR");
-  md5filename += "/md5sums";
 
-    { // the scope is needed for cmGeneratedFileStream
+  std::string md5filename = strGenWDIR + "/md5sums";
+  {
+    // the scope is needed for cmGeneratedFileStream
     cmGeneratedFileStream out(md5filename.c_str());
-    std::vector<std::string>::const_iterator fileIt;
-//       std::string topLevelWithTrailingSlash = toplevel;
+
     std::string topLevelWithTrailingSlash =
         this->GetOption("CPACK_TEMPORARY_DIRECTORY");
     topLevelWithTrailingSlash += '/';
-      for ( fileIt = packageFiles.begin();
-            fileIt != packageFiles.end(); ++ fileIt )
+    for (std::vector<std::string>::const_iterator fileIt =
+           packageFiles.begin();
+         fileIt != packageFiles.end(); ++ fileIt )
       {
-      cmd = "\"";
-      cmd += cmSystemTools::GetCMakeCommand();
-      cmd += "\" -E md5sum \"";
-      cmd += *fileIt;
-      cmd += "\"";
-      //std::string output;
-      //int retVal = -1;
-      res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
-          &retval, toplevel.c_str(), this->GeneratorVerbose, 0);
-      if ( !res || retval )
+      // hash only regular files
+      if(   cmSystemTools::FileIsDirectory(*fileIt)
+         || cmSystemTools::FileIsSymlink(*fileIt))
+        {
+        continue;
+        }
+
+      char md5sum[33];
+      if(!cmSystemTools::ComputeFileMD5(*fileIt, md5sum))
         {
-        cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running cmake -E md5sum "
-                      << cmd << std::endl);
+        cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem computing the md5 of "
+                      << *fileIt << std::endl);
         }
+
+      md5sum[32] = 0;
+
+      std::string output(md5sum);
+      output += "  " + *fileIt + "\n";
       // debian md5sums entries are like this:
       // 014f3604694729f3bf19263bac599765  usr/bin/ccmake
       // thus strip the full path (with the trailing slash)
@@ -521,70 +553,116 @@ int cmCPackDebGenerator::createDeb()
       }
     // each line contains a eol.
     // Do not end the md5sum file with yet another (invalid)
-    }
+  }
 
-    // set md5sum file permissins to RW-R--R-- so that deb lintian doesn't warn
-    // about it
-    cmSystemTools::SetPermissions(md5filename.c_str(),
-        S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
-    cmd = this->GetOption("GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE");
-    cmd += cmake_tar + "tar czf control.tar.gz ./control ./md5sums";
+
+  std::string filename_control_tar = strGenWDIR + "/control.tar.gz";
+  // atomic file generation for control.tar
+  {
+    cmGeneratedFileStream fileStream_control_tar;
+    fileStream_control_tar.Open(filename_control_tar.c_str(), false, true);
+    if(!fileStream_control_tar)
+      {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+          "Error opening the file \"" << filename_control_tar
+          << "\" for writing" << std::endl);
+      return 0;
+      }
+    cmArchiveWrite control_tar(fileStream_control_tar,
+                               cmArchiveWrite::CompressGZip,
+                               "paxr");
+
+    // sets permissions and uid/gid for the files
+    control_tar.SetUIDAndGID(0u, 0u);
+    control_tar.SetUNAMEAndGNAME("root", "root");
+
+    /* permissions are set according to
+    https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
+    and
+    https://lintian.debian.org/tags/control-file-has-bad-permissions.html
+    */
+    const mode_t permission644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+    const mode_t permissionExecute = S_IXUSR | S_IXGRP | S_IXOTH;
+    const mode_t permission755 = permission644 | permissionExecute;
+
+    // for md5sum and control (that we have generated here), we use 644
+    // (RW-R--R--)
+    // so that deb lintian doesn't warn about it
+    control_tar.SetPermissions(permission644);
+
+    // adds control and md5sums
+    if(   !control_tar.Add(md5filename, strGenWDIR.length(), ".")
+       || !control_tar.Add(strGenWDIR + "/control", strGenWDIR.length(), "."))
+      {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+            "Error adding file to tar:" << std::endl
+            << "#top level directory: "
+               << strGenWDIR << std::endl
+            << "#file: \"control\" or \"md5sums\"" << std::endl
+            << "#error:" << control_tar.GetError() << std::endl);
+        return 0;
+      }
+
+    // for the other files, we use
+    // -either the original permission on the files
+    // -either a permission strictly defined by the Debian policies
     const char* controlExtra =
       this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA");
-  if( controlExtra )
-    {
-    std::vector<std::string> controlExtraList;
-    cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
-    for(std::vector<std::string>::iterator i =
-          controlExtraList.begin(); i != controlExtraList.end(); ++i)
+    if( controlExtra )
       {
-      std::string filenamename =
-        cmsys::SystemTools::GetFilenameName(*i);
-      std::string localcopy = this->GetOption("GEN_WDIR");
-      localcopy += "/";
-      localcopy += filenamename;
-      // if we can copy the file, it means it does exist, let's add it:
-      if( cmsys::SystemTools::CopyFileIfDifferent(
-            *i, localcopy) )
+      // permissions are now controlled by the original file permissions
+
+      const bool permissionStrictPolicy =
+        this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION");
+
+      static const char* strictFiles[] = {
+        "config", "postinst", "postrm", "preinst", "prerm"
+        };
+      std::set<std::string> setStrictFiles(
+        strictFiles,
+        strictFiles + sizeof(strictFiles)/sizeof(strictFiles[0]));
+
+      // default
+      control_tar.ClearPermissions();
+
+      std::vector<std::string> controlExtraList;
+      cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
+      for(std::vector<std::string>::iterator i = controlExtraList.begin();
+          i != controlExtraList.end(); ++i)
         {
-        // debian is picky and need relative to ./ path in the tar.*
-        cmd += " ./";
-        cmd += filenamename;
+        std::string filenamename =
+          cmsys::SystemTools::GetFilenameName(*i);
+        std::string localcopy = strGenWDIR + "/" + filenamename;
+
+        if(permissionStrictPolicy)
+          {
+          control_tar.SetPermissions(setStrictFiles.count(filenamename) ?
+            permission755 : permission644);
+          }
+
+        // if we can copy the file, it means it does exist, let's add it:
+        if( cmsys::SystemTools::CopyFileIfDifferent(*i, localcopy) )
+          {
+          control_tar.Add(localcopy, strGenWDIR.length(), ".");
+          }
         }
       }
-    }
-  res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
-      &retval, this->GetOption("GEN_WDIR"), this->GeneratorVerbose, 0);
+  }
 
-    if ( !res || retval )
-    {
-    std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
-    tmpFile += "/Deb.log";
-    cmGeneratedFileStream ofs(tmpFile.c_str());
-    ofs << "# Run command: " << cmd << std::endl
-      << "# Working directory: " << toplevel << std::endl
-      << "# Output:" << std::endl
-      << output << std::endl;
-    cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: "
-      << cmd << std::endl
-      << "Please check " << tmpFile << " for errors" << std::endl);
-    return 0;
-    }
 
   // ar -r your-package-name.deb debian-binary control.tar.* data.tar.*
   // since debian packages require BSD ar (most Linux distros and even
   // FreeBSD and NetBSD ship GNU ar) we use a copy of OpenBSD ar here.
   std::vector<std::string> arFiles;
-    std::string topLevelString = this->GetOption("GEN_WDIR");
-  topLevelString += "/";
+  std::string topLevelString = strGenWDIR + "/";
   arFiles.push_back(topLevelString + "debian-binary");
   arFiles.push_back(topLevelString + "control.tar.gz");
   arFiles.push_back(topLevelString + "data.tar" + compression_suffix);
-    std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
-    outputFileName += "/";
-    outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME");
-    res = ar_append(outputFileName.c_str(), arFiles);
+  std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+  outputFileName += "/";
+  outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME");
+  int res = ar_append(outputFileName.c_str(), arFiles);
   if ( res!=0 )
     {
     std::string tmpFile = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME");
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index bf4df60..def9fc7 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -367,6 +367,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
       cmCPackLogger(cmCPackLog::LOG_OUTPUT,
         "- Install directory: " << top << std::endl);
       gl.RecurseOn();
+      gl.SetRecurseListDirs(true);
       if ( !gl.FindFiles(findExpr) )
         {
         cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -379,7 +380,11 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
       for ( gfit = files.begin(); gfit != files.end(); ++ gfit )
         {
         bool skip = false;
-        std::string &inFile = *gfit;
+        std::string inFile = *gfit;
+        if(cmSystemTools::FileIsDirectory(*gfit))
+          {
+          inFile += '/';
+          }
         for ( regIt= ignoreFilesRegex.begin();
           regIt!= ignoreFilesRegex.end();
           ++ regIt)
@@ -716,8 +721,10 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
         cm.AddCMakePaths();
         cm.SetProgressCallback(cmCPackGeneratorProgress, this);
         cmGlobalGenerator gg(&cm);
-        cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
-        cmMakefile *mf = lg->GetMakefile();
+        cmsys::auto_ptr<cmMakefile> mf(
+              new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+        cmsys::auto_ptr<cmLocalGenerator> lg(
+              gg.CreateLocalGenerator(mf.get()));
         std::string realInstallDirectory = tempInstallDirectory;
         if ( !installSubDirectory.empty() && installSubDirectory != "/" )
           {
@@ -867,6 +874,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
           cmsys::Glob glB;
           findExpr += "/*";
           glB.RecurseOn();
+          glB.SetRecurseListDirs(true);
           glB.FindFiles(findExpr);
           filesBefore = glB.GetFiles();
           std::sort(filesBefore.begin(),filesBefore.end());
@@ -906,6 +914,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
           {
           cmsys::Glob glA;
           glA.RecurseOn();
+          glA.SetRecurseListDirs(true);
           glA.FindFiles(findExpr);
           std::vector<std::string> filesAfter = glA.GetFiles();
           std::sort(filesAfter.begin(),filesAfter.end());
@@ -1072,6 +1081,7 @@ int cmCPackGenerator::DoPackage()
   std::string findExpr = tempDirectory;
   findExpr += "/*";
   gl.RecurseOn();
+  gl.SetRecurseListDirs(true);
   gl.SetRecurseThroughSymlinks(false);
   if ( !gl.FindFiles(findExpr) )
     {
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 2de2bc4..6cdda28 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -49,7 +49,7 @@ int cmCPackNSISGenerator::PackageFiles()
   // TODO: Fix nsis to force out file name
 
   std::string nsisInFileName = this->FindTemplate("NSIS.template.in");
-  if ( nsisInFileName.size() == 0 )
+  if (nsisInFileName.empty())
     {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
       "CPack error: Could not find NSIS installer template file."
@@ -58,7 +58,7 @@ int cmCPackNSISGenerator::PackageFiles()
     }
   std::string nsisInInstallOptions
     = this->FindTemplate("NSIS.InstallOptions.ini.in");
-  if ( nsisInInstallOptions.size() == 0 )
+  if (nsisInInstallOptions.empty())
     {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
       "CPack error: Could not find NSIS installer options file."
@@ -536,7 +536,7 @@ int cmCPackNSISGenerator::InitializeInternal()
         << ".lnk\"" << std::endl;
       // see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
       // if so add a desktop link
-      if(cpackPackageDesktopLinksVector.size() &&
+      if(!cpackPackageDesktopLinksVector.empty() &&
          std::find(cpackPackageDesktopLinksVector.begin(),
                    cpackPackageDesktopLinksVector.end(),
                    execName)
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index e5da5cf..109dcb7 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -19,7 +19,6 @@
 #include "cmMakefile.h"
 #include "cmCPackLog.h"
 
-#include <cmsys/ios/sstream>
 #include <cmsys/FStream.hxx>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -85,7 +84,7 @@ int cmCPackSTGZGenerator::PackageFiles()
 int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os)
 {
   cmCPackLogger(cmCPackLog::LOG_DEBUG, "Writing header" << std::endl);
-  cmsys_ios::ostringstream str;
+  std::ostringstream str;
   int counter = 0;
 
   std::string inLicFile = this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index c2fe763..cb9cbc4 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -202,8 +202,10 @@ int main (int argc, char const* const* argv)
   cminst.SetHomeOutputDirectory("");
   cminst.GetState()->RemoveUnscriptableCommands();
   cmGlobalGenerator cmgg(&cminst);
-  cmsys::auto_ptr<cmLocalGenerator> cmlg(cmgg.MakeLocalGenerator());
-  cmMakefile* globalMF = cmlg->GetMakefile();
+  cmsys::auto_ptr<cmMakefile> globalMF(
+        new cmMakefile(&cmgg, cminst.GetCurrentSnapshot()));
+  cmsys::auto_ptr<cmLocalGenerator> cmlg(
+        cmgg.CreateLocalGenerator(globalMF.get()));
 #if defined(__CYGWIN__)
   globalMF->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0");
 #endif
@@ -357,8 +359,8 @@ int main (int argc, char const* const* argv)
         ++it )
         {
         const char* gen = it->c_str();
-        cmMakefile::ScopePushPop raii(globalMF);
-        cmMakefile* mf = globalMF;
+        cmMakefile::ScopePushPop raii(globalMF.get());
+        cmMakefile* mf = globalMF.get();
         cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
           "Specified generator: " << gen << std::endl);
         if ( parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME") )
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index e141b60..6dbb245 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -920,7 +920,7 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
 
   char* data;
   int length;
-  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+  cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT,
     "   Each symbol represents " << tick_len << " bytes of output."
     << std::endl
     << (this->UseCTestLaunch? "" :
@@ -968,7 +968,7 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
   this->ProcessBuffer(0, 0, tick, tick_len, ofs, &this->BuildProcessingQueue);
   this->ProcessBuffer(0, 0, tick, tick_len, ofs,
     &this->BuildProcessingErrorQueue);
-  cmCTestOptionalLog(this->CTest, OUTPUT, " Size of output: "
+  cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, " Size of output: "
     << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl,
     this->Quiet);
 
@@ -1175,12 +1175,12 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length,
   while ( this->BuildOutputLogSize > (tick * tick_len) )
     {
     tick ++;
-    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->LastTickChar,
-      this->Quiet);
+    cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT,
+      this->LastTickChar, this->Quiet);
     tickDisplayed = true;
     if ( tick % tick_line_len == 0 && tick > 0 )
       {
-      cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "  Size: "
+      cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, "  Size: "
         << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl
         << "    ", this->Quiet);
       }
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index f92f19a..20807c8 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -27,8 +27,6 @@
 #include <cmsys/Process.h>
 #include <cmsys/RegularExpression.hxx>
 #include <cmsys/Glob.hxx>
-#include <cmsys/stl/iterator>
-#include <cmsys/stl/algorithm>
 #include <cmsys/FStream.hxx>
 
 #include <stdlib.h>
@@ -446,7 +444,7 @@ int cmCTestCoverageHandler::ProcessHandler()
     }
   std::set<std::string> uncovered = this->FindUncoveredFiles(&cont);
 
-  if ( file_count == 0 )
+  if (file_count == 0 && this->ExtraCoverageGlobs.empty())
     {
     cmCTestOptionalLog(this->CTest, WARNING,
       " Cannot find any coverage files. Ignoring Coverage request."
@@ -1474,7 +1472,12 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
     << std::endl, this->Quiet);
 
   std::vector<std::string> files;
-  this->FindLCovFiles(files);
+  if (!this->FindLCovFiles(files))
+    {
+    cmCTestLog(this->CTest, ERROR_MESSAGE,
+               "Error while finding LCov files.\n");
+    return 0;
+    }
   std::vector<std::string>::iterator it;
 
   if (files.empty())
@@ -1745,18 +1748,28 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
 }
 
 //----------------------------------------------------------------------------
-void cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
+bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
 {
   cmsys::Glob gl;
   gl.RecurseOff(); // No need of recurse if -prof_dir${BUILD_DIR} flag is
                    // used while compiling.
   gl.RecurseThroughSymlinksOff();
   std::string prevBinaryDir;
-  cmSystemTools::ChangeDirectory(
-    this->CTest->GetCTestConfiguration("BuildDirectory"));
+  std::string buildDir = this->CTest->GetCTestConfiguration("BuildDirectory");
+  if (cmSystemTools::ChangeDirectory(buildDir))
+    {
+    cmCTestLog(this->CTest, ERROR_MESSAGE,
+               "Error changing directory to " << buildDir << std::endl);
+    return false;
+    }
 
   // Run profmerge to merge all *.dyn files into dpi files
-  cmSystemTools::RunSingleCommand("profmerge");
+  if (!cmSystemTools::RunSingleCommand("profmerge"))
+    {
+    cmCTestLog(this->CTest, ERROR_MESSAGE,
+               "Error while running profmerge.\n");
+    return false;
+    }
 
   prevBinaryDir = cmSystemTools::GetCurrentWorkingDirectory().c_str();
 
@@ -1766,10 +1779,16 @@ void cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
   daGlob += "/*.dpi";
   cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
     "   looking for dpi files in: " << daGlob << std::endl, this->Quiet);
-  gl.FindFiles(daGlob);
+  if (!gl.FindFiles(daGlob))
+    {
+    cmCTestLog(this->CTest, ERROR_MESSAGE,
+               "Error while finding files matching " << daGlob << std::endl);
+    return false;
+    }
   files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
   cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
     "Now searching in: " << daGlob << std::endl, this->Quiet);
+  return true;
 }
 
 //----------------------------------------------------------------------
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 2ca123a..7102d1e 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -75,7 +75,7 @@ private:
 
   //! Handle coverage using Intel's LCov
   int HandleLCovCoverage(cmCTestCoverageHandlerContainer* cont);
-  void FindLCovFiles(std::vector<std::string>& files);
+  bool FindLCovFiles(std::vector<std::string>& files);
 
   //! Handle coverage using xdebug php coverage
   int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont);
diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx
index b4c0137..fb6cc00 100644
--- a/Source/CTest/cmCTestCurl.cxx
+++ b/Source/CTest/cmCTestCurl.cxx
@@ -166,6 +166,10 @@ bool cmCTestCurl::UploadFile(std::string const& local_file,
                      curlWriteMemoryCallback);
   ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGFUNCTION,
                      curlDebugCallback);
+  // Be sure to set Content-Type to satisfy fussy modsecurity rules
+  struct curl_slist *headers = ::curl_slist_append(NULL,
+                                                   "Content-Type: text/xml");
+  ::curl_easy_setopt(this->Curl, CURLOPT_HTTPHEADER, headers);
   std::vector<char> responseData;
   std::vector<char> debugData;
   ::curl_easy_setopt(this->Curl, CURLOPT_FILE, (void *)&responseData);
@@ -174,6 +178,8 @@ bool cmCTestCurl::UploadFile(std::string const& local_file,
   // Now run off and do what you've been told!
   ::curl_easy_perform(this->Curl);
   ::fclose(ftpfile);
+  ::curl_easy_setopt(this->Curl, CURLOPT_HTTPHEADER, NULL);
+  ::curl_slist_free_all(headers);
 
   if ( responseData.size() > 0 )
     {
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index c32e876..bbb3b9d 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -16,7 +16,6 @@
 #include "cmAlgorithms.h"
 
 #include <cmsys/RegularExpression.hxx>
-#include <cmsys/ios/sstream>
 #include <cmsys/Process.h>
 #include <cmsys/FStream.hxx>
 
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
index 81eb0a8..ad79ba2 100644
--- a/Source/CTest/cmCTestGenericHandler.cxx
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -23,6 +23,7 @@ cmCTestGenericHandler::cmCTestGenericHandler()
   this->SubmitIndex = 0;
   this->AppendXML = false;
   this->Quiet = false;
+  this->TestLoad = 0;
 }
 
 //----------------------------------------------------------------------
@@ -70,6 +71,7 @@ void cmCTestGenericHandler::SetPersistentOption(const std::string& op,
 void cmCTestGenericHandler::Initialize()
 {
   this->AppendXML = false;
+  this->TestLoad = 0;
   this->Options.clear();
   t_StringToString::iterator it;
   for ( it = this->PersistentOptions.begin();
diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h
index 8567dd7..4b7ae79 100644
--- a/Source/CTest/cmCTestGenericHandler.h
+++ b/Source/CTest/cmCTestGenericHandler.h
@@ -89,6 +89,8 @@ public:
   void SetAppendXML(bool b) { this->AppendXML = b; }
   void SetQuiet(bool b) { this->Quiet = b; }
   bool GetQuiet() { return this->Quiet; }
+  void SetTestLoad(unsigned long load) { this->TestLoad = load; }
+  unsigned long GetTestLoad() const { return this->TestLoad;  }
 
 protected:
   bool StartResultingXML(cmCTest::Part part,
@@ -97,6 +99,7 @@ protected:
 
   bool AppendXML;
   bool Quiet;
+  unsigned long TestLoad;
   cmSystemTools::OutputOption HandlerVerbose;
   cmCTest *CTest;
   t_StringToString Options;
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index 3003e8a..3579aee 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -109,6 +109,12 @@ bool cmCTestHandlerCommand
       this->Quiet);
     }
 
+  if(const char* changeId =
+     this->Makefile->GetDefinition("CTEST_CHANGE_ID"))
+    {
+    this->CTest->SetCTestConfiguration("ChangeId", changeId, this->Quiet);
+    }
+
   cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
   cmCTestGenericHandler* handler = this->InitializeHandler();
   if ( !handler )
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 0f588c5..fb0cce6 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -738,8 +738,9 @@ void cmCTestLaunch::LoadConfig()
   cm.SetHomeDirectory("");
   cm.SetHomeOutputDirectory("");
   cmGlobalGenerator gg(&cm);
-  cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
-  cmMakefile* mf = lg->GetMakefile();
+  cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+  cmsys::auto_ptr<cmLocalGenerator> lg(
+        gg.CreateLocalGenerator(mf.get()));
   std::string fname = this->LogDir;
   fname += "CTestLaunchConfig.cmake";
   if(cmSystemTools::FileExists(fname.c_str()) &&
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index bd090db..7c7f5df 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -13,12 +13,15 @@
 #include "cmProcess.h"
 #include "cmStandardIncludes.h"
 #include "cmCTest.h"
+#include "cmCTestScriptHandler.h"
 #include "cmSystemTools.h"
 #include <stdlib.h>
 #include <stack>
 #include <list>
 #include <float.h>
+#include <math.h>
 #include <cmsys/FStream.hxx>
+#include <cmsys/SystemInformation.hxx>
 
 class TestComparator
 {
@@ -40,10 +43,12 @@ private:
 cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
 {
   this->ParallelLevel = 1;
+  this->TestLoad = 0;
   this->Completed = 0;
   this->RunningCount = 0;
   this->StopTimePassed = false;
   this->HasCycles = false;
+  this->SerialTestRunning = false;
 }
 
 cmCTestMultiProcessHandler::~cmCTestMultiProcessHandler()
@@ -83,6 +88,11 @@ void cmCTestMultiProcessHandler::SetParallelLevel(size_t level)
   this->ParallelLevel = level < 1 ? 1 : level;
 }
 
+void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load)
+{
+  this->TestLoad = load;
+}
+
 //---------------------------------------------------------
 void cmCTestMultiProcessHandler::RunTests()
 {
@@ -172,6 +182,11 @@ void cmCTestMultiProcessHandler::LockResources(int index)
   this->LockedResources.insert(
       this->Properties[index]->LockedResources.begin(),
       this->Properties[index]->LockedResources.end());
+
+  if (this->Properties[index]->RunSerial)
+    {
+    this->SerialTestRunning = true;
+    }
 }
 
 //---------------------------------------------------------
@@ -183,6 +198,10 @@ void cmCTestMultiProcessHandler::UnlockResources(int index)
     {
     this->LockedResources.erase(*i);
     }
+  if (this->Properties[index]->RunSerial)
+    {
+    this->SerialTestRunning = false;
+    }
 }
 
 //---------------------------------------------------------
@@ -198,17 +217,20 @@ inline size_t cmCTestMultiProcessHandler::GetProcessorsUsed(int test)
 {
   size_t processors =
     static_cast<int>(this->Properties[test]->Processors);
-  //If this is set to run serially, it must run alone.
-  //Also, if processors setting is set higher than the -j
+  //If processors setting is set higher than the -j
   //setting, we default to using all of the process slots.
-  if(this->Properties[test]->RunSerial
-     || processors > this->ParallelLevel)
+  if (processors > this->ParallelLevel)
     {
     processors = this->ParallelLevel;
     }
   return processors;
 }
 
+std::string cmCTestMultiProcessHandler::GetName(int test)
+{
+  return this->Properties[test]->Name;
+}
+
 //---------------------------------------------------------
 bool cmCTestMultiProcessHandler::StartTest(int test)
 {
@@ -248,22 +270,136 @@ void cmCTestMultiProcessHandler::StartNextTests()
     return;
     }
 
+  // Don't start any new tests if one with the RUN_SERIAL property
+  // is already running.
+  if (this->SerialTestRunning)
+    {
+    return;
+    }
+
+  bool allTestsFailedTestLoadCheck = false;
+  bool usedFakeLoadForTesting = false;
+  size_t minProcessorsRequired = this->ParallelLevel;
+  std::string testWithMinProcessors = "";
+
+  cmsys::SystemInformation info;
+
+  unsigned long systemLoad = 0;
+  size_t spareLoad = 0;
+  if (this->TestLoad > 0)
+    {
+    // Activate possible wait.
+    allTestsFailedTestLoadCheck = true;
+
+    // Check for a fake load average value used in testing.
+    if (const char* fake_load_value =
+        cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING"))
+      {
+      usedFakeLoadForTesting = true;
+      if (!cmSystemTools::StringToULong(fake_load_value, &systemLoad))
+        {
+        cmSystemTools::Error("Failed to parse fake load value: ",
+                             fake_load_value);
+        }
+      }
+    // If it's not set, look up the true load average.
+    else
+      {
+      systemLoad = static_cast<unsigned long>(ceil(info.GetLoadAverage()));
+      }
+    spareLoad = (this->TestLoad > systemLoad ?
+                 this->TestLoad - systemLoad : 0);
+
+    // Don't start more tests than the spare load can support.
+    if (numToStart > spareLoad)
+      {
+      numToStart = spareLoad;
+      }
+    }
+
   TestList copy = this->SortedTests;
   for(TestList::iterator test = copy.begin(); test != copy.end(); ++test)
     {
+    // Take a nap if we're currently performing a RUN_SERIAL test.
+    if (this->SerialTestRunning)
+      {
+      break;
+      }
+    // We can only start a RUN_SERIAL test if no other tests are also running.
+    if (this->Properties[*test]->RunSerial && this->RunningCount > 0)
+      {
+      continue;
+      }
+
     size_t processors = GetProcessorsUsed(*test);
+    bool testLoadOk = true;
+    if (this->TestLoad > 0)
+      {
+      if (processors <= spareLoad)
+        {
+        cmCTestLog(this->CTest, DEBUG,
+                    "OK to run " << GetName(*test) <<
+                    ", it requires " << processors <<
+                    " procs & system load is: " <<
+                    systemLoad << std::endl);
+        allTestsFailedTestLoadCheck = false;
+        }
+      else
+        {
+        testLoadOk = false;
+        }
+      }
 
-    if(processors <= numToStart && this->StartTest(*test))
+    if (processors <= minProcessorsRequired)
       {
-        if(this->StopTimePassed)
-          {
-          return;
-          }
-        numToStart -= processors;
+      minProcessorsRequired = processors;
+      testWithMinProcessors = GetName(*test);
+      }
+
+    if(testLoadOk && processors <= numToStart && this->StartTest(*test))
+      {
+      if(this->StopTimePassed)
+        {
+        return;
+        }
+
+      numToStart -= processors;
       }
     else if(numToStart == 0)
       {
-      return;
+      break;
+      }
+    }
+
+  if (allTestsFailedTestLoadCheck)
+    {
+    cmCTestLog(this->CTest, HANDLER_OUTPUT, "***** WAITING, ");
+    if (this->SerialTestRunning)
+      {
+      cmCTestLog(this->CTest, HANDLER_OUTPUT,
+                 "Waiting for RUN_SERIAL test to finish.");
+      }
+    else
+      {
+      cmCTestLog(this->CTest, HANDLER_OUTPUT,
+                 "System Load: " << systemLoad << ", "
+                 "Max Allowed Load: " << this->TestLoad << ", "
+                 "Smallest test " << testWithMinProcessors <<
+                 " requires " << minProcessorsRequired);
+      }
+    cmCTestLog(this->CTest, HANDLER_OUTPUT, "*****" << std::endl);
+
+    if (usedFakeLoadForTesting)
+      {
+      // Break out of the infinite loop of waiting for our fake load
+      // to come down.
+      this->StopTimePassed = true;
+      }
+    else
+      {
+      // Wait between 1 and 5 seconds before trying again.
+      cmCTestScriptHandler::SleepInSeconds(
+        cmSystemTools::RandomSeed() % 5 + 1);
       }
     }
 }
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 6440fbc..ed3e155 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -37,6 +37,7 @@ public:
   void SetTests(TestMap& tests, PropertiesMap& properties);
   // Set the max number of tests that can be run at the same time.
   void SetParallelLevel(size_t);
+  void SetTestLoad(unsigned long load);
   virtual void RunTests();
   void PrintTestList();
   void PrintLabels();
@@ -93,6 +94,7 @@ protected:
   bool CheckCycles();
   int FindMaxIndex();
   inline size_t GetProcessorsUsed(int index);
+  std::string GetName(int index);
 
   void LockResources(int index);
   void UnlockResources(int index);
@@ -116,11 +118,13 @@ protected:
   std::set<std::string> LockedResources;
   std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
   size_t ParallelLevel; // max number of process that can be run at once
+  unsigned long TestLoad;
   std::set<cmCTestRunTest*> RunningTests;  // current running tests
   cmCTestTestHandler * TestHandler;
   cmCTest* CTest;
   bool HasCycles;
   bool Quiet;
+  bool SerialTestRunning;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index ad8e8b3..5e0c54a 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -15,7 +15,6 @@
 #include "cmSystemTools.h"
 
 #include <cmsys/RegularExpression.hxx>
-#include <cmsys/ios/sstream>
 #include <cmsys/Process.h>
 
 #include <sys/types.h>
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index d9e4bd4..d108592 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -57,8 +57,7 @@ bool cmCTestRunTest::CheckOutput()
       // Process has terminated and all output read.
       return false;
       }
-    else if(p == cmsysProcess_Pipe_STDOUT ||
-            p == cmsysProcess_Pipe_STDERR)
+    else if(p == cmsysProcess_Pipe_STDOUT)
       {
       // Store this line of output.
       cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 047bd98..c1ba279 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -125,42 +125,25 @@ void cmCTestScriptHandler::Initialize()
   // what time in seconds did this script start running
   this->ScriptStartTime = 0;
 
+  delete this->Makefile;
   this->Makefile = 0;
-  if (this->LocalGenerator)
-    {
-    delete this->LocalGenerator;
-    }
+
+  delete this->LocalGenerator;
   this->LocalGenerator = 0;
-  if (this->GlobalGenerator)
-    {
-    delete this->GlobalGenerator;
-    }
+
+  delete this->GlobalGenerator;
   this->GlobalGenerator = 0;
-  if (this->CMake)
-    {
-    delete this->CMake;
-    }
+
+  delete this->CMake;
 }
 
 //----------------------------------------------------------------------
 cmCTestScriptHandler::~cmCTestScriptHandler()
 {
-  // local generator owns the makefile
-  this->Makefile = 0;
-  if (this->LocalGenerator)
-    {
-    delete this->LocalGenerator;
-    }
-  this->LocalGenerator = 0;
-  if (this->GlobalGenerator)
-    {
-    delete this->GlobalGenerator;
-    }
-  this->GlobalGenerator = 0;
-  if (this->CMake)
-    {
-    delete this->CMake;
-    }
+  delete this->Makefile;
+  delete this->LocalGenerator;
+  delete this->GlobalGenerator;
+  delete this->CMake;
 }
 
 
@@ -334,6 +317,7 @@ void cmCTestScriptHandler::CreateCMake()
     delete this->CMake;
     delete this->GlobalGenerator;
     delete this->LocalGenerator;
+    delete this->Makefile;
     }
   this->CMake = new cmake;
   this->CMake->SetHomeDirectory("");
@@ -341,8 +325,10 @@ void cmCTestScriptHandler::CreateCMake()
   this->CMake->AddCMakePaths();
   this->GlobalGenerator = new cmGlobalGenerator(this->CMake);
 
-  this->LocalGenerator = this->GlobalGenerator->MakeLocalGenerator();
-  this->Makefile = this->LocalGenerator->GetMakefile();
+  cmState::Snapshot snapshot = this->CMake->GetCurrentSnapshot();
+  this->Makefile = new cmMakefile(this->GlobalGenerator, snapshot);
+  this->LocalGenerator =
+      this->GlobalGenerator->CreateLocalGenerator(this->Makefile);
 
   this->CMake->SetProgressCallback(ctestScriptProgressCallback, this->CTest);
 
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 1e12f15..833cad6 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -338,6 +338,8 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
   CURLcode res;
   FILE* ftpfile;
   char error_buffer[1024];
+  struct curl_slist *headers = ::curl_slist_append(NULL,
+                                                   "Content-Type: text/xml");
 
   /* In windows, this will init the winsock stuff */
   ::curl_global_init(CURL_GLOBAL_ALL);
@@ -420,6 +422,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
       ::curl_easy_setopt(curl, CURLOPT_PUT, 1);
       ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
 
+      // Be sure to set Content-Type to satisfy fussy modsecurity rules
+      ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
       std::string local_file = *file;
       if ( !cmSystemTools::FileExists(local_file.c_str()) )
         {
@@ -477,6 +482,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
         cmCTestLog(this->CTest, ERROR_MESSAGE, "   Cannot find file: "
           << local_file << std::endl);
         ::curl_easy_cleanup(curl);
+        ::curl_slist_free_all(headers);
         ::curl_global_cleanup();
         return false;
         }
@@ -621,6 +627,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
                      << std::endl);
           }
         ::curl_easy_cleanup(curl);
+        ::curl_slist_free_all(headers);
         ::curl_global_cleanup();
         return false;
         }
@@ -630,6 +637,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
         "   Uploaded: " + local_file << std::endl, this->Quiet);
       }
     }
+  ::curl_slist_free_all(headers);
   ::curl_global_cleanup();
   return true;
 }
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 8b357ac..b7d8318 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -26,6 +26,7 @@ cmCTestTestCommand::cmCTestTestCommand()
   this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL";
   this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM";
   this->Arguments[ctt_STOP_TIME] = "STOP_TIME";
+  this->Arguments[ctt_TEST_LOAD] = "TEST_LOAD";
   this->Arguments[ctt_LAST] = 0;
   this->Last = ctt_LAST;
 }
@@ -103,6 +104,38 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
     {
     this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]);
     }
+
+  // Test load is determined by: TEST_LOAD argument,
+  // or CTEST_TEST_LOAD script variable, or ctest --test-load
+  // command line argument... in that order.
+  unsigned long testLoad;
+  const char* ctestTestLoad
+    = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
+  if(this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD])
+    {
+    if (!cmSystemTools::StringToULong(this->Values[ctt_TEST_LOAD], &testLoad))
+      {
+      testLoad = 0;
+      cmCTestLog(this->CTest, WARNING, "Invalid value for 'TEST_LOAD' : "
+          << this->Values[ctt_TEST_LOAD] << std::endl);
+      }
+    }
+  else if(ctestTestLoad && *ctestTestLoad)
+    {
+    if (!cmSystemTools::StringToULong(ctestTestLoad, &testLoad))
+      {
+      testLoad = 0;
+      cmCTestLog(this->CTest, WARNING,
+        "Invalid value for 'CTEST_TEST_LOAD' : " <<
+        ctestTestLoad << std::endl);
+      }
+    }
+  else
+    {
+    testLoad = this->CTest->GetTestLoad();
+    }
+  handler->SetTestLoad(testLoad);
+
   handler->SetQuiet(this->Quiet);
   return handler;
 }
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index a1e5f36..0dfca97 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -60,6 +60,7 @@ protected:
     ctt_PARALLEL_LEVEL,
     ctt_SCHEDULE_RANDOM,
     ctt_STOP_TIME,
+    ctt_TEST_LOAD,
     ctt_LAST
   };
 };
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index f93b87b..f9678e7 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -656,9 +656,8 @@ int cmCTestTestHandler::ProcessHandler()
 void cmCTestTestHandler::PrintLabelSummary()
 {
   cmCTestTestHandler::ListOfTests::iterator it = this->TestList.begin();
-  cmCTestTestHandler::TestResultsVector::iterator ri =
-    this->TestResults.begin();
   std::map<std::string, double> labelTimes;
+  std::map<std::string, int> labelCounts;
   std::set<std::string> labels;
   // initialize maps
   std::string::size_type maxlen = 0;
@@ -676,10 +675,12 @@ void cmCTestTestHandler::PrintLabelSummary()
           }
         labels.insert(*l);
         labelTimes[*l] = 0;
+        labelCounts[*l] = 0;
         }
       }
     }
-  ri = this->TestResults.begin();
+  cmCTestTestHandler::TestResultsVector::iterator ri =
+      this->TestResults.begin();
   // fill maps
   for(; ri != this->TestResults.end(); ++ri)
     {
@@ -691,6 +692,7 @@ void cmCTestTestHandler::PrintLabelSummary()
           l !=  p.Labels.end(); ++l)
         {
         labelTimes[*l] += result.ExecutionTime;
+        ++labelCounts[*l];
         }
       }
     }
@@ -705,10 +707,21 @@ void cmCTestTestHandler::PrintLabelSummary()
     {
     std::string label = *i;
     label.resize(maxlen +3, ' ');
+
     char buf[1024];
     sprintf(buf, "%6.2f sec", labelTimes[*i]);
+
+    std::ostringstream labelCountStr;
+    labelCountStr << "(" << labelCounts[*i] << " test";
+    if (labelCounts[*i] > 1)
+      {
+      labelCountStr << "s";
+      }
+    labelCountStr << ")";
+
     cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n"
-               << label << " = " << buf, this->Quiet );
+               << label << " = " << buf << " " << labelCountStr.str(),
+               this->Quiet );
     if ( this->LogFile )
       {
       *this->LogFile << "\n" << *i << " = "
@@ -1062,6 +1075,14 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string> &passed,
   parallel->SetParallelLevel(this->CTest->GetParallelLevel());
   parallel->SetTestHandler(this);
   parallel->SetQuiet(this->Quiet);
+  if(this->TestLoad > 0)
+    {
+    parallel->SetTestLoad(this->TestLoad);
+    }
+  else
+    {
+    parallel->SetTestLoad(this->CTest->GetTestLoad());
+    }
 
   *this->LogFile << "Start testing: "
     << this->CTest->CurrentTime() << std::endl
@@ -1571,8 +1592,9 @@ void cmCTestTestHandler::GetListOfTests()
   cm.SetHomeDirectory("");
   cm.SetHomeOutputDirectory("");
   cmGlobalGenerator gg(&cm);
-  cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
-  cmMakefile *mf = lg->GetMakefile();
+  cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+  cmsys::auto_ptr<cmLocalGenerator> lg(
+        gg.CreateLocalGenerator(mf.get()));
   mf->AddDefinition("CTEST_CONFIGURATION_TYPE",
     this->CTest->GetConfigType().c_str());
 
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 14067d5..c635430 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -65,6 +65,11 @@ public:
   void SetMaxIndex(int n) {this->MaxIndex = n;}
   int GetMaxIndex() {return this->MaxIndex;}
 
+  void SetTestOutputSizePassed(int n)
+    { this->CustomMaximumPassedTestOutputSize = n; }
+  void SetTestOutputSizeFailed(int n)
+    { this->CustomMaximumFailedTestOutputSize = n; }
+
   ///! pass the -I argument down
   void SetTestsToRunInformation(const char*);
 
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
index 8494d28..963e501 100644
--- a/Source/CTest/cmCTestUpdateHandler.cxx
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -283,13 +283,13 @@ int cmCTestUpdateHandler::ProcessHandler()
     {
     xml.Content("Update command failed:\n");
     xml.Content(vc->GetUpdateCommandLine());
-    cmCTestLog(this->CTest, ERROR_MESSAGE, "   Update command failed: "
+    cmCTestLog(this->CTest, HANDLER_OUTPUT, "   Update command failed: "
                << vc->GetUpdateCommandLine() << "\n");
     }
   xml.EndElement(); // UpdateReturnStatus
   xml.EndElement(); // Update
   xml.EndDocument();
-  return numUpdated;
+  return updated? numUpdated : -1;
 }
 
 //----------------------------------------------------------------------
diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx
index 31ad9fe..47e3b32 100644
--- a/Source/CTest/cmParseJacocoCoverage.cxx
+++ b/Source/CTest/cmParseJacocoCoverage.cxx
@@ -15,11 +15,9 @@ class cmParseJacocoCoverage::XMLParser: public cmXMLParser
     XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
       : CTest(ctest), Coverage(cont)
       {
+      this->FilePath = "";
+      this->PackagePath = "";
       this->PackageName = "";
-      this->ModuleName = "";
-      this->FileName = "";
-      this->CurFileName = "";
-      this->FilePaths.push_back(this->Coverage.SourceDir);
       }
 
     virtual ~XMLParser()
@@ -38,58 +36,46 @@ class cmParseJacocoCoverage::XMLParser: public cmXMLParser
       if(name == "package")
         {
         this->PackageName = atts[1];
-        std::string FilePath = this->Coverage.SourceDir +
-          "/" + this->ModuleName + "/src/main/java/" +
-          this->PackageName;
-        this->FilePaths.push_back(FilePath);
-        FilePath = this->Coverage.SourceDir +
-         "/src/main/java/" + this->PackageName;
-        this->FilePaths.push_back(FilePath);
+        this->PackagePath = "";
         }
       else if(name == "sourcefile")
         {
-        this->FileName = atts[1];
-        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
-          "Reading file: " << this->FileName << std::endl,
-          this->Coverage.Quiet);
-          for(size_t i=0;i < FilePaths.size();i++)
-            {
-            std::string finalpath = FilePaths[i] + "/" + this->FileName;
-            if(cmSystemTools::FileExists(finalpath.c_str()))
-              {
-              this->CurFileName = finalpath;
-              break;
-              }
-            }
-          cmsys::ifstream fin(this->CurFileName.c_str());
-          if(this->CurFileName == "" || !fin )
+        std::string fileName = atts[1];
+
+        if (this->PackagePath == "")
           {
-            this->CurFileName = this->Coverage.BinaryDir + "/" +
-                                   this->FileName;
-            fin.open(this->CurFileName.c_str());
-            if (!fin)
+          if(!this->FindPackagePath(fileName))
             {
-              cmCTestLog(this->CTest, ERROR_MESSAGE,
-                         "Jacoco Coverage: Error opening " << this->CurFileName
-                         << std::endl);
-              this->Coverage.Error++;
+            cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find file: "
+              << this->PackageName << "/" << fileName << std::endl);
+            this->Coverage.Error++;
+            return;
             }
           }
-          std::string line;
-          FileLinesType& curFileLines =
-            this->Coverage.TotalCoverage[this->CurFileName];
-          if(fin)
-            {
-            curFileLines.push_back(-1);
-            }
-          while(cmSystemTools::GetLineFromStream(fin, line))
+
+        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+          "Reading file: " << fileName << std::endl,
+          this->Coverage.Quiet);
+
+        this->FilePath = this->PackagePath + "/" + fileName;
+        cmsys::ifstream fin(this->FilePath.c_str());
+        if (!fin)
           {
-            curFileLines.push_back(-1);
+          cmCTestLog(this->CTest, ERROR_MESSAGE,
+                     "Jacoco Coverage: Error opening " << this->FilePath
+                     << std::endl);
+          }
+        std::string line;
+        FileLinesType& curFileLines =
+          this->Coverage.TotalCoverage[this->FilePath];
+        if(fin)
+          {
+          curFileLines.push_back(-1);
+          }
+        while(cmSystemTools::GetLineFromStream(fin, line))
+          {
+          curFileLines.push_back(-1);
           }
-        }
-      else if(name == "report")
-        {
-        this->ModuleName=atts[1];
         }
       else if(name == "line")
         {
@@ -109,7 +95,7 @@ class cmParseJacocoCoverage::XMLParser: public cmXMLParser
           if (ci > -1 && nr > 0)
             {
             FileLinesType& curFileLines=
-              this->Coverage.TotalCoverage[this->CurFileName];
+              this->Coverage.TotalCoverage[this->FilePath];
             if(!curFileLines.empty())
                {
                curFileLines[nr-1] = ci;
@@ -121,12 +107,61 @@ class cmParseJacocoCoverage::XMLParser: public cmXMLParser
         }
       }
 
+    virtual bool FindPackagePath(const std::string fileName)
+      {
+      // Search for the source file in the source directory.
+      if (this->PackagePathFound(fileName, this->Coverage.SourceDir))
+        {
+        return true;
+        }
+
+      // If not found there, check the binary directory.
+      if (this->PackagePathFound(fileName, this->Coverage.BinaryDir))
+        {
+        return true;
+        }
+      return false;
+      }
+
+    virtual bool PackagePathFound(const std::string fileName,
+                                  const std::string baseDir)
+      {
+      // Search for the file in the baseDir and its subdirectories.
+      std::string packageGlob = baseDir;
+      packageGlob += "/";
+      packageGlob += fileName;
+      cmsys::Glob gl;
+      gl.RecurseOn();
+      gl.RecurseThroughSymlinksOn();
+      gl.FindFiles(packageGlob);
+      std::vector<std::string> const& files = gl.GetFiles();
+      if (files.size() == 0)
+        {
+        return false;
+        }
+
+      // Check if any of the locations found match our package.
+      for(std::vector<std::string>::const_iterator fi = files.begin();
+          fi != files.end(); ++fi)
+        {
+        std::string dir = cmsys::SystemTools::GetParentDirectory(*fi);
+        if (cmsys::SystemTools::StringEndsWith(dir, this->PackageName.c_str()))
+          {
+          cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+                             "Found package directory for " << fileName <<
+                             ": " << dir << std::endl,
+                             this->Coverage.Quiet);
+          this->PackagePath = dir;
+          return true;
+          }
+        }
+      return false;
+      }
+
   private:
+    std::string FilePath;
+    std::string PackagePath;
     std::string PackageName;
-    std::string FileName;
-    std::string ModuleName;
-    std::string CurFileName;
-    std::vector<std::string> FilePaths;
     typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
      FileLinesType;
     cmCTest* CTest;
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index e1bd02b..0c25f40 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -62,6 +62,7 @@ bool cmProcess::StartProcess()
                                      this->WorkingDirectory.c_str());
     }
   cmsysProcess_SetTimeout(this->Process, this->Timeout);
+  cmsysProcess_SetOption(this->Process, cmsysProcess_Option_MergeOutput, 1);
   cmsysProcess_Execute(this->Process);
   return (cmsysProcess_GetState(this->Process)
           == cmsysProcess_State_Executing);
@@ -124,14 +125,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout)
   for(;;)
     {
     // Look for lines already buffered.
-    if(this->StdOut.GetLine(line))
+    if(this->Output.GetLine(line))
       {
       return cmsysProcess_Pipe_STDOUT;
       }
-    else if(this->StdErr.GetLine(line))
-      {
-      return cmsysProcess_Pipe_STDERR;
-      }
 
     // Check for more data from the process.
     char* data;
@@ -143,11 +140,7 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout)
       }
     else if(p == cmsysProcess_Pipe_STDOUT)
       {
-      this->StdOut.insert(this->StdOut.end(), data, data+length);
-      }
-    else if(p == cmsysProcess_Pipe_STDERR)
-      {
-      this->StdErr.insert(this->StdErr.end(), data, data+length);
+      this->Output.insert(this->Output.end(), data, data+length);
       }
     else // p == cmsysProcess_Pipe_None
       {
@@ -157,14 +150,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout)
     }
 
   // Look for partial last lines.
-  if(this->StdOut.GetLast(line))
+  if(this->Output.GetLast(line))
     {
     return cmsysProcess_Pipe_STDOUT;
     }
-  else if(this->StdErr.GetLast(line))
-    {
-    return cmsysProcess_Pipe_STDERR;
-    }
 
   // No more data.  Wait for process exit.
   if(!cmsysProcess_WaitForExit(this->Process, &timeout))
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index 1479df0..eddeeab 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -48,8 +48,7 @@ public:
    * Read one line of output but block for no more than timeout.
    * Returns:
    *   cmsysProcess_Pipe_None    = Process terminated and all output read
-   *   cmsysProcess_Pipe_STDOUT  = Line came from stdout
-   *   cmsysProcess_Pipe_STDOUT  = Line came from stderr
+   *   cmsysProcess_Pipe_STDOUT  = Line came from stdout or stderr
    *   cmsysProcess_Pipe_Timeout = Timeout expired while waiting
    */
   int GetNextOutputLine(std::string& line, double timeout);
@@ -68,13 +67,11 @@ private:
     bool GetLine(std::string& line);
     bool GetLast(std::string& line);
   };
-  Buffer StdErr;
-  Buffer StdOut;
+  Buffer Output;
   std::string Command;
   std::string WorkingDirectory;
   std::vector<std::string> Arguments;
   std::vector<const char*> ProcessArgs;
-  std::string Output;
   int Id;
   int ExitValue;
 };
diff --git a/Source/Checks/cm_c11_thread_local.c b/Source/Checks/cm_c11_thread_local.c
new file mode 100644
index 0000000..ab780f2
--- /dev/null
+++ b/Source/Checks/cm_c11_thread_local.c
@@ -0,0 +1,2 @@
+_Thread_local int i = 42;
+int main(void) { return 0; }
diff --git a/Source/Checks/cm_c11_thread_local.cmake b/Source/Checks/cm_c11_thread_local.cmake
new file mode 100644
index 0000000..6b8d10b
--- /dev/null
+++ b/Source/Checks/cm_c11_thread_local.cmake
@@ -0,0 +1,33 @@
+set(CMake_C11_THREAD_LOCAL_BROKEN 0)
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_C11_STANDARD_COMPILE_OPTION)
+  if(NOT DEFINED CMake_C11_THREAD_LOCAL_WORKS)
+    message(STATUS "Checking if compiler supports C11 _Thread_local")
+    try_compile(CMake_C11_THREAD_LOCAL_WORKS
+      ${CMAKE_CURRENT_BINARY_DIR}
+      ${CMAKE_CURRENT_LIST_DIR}/cm_c11_thread_local.c
+      CMAKE_FLAGS -DCMAKE_C_STANDARD=11
+      OUTPUT_VARIABLE OUTPUT
+      )
+    if(CMake_C11_THREAD_LOCAL_WORKS AND "${OUTPUT}" MATCHES "error: expected '=', ',', ';', 'asm' or '__attribute__' before 'int'")
+      set_property(CACHE CMake_C11_THREAD_LOCAL_WORKS PROPERTY VALUE 0)
+    endif()
+    if(CMake_C11_THREAD_LOCAL_WORKS)
+      message(STATUS "Checking if compiler supports C11 _Thread_local - yes")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Determining if compiler supports C11 _Thread_local passed with the following output:\n"
+        "${OUTPUT}\n"
+        "\n"
+        )
+    else()
+      message(STATUS "Checking if compiler supports C11 _Thread_local - no")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Determining if compiler supports C11 _Thread_local failed with the following output:\n"
+        "${OUTPUT}\n"
+        "\n"
+        )
+    endif()
+  endif()
+  if(NOT CMake_C11_THREAD_LOCAL_WORKS)
+    set(CMake_C11_THREAD_LOCAL_BROKEN 1)
+  endif()
+endif()
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
index 7d4e88c..93ff425 100644
--- a/Source/CursesDialog/CMakeLists.txt
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -47,4 +47,5 @@ else()
   target_link_libraries(ccmake cmForm)
 endif()
 
-install(TARGETS ccmake DESTINATION bin)
+CMake_OPTIONAL_COMPONENT(ccmake)
+install(TARGETS ccmake DESTINATION bin ${COMPONENT})
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index 67e4aab..6144ddc 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.cxx
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -80,12 +80,13 @@ void cmCursesLongMessageForm::UpdateStatusBar()
   sprintf(version+sideSpace, "%s", vertmp);
   version[width] = '\0';
 
+  char fmt_s[] = "%s";
   curses_move(y-4,0);
   attron(A_STANDOUT);
-  printw(bar);
+  printw(fmt_s, bar);
   attroff(A_STANDOUT);
   curses_move(y-3,0);
-  printw(version);
+  printw(fmt_s, version);
   pos_form_cursor(this->Form);
 }
 
@@ -101,8 +102,9 @@ void cmCursesLongMessageForm::PrintKeys()
   char firstLine[512];
   sprintf(firstLine,  "Press [e] to exit help");
 
+  char fmt_s[] = "%s";
   curses_move(y-2,0);
-  printw(firstLine);
+  printw(fmt_s, firstLine);
   pos_form_cursor(this->Form);
 
 }
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index be17a9f..a2fc2c0 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -451,24 +451,25 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */)
     }
 
   curses_move(y-4,0);
+  char fmt_s[] = "%s";
   char fmt[512] = "Press [enter] to edit option";
   if ( process )
     {
     strcpy(fmt, "                           ");
     }
-  printw(fmt);
+  printw(fmt_s, fmt);
   curses_move(y-3,0);
-  printw(firstLine);
+  printw(fmt_s, firstLine);
   curses_move(y-2,0);
-  printw(secondLine);
+  printw(fmt_s, secondLine);
   curses_move(y-1,0);
-  printw(thirdLine);
+  printw(fmt_s, thirdLine);
 
   if (cw)
     {
     sprintf(firstLine, "Page %d of %d", cw->GetPage(), this->NumberOfPages);
     curses_move(0,65-static_cast<unsigned int>(strlen(firstLine))-1);
-    printw(firstLine);
+    printw(fmt_s, firstLine);
     }
 //    }
 
@@ -612,13 +613,13 @@ void cmCursesMainForm::UpdateStatusBar(const char* message)
   version[width] = '\0';
 
   // Now print both lines
+  char fmt_s[] = "%s";
   curses_move(y-5,0);
   attron(A_STANDOUT);
-  char format[] = "%s";
-  printw(format, bar);
+  printw(fmt_s, bar);
   attroff(A_STANDOUT);
   curses_move(y-4,0);
-  printw(version);
+  printw(fmt_s, version);
   pos_form_cursor(this->Form);
 }
 
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
index acf262f..6eb15c1 100644
--- a/Source/CursesDialog/cmCursesStringWidget.cxx
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -168,17 +168,16 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
     else if ( key == 127 ||
               key == KEY_BACKSPACE )
       {
-      if ( form->curcol > 0 )
-        {
+        FIELD *cur = current_field(form);
         form_driver(form, REQ_DEL_PREV);
-        }
+        if (current_field(form) != cur)
+          {
+          set_current_field(form, cur);
+          }
       }
     else if ( key == ctrl('d') ||key == KEY_DC )
       {
-      if ( form->curcol >= 0 )
-        {
-        form_driver(form, REQ_DEL_CHAR);
-        }
+      form_driver(form, REQ_DEL_CHAR);
       }
     else
       {
@@ -221,6 +220,7 @@ bool cmCursesStringWidget::PrintKeys()
     }
   if (this->InEdit)
     {
+    char fmt_s[] = "%s";
     char firstLine[512];
     // Clean the toolbar
     for(int i=0; i<512; i++)
@@ -229,17 +229,16 @@ bool cmCursesStringWidget::PrintKeys()
       }
     firstLine[511] = '\0';
     curses_move(y-4,0);
-    printw(firstLine);
+    printw(fmt_s, firstLine);
     curses_move(y-3,0);
-    printw(firstLine);
+    printw(fmt_s, firstLine);
     curses_move(y-2,0);
-    printw(firstLine);
+    printw(fmt_s, firstLine);
     curses_move(y-1,0);
-    printw(firstLine);
+    printw(fmt_s, firstLine);
 
-    sprintf(firstLine,  "Editing option, press [enter] to leave edit.");
     curses_move(y-3,0);
-    printw(firstLine);
+    printw(fmt_s, "Editing option, press [enter] to leave edit.");
     return true;
     }
   else
diff --git a/Source/CursesDialog/cmCursesWidget.cxx b/Source/CursesDialog/cmCursesWidget.cxx
index e5363f4..a12e4c2 100644
--- a/Source/CursesDialog/cmCursesWidget.cxx
+++ b/Source/CursesDialog/cmCursesWidget.cxx
@@ -49,7 +49,7 @@ void cmCursesWidget::Move(int x, int y, bool isNewPage)
 void cmCursesWidget::SetValue(const std::string& value)
 {
   this->Value = value;
-  set_field_buffer(this->Field, 0, value.c_str());
+  set_field_buffer(this->Field, 0, const_cast<char *>(value.c_str()));
 }
 
 const char* cmCursesWidget::GetValue()
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 168f57d..66fd18b 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -14,6 +14,7 @@ project(QtDialog)
 if(POLICY CMP0020)
   cmake_policy(SET CMP0020 NEW) # Drop when CMake >= 2.8.11 required
 endif()
+CMake_OPTIONAL_COMPONENT(cmake-gui)
 find_package(Qt5Widgets QUIET)
 if (Qt5Widgets_FOUND)
   include_directories(${Qt5Widgets_INCLUDE_DIRS})
@@ -35,35 +36,54 @@ if (Qt5Widgets_FOUND)
 
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
 
-  # We need to install Cocoa platform plugin and add qt.conf for Qt5 on Mac.
+  # We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
   # FIXME: This should be part of Qt5 CMake scripts, but unfortunatelly
-  # Qt5 Mac support is missing there.
-  if(APPLE)
+  # Qt5 support is missing there.
+  if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
     macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
       get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
       if(EXISTS "${_qt_plugin_path}")
         get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
         get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
         get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
-        set(_qt_plugin_dest "PlugIns/${_qt_plugin_type}")
+        if(APPLE)
+          set(_qt_plugin_dir "PlugIns")
+        elseif(WIN32)
+          set(_qt_plugin_dir "plugins")
+        endif()
+        set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
         install(FILES "${_qt_plugin_path}"
-          DESTINATION "${_qt_plugin_dest}")
+          DESTINATION "${_qt_plugin_dest}"
+          ${COMPONENT})
         set(${_qt_plugins_var}
           "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
       else()
         message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
       endif()
     endmacro()
-    install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
-    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-      "[Paths]\nPlugins = PlugIns\n")
-    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-      DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources")
+    if(APPLE)
+      install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
+      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+        "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
+      install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+        DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+        ${COMPONENT})
+    elseif(WIN32)
+      install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
+      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+        "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
+      install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+        DESTINATION bin
+        ${COMPONENT})
+    endif()
   endif()
 
-  if(WIN32 AND TARGET Qt5::Core)
+  if(TARGET Qt5::Core)
     get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
     get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
+    if(APPLE)
+      get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
+    endif()
   endif()
 else()
   set(QT_MIN_VERSION "4.4.0")
@@ -77,12 +97,6 @@ else()
 
   set(CMake_QT_LIBRARIES ${QT_LIBRARIES})
 
-  if(WIN32 AND EXISTS "${QT_QMAKE_EXECUTABLE}")
-    get_filename_component(_Qt_BIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH)
-    if(EXISTS "${_Qt_BIN_DIR}/QtCore4.dll")
-      set(Qt_BIN_DIR ${_Qt_BIN_DIR})
-    endif()
-  endif()
 endif()
 
 set(SRCS
@@ -130,18 +144,16 @@ endif()
 
 if(CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL)
   install(FILES ${CMake_SOURCE_DIR}/Licenses/LGPLv2.1.txt
-    DESTINATION ${CMAKE_DATA_DIR}/Licenses)
+    DESTINATION ${CMAKE_DATA_DIR}/Licenses
+    ${COMPONENT})
   set_property(SOURCE CMakeSetupDialog.cxx
     PROPERTY COMPILE_DEFINITIONS CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL)
 endif()
 
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
-add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS})
+add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS} ${MANIFEST_FILE})
 target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${CMake_QT_LIBRARIES})
-if(Qt_BIN_DIR)
-  set_property(TARGET cmake-gui PROPERTY Qt_BIN_DIR ${Qt_BIN_DIR})
-endif()
 
 if(APPLE)
   file(STRINGS "${CMake_SOURCE_DIR}/Copyright.txt" copyright_line
@@ -163,30 +175,39 @@ if(APPLE)
     )
 endif()
 set(CMAKE_INSTALL_DESTINATION_ARGS
-  BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}")
+  BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}" ${COMPONENT})
 
-install(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS})
+install(TARGETS cmake-gui
+  RUNTIME DESTINATION bin ${COMPONENT}
+  ${CMAKE_INSTALL_DESTINATION_ARGS})
 
 if(UNIX AND NOT APPLE)
   foreach (size IN ITEMS 32 128)
     install(
       FILES       "${CMAKE_CURRENT_SOURCE_DIR}/CMakeSetup${size}.png"
       DESTINATION "share/icons/hicolor/${size}x${size}/apps"
+      ${COMPONENT}
       RENAME      "CMakeSetup.png")
   endforeach ()
 
   # install a desktop file so CMake appears in the application start menu
   # with an icon
-  install(FILES CMake.desktop DESTINATION share/applications )
-  install(FILES cmakecache.xml DESTINATION share/mime/packages )
+  install(FILES CMake.desktop
+    DESTINATION share/applications
+    ${COMPONENT})
+  install(FILES cmakecache.xml
+    DESTINATION share/mime/packages
+    ${COMPONENT})
 endif()
 
 if(APPLE)
-  install(CODE "execute_process(COMMAND ln -s \"../MacOS/CMake\" cmake-gui
-                WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)")
+  install(CODE "
+    execute_process(COMMAND ln -s \"../MacOS/CMake\" cmake-gui
+        WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)
+  " ${COMPONENT})
 endif()
 
-if(APPLE OR WIN32)
+if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
   # install rules for including 3rd party libs such as Qt
   # if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation
   set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}")
@@ -196,8 +217,8 @@ if(APPLE OR WIN32)
   install(CODE "
     include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\")
     set(BU_CHMOD_BUNDLE_ITEMS ON)
-    fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
-  ")
+    fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${Qt_BIN_DIR};${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
+  " ${COMPONENT})
 endif()
 
 set(CMAKE_PACKAGE_QTGUI TRUE)
diff --git a/Source/QtDialog/Info.plist.in b/Source/QtDialog/Info.plist.in
index b9c4af5..00a27c3 100644
--- a/Source/QtDialog/Info.plist.in
+++ b/Source/QtDialog/Info.plist.in
@@ -28,5 +28,7 @@
 	<string>public.app-category.developer-tools</string>
 	<key>NSHumanReadableCopyright</key>
 	<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+	<key>NSHighResolutionCapable</key>
+	<true/>
 </dict>
 </plist>
diff --git a/Source/QtIFW/CMake.Dialogs.QtGUI.qs b/Source/QtIFW/CMake.Dialogs.QtGUI.qs
new file mode 100644
index 0000000..219a0a9
--- /dev/null
+++ b/Source/QtIFW/CMake.Dialogs.QtGUI.qs
@@ -0,0 +1,21 @@
+// Component: CMake.Dialogs.QtGUI
+
+function Component()
+{
+    // Default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+    // Create shortcut
+    if (installer.value("os") === "win") {
+
+        component.addOperation("CreateShortcut",
+                               installer.value("TargetDir") + "/bin/cmake-gui.exe",
+                               installer.value("StartMenuDir") + "/CMake (cmake-gui).lnk");
+
+    }
+
+    // Call default implementation
+    component.createOperations();
+}
diff --git a/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
new file mode 100644
index 0000000..5c929e8
--- /dev/null
+++ b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
@@ -0,0 +1,21 @@
+// Component: CMake.Documentation.SphinxHTML
+
+function Component()
+{
+    // Default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+    // Create shortcut
+    if (installer.value("os") === "win") {
+
+        component.addOperation("CreateShortcut",
+                               installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/html/index.html",
+                               installer.value("StartMenuDir") + "/CMake Documentation.lnk");
+
+    }
+
+    // Call default implementation
+    component.createOperations();
+}
diff --git a/Source/QtIFW/CMake.qs.in b/Source/QtIFW/CMake.qs.in
new file mode 100644
index 0000000..828cc7c
--- /dev/null
+++ b/Source/QtIFW/CMake.qs.in
@@ -0,0 +1,22 @@
+function Component()
+{
+    // Default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+    // Create shortcut
+    if (installer.value("os") === "win") {
+
+        component.addOperation("CreateShortcut",
+                               installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html",
+                               installer.value("StartMenuDir") + "/CMake Web Site.lnk");
+
+        component.addOperation("CreateShortcut",
+                               installer.value("TargetDir") + "/cmake-maintenance.exe",
+                               installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk");
+    }
+
+    // Call default implementation
+    component.createOperations();
+}
diff --git a/Source/QtIFW/installscript.qs.in b/Source/QtIFW/installscript.qs.in
index 570dba1..3411e34 100644
--- a/Source/QtIFW/installscript.qs.in
+++ b/Source/QtIFW/installscript.qs.in
@@ -5,20 +5,20 @@ function Component()
 
 Component.prototype.createOperations = function()
 {
-    // call default implementation to actually install applications!
-    component.createOperations();
-
     // Create shortcut
     if (installer.value("os") === "win") {
 
 @_CPACK_IFW_SHORTCUT_OPTIONAL@
 
         component.addOperation("CreateShortcut",
-                               installer.value("TargetDir") + "/cmake.org.html",
+                               installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html",
                                installer.value("StartMenuDir") + "/CMake Web Site.lnk");
 
         component.addOperation("CreateShortcut",
                                installer.value("TargetDir") + "/cmake-maintenance.exe",
                                installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk");
     }
+
+    // Call default implementation
+    component.createOperations();
 }
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
new file mode 100644
index 0000000..dc4db63
--- /dev/null
+++ b/Source/bindexplib.cxx
@@ -0,0 +1,439 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc.
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+  Portions of this source have been derived from the 'bindexplib' tool
+  provided by the CERN ROOT Data Analysis Framework project (root.cern.ch).
+  Permission has been granted by Pere Mato <pere.mato at cern.ch> to distribute
+  this derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+*----------------------------------------------------------------------
+* Program:  dumpexts.exe
+* Author:   Gordon Chaffee
+*
+* History:  The real functionality of this file was written by
+*           Matt Pietrek in 1993 in his pedump utility.  I've
+*           modified it to dump the externals in a bunch of object
+*           files to create a .def file.
+*
+* Notes:    Visual C++ puts an underscore before each exported symbol.
+*           This file removes them.  I don't know if this is a problem
+*           this other compilers.  If _MSC_VER is defined,
+*           the underscore is removed.  If not, it isn't.  To get a
+*           full dump of an object file, use the -f option.  This can
+*           help determine the something that may be different with a
+*           compiler other than Visual C++.
+*   ======================================
+* Corrections (Axel 2006-04-04):
+*   Conversion to C++. Mostly.
+*
+ * Extension (Axel 2006-03-15)
+ *    As soon as an object file contains an /EXPORT directive (which
+ *    is generated by the compiler when a symbol is declared as
+ *    declspec(dllexport)) no to-be-exported symbols are printed,
+ *    as the linker will see these directives, and if those directives
+ *    are present we only export selectively (i.e. we trust the
+ *    programmer).
+ *
+ *   ======================================
+*   ======================================
+* Corrections (Valery Fine 23/02/98):
+*
+*           The "(vector) deleting destructor" MUST not be exported
+*           To recognize it the following test are introduced:
+*  "@@UAEPAXI at Z"  scalar deleting dtor
+*  "@@QAEPAXI at Z"  vector deleting dtor
+*  "AEPAXI at Z"     vector deleting dtor with thunk adjustor
+*   ======================================
+* Corrections (Valery Fine 12/02/97):
+*
+*    It created a wrong EXPORTS for the global pointers and constants.
+*    The Section Header has been involved to discover the missing information
+*    Now the pointers are correctly supplied  supplied with "DATA" descriptor
+*        the constants  with no extra descriptor.
+*
+* Corrections (Valery Fine 16/09/96):
+*
+*     It didn't work for C++ code with global variables and class definitons
+*     The DumpExternalObject function has been introduced to generate .DEF file
+*
+* Author:   Valery Fine 16/09/96  (E-mail: fine at vxcern.cern.ch)
+*----------------------------------------------------------------------
+*/
+
+#include <cmsys/Encoding.hxx>
+#include <windows.h>
+#include <stdio.h>
+#include <string>
+#include <fstream>
+#include <iostream>
+
+typedef struct cmANON_OBJECT_HEADER_BIGOBJ {
+   /* same as ANON_OBJECT_HEADER_V2 */
+    WORD    Sig1;            // Must be IMAGE_FILE_MACHINE_UNKNOWN
+    WORD    Sig2;            // Must be 0xffff
+    WORD    Version;         // >= 2 (implies the Flags field is present)
+    WORD    Machine;         // Actual machine - IMAGE_FILE_MACHINE_xxx
+    DWORD   TimeDateStamp;
+    CLSID   ClassID;         // {D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8}
+    DWORD   SizeOfData;      // Size of data that follows the header
+    DWORD   Flags;           // 0x1 -> contains metadata
+    DWORD   MetaDataSize;    // Size of CLR metadata
+    DWORD   MetaDataOffset;  // Offset of CLR metadata
+
+    /* bigobj specifics */
+    DWORD   NumberOfSections; // extended from WORD
+    DWORD   PointerToSymbolTable;
+    DWORD   NumberOfSymbols;
+} cmANON_OBJECT_HEADER_BIGOBJ;
+
+typedef struct _cmIMAGE_SYMBOL_EX {
+    union {
+        BYTE     ShortName[8];
+        struct {
+            DWORD   Short;     // if 0, use LongName
+            DWORD   Long;      // offset into string table
+        } Name;
+        DWORD   LongName[2];    // PBYTE  [2]
+    } N;
+    DWORD   Value;
+    LONG    SectionNumber;
+    WORD    Type;
+    BYTE    StorageClass;
+    BYTE    NumberOfAuxSymbols;
+} cmIMAGE_SYMBOL_EX;
+typedef cmIMAGE_SYMBOL_EX UNALIGNED *cmPIMAGE_SYMBOL_EX;
+
+PIMAGE_SECTION_HEADER GetSectionHeaderOffset(PIMAGE_FILE_HEADER
+                                             pImageFileHeader)
+{
+  return (PIMAGE_SECTION_HEADER)
+    ((DWORD_PTR)pImageFileHeader +
+     IMAGE_SIZEOF_FILE_HEADER +
+     pImageFileHeader->SizeOfOptionalHeader);
+}
+
+PIMAGE_SECTION_HEADER GetSectionHeaderOffset(cmANON_OBJECT_HEADER_BIGOBJ*
+                                             pImageFileHeader)
+{
+  return (PIMAGE_SECTION_HEADER)
+      ((DWORD_PTR)pImageFileHeader          +
+       sizeof(cmANON_OBJECT_HEADER_BIGOBJ));
+}
+
+/*
++ * Utility func, strstr with size
++ */
+const char* StrNStr(const char* start, const char* find, size_t &size) {
+   size_t len;
+   const char* hint;
+
+   if (!start || !find || !size) {
+      size = 0;
+      return 0;
+   }
+   len = strlen(find);
+
+   while ((hint = (const char*) memchr(start, find[0], size-len+1))) {
+      size -= (hint - start);
+      if (!strncmp(hint, find, len))
+         return hint;
+      start = hint + 1;
+   }
+
+   size = 0;
+   return 0;
+}
+
+template <
+  // cmANON_OBJECT_HEADER_BIGOBJ or IMAGE_FILE_HEADER
+  class ObjectHeaderType,
+  // cmPIMAGE_SYMBOL_EX or PIMAGE_SYMBOL
+  class SymbolTableType>
+class DumpSymbols
+{
+public:
+  /*
+   *----------------------------------------------------------------------
+   * Constructor --
+   *
+   *     Initialize variables from pointer to object header.
+   *
+   *----------------------------------------------------------------------
+   */
+
+   DumpSymbols(ObjectHeaderType* ih,
+               FILE* fout, bool is64) {
+      this->ObjectImageHeader = ih;
+      this->SymbolTable = (SymbolTableType*)
+      ((DWORD_PTR)this->ObjectImageHeader
+       + this->ObjectImageHeader->PointerToSymbolTable);
+      this->FileOut = fout;
+      this->SectionHeaders =
+        GetSectionHeaderOffset(this->ObjectImageHeader);
+      this->ImportFlag = true;
+      this->SymbolCount = this->ObjectImageHeader->NumberOfSymbols;
+      this->Is64Bit = is64;
+   }
+
+  /*
+   *----------------------------------------------------------------------
+   * HaveExportedObjects --
+   *
+   *      Returns true if export directives (declspec(dllexport)) exist.
+   *
+   *----------------------------------------------------------------------
+   */
+
+  bool HaveExportedObjects() {
+     WORD i = 0;
+     size_t size = 0;
+     const char * rawdata = 0;
+     PIMAGE_SECTION_HEADER pDirectivesSectionHeader = 0;
+     PIMAGE_SECTION_HEADER pSectionHeaders = this->SectionHeaders;
+     for(i = 0; (i < this->ObjectImageHeader->NumberOfSections &&
+                 !pDirectivesSectionHeader); i++)
+       if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
+         pDirectivesSectionHeader = &pSectionHeaders[i];
+     if (!pDirectivesSectionHeader) return 0;
+
+     rawdata=(const char*)
+       this->ObjectImageHeader+pDirectivesSectionHeader->PointerToRawData;
+     if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
+
+     size = pDirectivesSectionHeader->SizeOfRawData;
+     const char* posImportFlag = rawdata;
+     while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) {
+       const char* lookingForDict = posImportFlag + 9;
+       if (!strncmp(lookingForDict, "_G__cpp_",8) ||
+           !strncmp(lookingForDict, "_G__set_cpp_",12)) {
+          posImportFlag = lookingForDict;
+          continue;
+       }
+
+       const char* lookingForDATA = posImportFlag + 9;
+       while (*(++lookingForDATA) && *lookingForDATA != ' ');
+       lookingForDATA -= 5;
+       // ignore DATA exports
+       if (strncmp(lookingForDATA, ",DATA", 5)) break;
+       posImportFlag = lookingForDATA + 5;
+     }
+     if(posImportFlag) {
+        return true;
+     }
+     return false;
+  }
+
+  /*
+   *----------------------------------------------------------------------
+   * DumpObjFile --
+   *
+   *      Dump an object file's exported symbols.
+   *----------------------------------------------------------------------
+   */
+  void DumpObjFile() {
+     if(!HaveExportedObjects()) {
+        this->DumpExternalsObjects();
+     }
+  }
+
+  /*
+   *----------------------------------------------------------------------
+   * DumpExternalsObjects --
+   *
+   *      Dumps a COFF symbol table from an OBJ.
+   *----------------------------------------------------------------------
+   */
+  void DumpExternalsObjects() {
+    unsigned i;
+    PSTR stringTable;
+    std::string symbol;
+    DWORD SectChar;
+    /*
+     * The string table apparently starts right after the symbol table
+     */
+    stringTable = (PSTR)&this->SymbolTable[this->SymbolCount];
+    SymbolTableType* pSymbolTable = this->SymbolTable;
+    for ( i=0; i < this->SymbolCount; i++ ) {
+      if (pSymbolTable->SectionNumber > 0 &&
+          ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
+         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+            /*
+            *    The name of the Function entry points
+            */
+            if (pSymbolTable->N.Name.Short != 0) {
+               symbol = "";
+               symbol.insert(0, (const char *)pSymbolTable->N.ShortName, 8);
+            } else {
+               symbol = stringTable + pSymbolTable->N.Name.Long;
+            }
+
+            // clear out any leading spaces
+            while (isspace(symbol[0])) symbol.erase(0,1);
+            // if it starts with _ and has an @ then it is a __cdecl
+            // so remove the @ stuff for the export
+            if(symbol[0] == '_') {
+               std::string::size_type posAt = symbol.find('@');
+               if (posAt != std::string::npos) {
+                  symbol.erase(posAt);
+               }
+            }
+            // For 64 bit builds we don't need to remove _
+            if(!this->Is64Bit)
+              {
+              if (symbol[0] == '_')
+                {
+                symbol.erase(0,1);
+                }
+              }
+            if (this->ImportFlag) {
+               this->ImportFlag = false;
+               fprintf(this->FileOut,"EXPORTS \n");
+            }
+            /*
+            Check whether it is "Scalar deleting destructor" and
+            "Vector deleting destructor"
+            */
+            const char *scalarPrefix = "??_G";
+            const char *vectorPrefix = "??_E";
+            // original code had a check for
+            // symbol.find("real@") == std::string::npos)
+            // but if this disallows memmber functions with the name real
+            // if scalarPrefix and vectorPrefix are not found then print
+            // the symbol
+            if (symbol.compare(0, 4, scalarPrefix) &&
+                symbol.compare(0, 4, vectorPrefix) )
+            {
+               SectChar =
+                 this->
+                 SectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
+               if (!pSymbolTable->Type  && (SectChar & IMAGE_SCN_MEM_WRITE)) {
+                  // Read only (i.e. constants) must be excluded
+                  fprintf(this->FileOut, "\t%s \t DATA\n", symbol.c_str());
+               } else {
+                  if ( pSymbolTable->Type  ||
+                       !(SectChar & IMAGE_SCN_MEM_READ)) {
+                     fprintf(this->FileOut, "\t%s\n", symbol.c_str());
+                  } else {
+                     // printf(" strange symbol: %s \n",symbol.c_str());
+                  }
+               }
+            }
+         }
+      }
+      else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED &&
+               !pSymbolTable->Type && 0) {
+         /*
+         *    The IMPORT global variable entry points
+         */
+         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+            symbol = stringTable + pSymbolTable->N.Name.Long;
+            while (isspace(symbol[0]))  symbol.erase(0,1);
+            if (symbol[0] == '_') symbol.erase(0,1);
+            if (!this->ImportFlag) {
+               this->ImportFlag = true;
+               fprintf(this->FileOut,"IMPORTS \n");
+            }
+            fprintf(this->FileOut, "\t%s DATA \n", symbol.c_str()+1);
+         }
+      }
+
+      /*
+      * Take into account any aux symbols
+      */
+      i += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable++;
+    }
+  }
+private:
+  bool ImportFlag;
+  FILE* FileOut;
+  DWORD_PTR SymbolCount;
+  PIMAGE_SECTION_HEADER SectionHeaders;
+  ObjectHeaderType* ObjectImageHeader;
+  SymbolTableType*  SymbolTable;
+  bool Is64Bit;
+};
+
+bool
+DumpFile(const char* filename, FILE *fout)
+{
+   HANDLE hFile;
+   HANDLE hFileMapping;
+   LPVOID lpFileBase;
+   PIMAGE_DOS_HEADER dosHeader;
+
+   hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(),
+                       GENERIC_READ, FILE_SHARE_READ, NULL,
+      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+   if (hFile == INVALID_HANDLE_VALUE) {
+      fprintf(stderr, "Couldn't open file '%s' with CreateFile()\n", filename);
+      return false;
+   }
+
+   hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+   if (hFileMapping == 0) {
+      CloseHandle(hFile);
+      fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
+      return false;
+   }
+
+   lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
+   if (lpFileBase == 0) {
+      CloseHandle(hFileMapping);
+      CloseHandle(hFile);
+      fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
+      return false;
+   }
+
+   dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
+   if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
+      fprintf(stderr, "File is an executable.  I don't dump those.\n");
+      return false;
+   }
+   /* Does it look like a i386 COFF OBJ file??? */
+   else if (
+           ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) ||
+            (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
+           && (dosHeader->e_sp == 0)
+           ) {
+      /*
+      * The two tests above aren't what they look like.  They're
+      * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
+      * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
+      */
+      DumpSymbols<IMAGE_FILE_HEADER, IMAGE_SYMBOL>
+        symbolDumper((PIMAGE_FILE_HEADER) lpFileBase, fout,
+                     (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64));
+      symbolDumper.DumpObjFile();
+   } else {
+      // check for /bigobj format
+      cmANON_OBJECT_HEADER_BIGOBJ* h =
+        (cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase;
+      if(h->Sig1 == 0x0 && h->Sig2 == 0xffff) {
+         DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX>
+           symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase, fout,
+                        (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64));
+         symbolDumper.DumpObjFile();
+      } else {
+         printf("unrecognized file format in '%s'\n", filename);
+         return false;
+      }
+   }
+   UnmapViewOfFile(lpFileBase);
+   CloseHandle(hFileMapping);
+   CloseHandle(hFile);
+   return true;
+}
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index f117475..bda933b 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -122,35 +122,6 @@ struct DefaultDeleter<Range, /* valueTypeIsPair = */ true>
   }
 };
 
-template<typename const_iterator_>
-struct Range
-{
-  typedef const_iterator_ const_iterator;
-  typedef typename std::iterator_traits<const_iterator>::value_type value_type;
-  typedef typename std::iterator_traits<const_iterator>::difference_type
-    difference_type;
-  Range(const_iterator begin_, const_iterator end_)
-    : Begin(begin_), End(end_) {}
-  const_iterator begin() const { return Begin; }
-  const_iterator end() const { return End; }
-  bool empty() const { return std::distance(Begin, End) == 0; }
-  difference_type size() const { return std::distance(Begin, End); }
-  Range& advance(cmIML_INT_intptr_t amount)
-  {
-    std::advance(Begin, amount);
-    return *this;
-  }
-
-  Range& retreat(cmIML_INT_intptr_t amount)
-  {
-    std::advance(End, -amount);
-    return *this;
-  }
-private:
-  const_iterator Begin;
-  const_iterator End;
-};
-
 template<typename FwdIt>
 FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n)
 {
@@ -178,17 +149,52 @@ private:
 
 }
 
+template<typename const_iterator_>
+struct cmRange
+{
+  typedef const_iterator_ const_iterator;
+  typedef typename std::iterator_traits<const_iterator>::value_type value_type;
+  typedef typename std::iterator_traits<const_iterator>::difference_type
+    difference_type;
+  cmRange(const_iterator begin_, const_iterator end_)
+    : Begin(begin_), End(end_) {}
+  const_iterator begin() const { return Begin; }
+  const_iterator end() const { return End; }
+  bool empty() const { return std::distance(Begin, End) == 0; }
+  difference_type size() const { return std::distance(Begin, End); }
+  cmRange& advance(cmIML_INT_intptr_t amount)
+  {
+    std::advance(Begin, amount);
+    return *this;
+  }
+
+  cmRange& retreat(cmIML_INT_intptr_t amount)
+  {
+    std::advance(End, -amount);
+    return *this;
+  }
+private:
+  const_iterator Begin;
+  const_iterator End;
+};
+
+typedef cmRange<std::vector<std::string>::const_iterator> cmStringRange;
+
+class cmListFileBacktrace;
+typedef
+cmRange<std::vector<cmListFileBacktrace>::const_iterator> cmBacktraceRange;
+
 template<typename Iter1, typename Iter2>
-ContainerAlgorithms::Range<Iter1> cmRange(Iter1 begin, Iter2 end)
+cmRange<Iter1> cmMakeRange(Iter1 begin, Iter2 end)
 {
-  return ContainerAlgorithms::Range<Iter1>(begin, end);
+  return cmRange<Iter1>(begin, end);
 }
 
 template<typename Range>
-ContainerAlgorithms::Range<typename Range::const_iterator>
-cmRange(Range const& range)
+cmRange<typename Range::const_iterator>
+cmMakeRange(Range const& range)
 {
-  return ContainerAlgorithms::Range<typename Range::const_iterator>(
+  return cmRange<typename Range::const_iterator>(
       range.begin(), range.end());
 }
 
@@ -350,11 +356,17 @@ typename Range::const_iterator cmFindNot(Range const& r, T const& t)
 }
 
 template<typename Range>
-ContainerAlgorithms::Range<typename Range::const_reverse_iterator>
+cmRange<typename Range::const_reverse_iterator>
 cmReverseRange(Range const& range)
 {
-  return ContainerAlgorithms::Range<typename Range::const_reverse_iterator>(
+  return cmRange<typename Range::const_reverse_iterator>(
       range.rbegin(), range.rend());
 }
 
+template <class Iter>
+std::reverse_iterator<Iter> cmMakeReverseIterator(Iter it)
+{
+  return std::reverse_iterator<Iter>(it);
+}
+
 #endif
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 72818f5..7946950 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -13,7 +13,6 @@
 
 #include "cmSystemTools.h"
 #include "cmLocale.h"
-#include <cmsys/ios/iostream>
 #include <cmsys/Directory.hxx>
 #include <cmsys/FStream.hxx>
 #include <cm_libarchive.h>
@@ -67,7 +66,7 @@ struct cmArchiveWrite::Callback
     {
     cmArchiveWrite* self = static_cast<cmArchiveWrite*>(cd);
     if(self->Stream.write(static_cast<const char*>(b),
-                          static_cast<cmsys_ios::streamsize>(n)))
+                          static_cast<std::streamsize>(n)))
       {
       return static_cast<__LA_SSIZE_T>(n);
       }
@@ -84,54 +83,55 @@ cmArchiveWrite::cmArchiveWrite(
     Stream(os),
     Archive(archive_write_new()),
     Disk(archive_read_disk_new()),
-    Verbose(false)
+    Verbose(false),
+    Format(format)
 {
   switch (c)
     {
     case CompressNone:
-      if(archive_write_set_compression_none(this->Archive) != ARCHIVE_OK)
+      if(archive_write_add_filter_none(this->Archive) != ARCHIVE_OK)
         {
-        this->Error = "archive_write_set_compression_none: ";
+        this->Error = "archive_write_add_filter_none: ";
         this->Error += cm_archive_error_string(this->Archive);
         return;
         }
       break;
     case CompressCompress:
-      if(archive_write_set_compression_compress(this->Archive) != ARCHIVE_OK)
+      if(archive_write_add_filter_compress(this->Archive) != ARCHIVE_OK)
         {
-        this->Error = "archive_write_set_compression_compress: ";
+        this->Error = "archive_write_add_filter_compress: ";
         this->Error += cm_archive_error_string(this->Archive);
         return;
         }
       break;
     case CompressGZip:
-      if(archive_write_set_compression_gzip(this->Archive) != ARCHIVE_OK)
+      if(archive_write_add_filter_gzip(this->Archive) != ARCHIVE_OK)
         {
-        this->Error = "archive_write_set_compression_gzip: ";
+        this->Error = "archive_write_add_filter_gzip: ";
         this->Error += cm_archive_error_string(this->Archive);
         return;
         }
       break;
     case CompressBZip2:
-      if(archive_write_set_compression_bzip2(this->Archive) != ARCHIVE_OK)
+      if(archive_write_add_filter_bzip2(this->Archive) != ARCHIVE_OK)
         {
-        this->Error = "archive_write_set_compression_bzip2: ";
+        this->Error = "archive_write_add_filter_bzip2: ";
         this->Error += cm_archive_error_string(this->Archive);
         return;
         }
       break;
     case CompressLZMA:
-      if(archive_write_set_compression_lzma(this->Archive) != ARCHIVE_OK)
+      if(archive_write_add_filter_lzma(this->Archive) != ARCHIVE_OK)
         {
-        this->Error = "archive_write_set_compression_lzma: ";
+        this->Error = "archive_write_add_filter_lzma: ";
         this->Error += cm_archive_error_string(this->Archive);
         return;
         }
       break;
     case CompressXZ:
-      if(archive_write_set_compression_xz(this->Archive) != ARCHIVE_OK)
+      if(archive_write_add_filter_xz(this->Archive) != ARCHIVE_OK)
         {
-        this->Error = "archive_write_set_compression_xz: ";
+        this->Error = "archive_write_add_filter_xz: ";
         this->Error += cm_archive_error_string(this->Archive);
         return;
         }
@@ -176,12 +176,15 @@ cmArchiveWrite::cmArchiveWrite(
 //----------------------------------------------------------------------------
 cmArchiveWrite::~cmArchiveWrite()
 {
-  archive_read_finish(this->Disk);
-  archive_write_finish(this->Archive);
+  archive_read_free(this->Disk);
+  archive_write_free(this->Archive);
 }
 
 //----------------------------------------------------------------------------
-bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix)
+bool cmArchiveWrite::Add(std::string path,
+                         size_t skip,
+                         const char* prefix,
+                         bool recursive)
 {
   if(this->Okay())
     {
@@ -189,20 +192,21 @@ bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix)
       {
       path.erase(path.size()-1);
       }
-    this->AddPath(path.c_str(), skip, prefix);
+    this->AddPath(path.c_str(), skip, prefix, recursive);
     }
   return this->Okay();
 }
 
 //----------------------------------------------------------------------------
 bool cmArchiveWrite::AddPath(const char* path,
-                             size_t skip, const char* prefix)
+                             size_t skip, const char* prefix,
+                             bool recursive)
 {
   if(!this->AddFile(path, skip, prefix))
     {
     return false;
     }
-  if(!cmSystemTools::FileIsDirectory(path) ||
+  if((!cmSystemTools::FileIsDirectory(path) || !recursive) ||
     cmSystemTools::FileIsSymlink(path))
     {
     return true;
@@ -278,10 +282,45 @@ bool cmArchiveWrite::AddFile(const char* file,
       }
     archive_entry_set_mtime(e, t, 0);
     }
+
+  // manages the uid/guid of the entry (if any)
+  if (this->Uid.IsSet() && this->Gid.IsSet())
+    {
+    archive_entry_set_uid(e, this->Uid.Get());
+    archive_entry_set_gid(e, this->Gid.Get());
+    }
+
+  if (this->Uname.size() && this->Gname.size())
+    {
+    archive_entry_set_uname(e, this->Uname.c_str());
+    archive_entry_set_gname(e, this->Gname.c_str());
+    }
+
+
+  // manages the permissions
+  if (this->Permissions.IsSet())
+    {
+    archive_entry_set_perm(e, this->Permissions.Get());
+    }
+
+  if (this->PermissionsMask.IsSet())
+    {
+    mode_t perm = archive_entry_perm(e);
+    archive_entry_set_perm(e, perm & this->PermissionsMask.Get());
+    }
+
   // Clear acl and xattr fields not useful for distribution.
   archive_entry_acl_clear(e);
   archive_entry_xattr_clear(e);
   archive_entry_set_fflags(e, 0, 0);
+
+  if (this->Format == "pax" || this->Format == "paxr")
+    {
+    // Sparse files are a GNU tar extension.
+    // Do not use them in standard tar files.
+    archive_entry_sparse_clear(e);
+    }
+
   if(archive_write_header(this->Archive, e) != ARCHIVE_OK)
     {
     this->Error = "archive_write_header: ";
@@ -304,7 +343,7 @@ bool cmArchiveWrite::AddFile(const char* file,
 //----------------------------------------------------------------------------
 bool cmArchiveWrite::AddData(const char* file, size_t size)
 {
-  cmsys::ifstream fin(file, std::ios::in | cmsys_ios_binary);
+  cmsys::ifstream fin(file, std::ios::in | std::ios::binary);
   if(!fin)
     {
     this->Error = "Error opening \"";
@@ -318,7 +357,7 @@ bool cmArchiveWrite::AddData(const char* file, size_t size)
   size_t nleft = size;
   while(nleft > 0)
     {
-    typedef cmsys_ios::streamsize ssize_type;
+    typedef std::streamsize ssize_type;
     size_t const nnext = nleft > sizeof(buffer)? sizeof(buffer) : nleft;
     ssize_type const nnext_s = static_cast<ssize_type>(nnext);
     fin.read(buffer, nnext_s);
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index 794cb28..8dbbb83 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -18,6 +18,22 @@
 # error "cmArchiveWrite not allowed during bootstrap build!"
 #endif
 
+template<typename T>
+class cmArchiveWriteOptional
+{
+public:
+  cmArchiveWriteOptional() {this->Clear();}
+  explicit cmArchiveWriteOptional(T val) {this->Set(val);}
+
+  void Set(T val) {this->IsValueSet = true; this->Value=val;}
+  void Clear() {this->IsValueSet = false;}
+  bool IsSet() const {return this->IsValueSet;}
+  T Get() const {return Value;}
+private:
+  T Value;
+  bool IsValueSet;
+};
+
 /** \class cmArchiveWrite
  * \brief Wrapper around libarchive for writing.
  *
@@ -52,7 +68,10 @@ public:
    * skip.  The remaining part of the input path is appended to the
    * "prefix" value to construct the final name in the archive.
    */
-  bool Add(std::string path, size_t skip = 0, const char* prefix = 0);
+  bool Add(std::string path,
+     size_t skip = 0,
+     const char* prefix = 0,
+     bool recursive = true);
 
   /** Returns true if there has been no error.  */
   operator safe_bool() const
@@ -69,9 +88,65 @@ public:
   void SetVerbose(bool v) { this->Verbose = v; }
 
   void SetMTime(std::string const& t) { this->MTime = t; }
+
+  //! Sets the permissions of the added files/folders
+  void SetPermissions(mode_t permissions_)
+    {
+    this->Permissions.Set(permissions_);
+    }
+
+  //! Clears permissions - default is used instead
+  void ClearPermissions() { this->Permissions.Clear(); }
+
+  //! Sets the permissions mask of files/folders
+  //!
+  //! The permissions will be copied from the existing file
+  //! or folder. The mask will then be applied to unset
+  //! some of them
+  void SetPermissionsMask(mode_t permissionsMask_)
+    {
+    this->PermissionsMask.Set(permissionsMask_);
+    }
+
+  //! Clears permissions mask - default is used instead
+  void ClearPermissionsMask()
+    {
+    this->PermissionsMask.Clear();
+    }
+
+  //! Sets UID and GID to be used in the tar file
+  void SetUIDAndGID(int uid_, int gid_)
+    {
+    this->Uid.Set(uid_);
+    this->Gid.Set(gid_);
+    }
+
+  //! Clears UID and GID to be used in the tar file - default is used instead
+  void ClearUIDAndGID()
+    {
+    this->Uid.Clear();
+    this->Gid.Clear();
+    }
+
+  //! Sets UNAME and GNAME to be used in the tar file
+  void SetUNAMEAndGNAME(const std::string& uname_, const std::string& gname_)
+    {
+    this->Uname = uname_;
+    this->Gname = gname_;
+    }
+
+  //! Clears UNAME and GNAME to be used in the tar file
+  //! default is used instead
+  void ClearUNAMEAndGNAME()
+    {
+    this->Uname = "";
+    this->Gname = "";
+    }
+
 private:
   bool Okay() const { return this->Error.empty(); }
-  bool AddPath(const char* path, size_t skip, const char* prefix);
+  bool AddPath(const char* path, size_t skip, const char* prefix,
+               bool recursive = true);
   bool AddFile(const char* file, size_t skip, const char* prefix);
   bool AddData(const char* file, size_t size);
 
@@ -84,8 +159,25 @@ private:
   struct archive* Archive;
   struct archive* Disk;
   bool Verbose;
+  std::string Format;
   std::string Error;
   std::string MTime;
+
+  //! UID of the user in the tar file
+  cmArchiveWriteOptional<int> Uid;
+
+  //! GUID of the user in the tar file
+  cmArchiveWriteOptional<int> Gid;
+
+  //! UNAME/GNAME of the user (does not override UID/GID)
+  //!@{
+  std::string Uname;
+  std::string Gname;
+  //!@}
+
+  //! Permissions on files/folders
+  cmArchiveWriteOptional<mode_t> Permissions;
+  cmArchiveWriteOptional<mode_t> PermissionsMask;
 };
 
 #endif
diff --git a/Source/cmBuildNameCommand.h b/Source/cmBuildNameCommand.h
index 8f8038f..47455f8 100644
--- a/Source/cmBuildNameCommand.h
+++ b/Source/cmBuildNameCommand.h
@@ -23,7 +23,6 @@ public:
                            cmExecutionStatus &status);
   virtual std::string GetName() const {return "build_name";}
   virtual bool IsScriptable() const { return true; }
-  virtual bool IsDiscouraged() const { return true; }
 };
 
 
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 5234538..6ff7c0d 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -11,8 +11,6 @@
 ============================================================================*/
 #include "cmCMakeHostSystemInformationCommand.h"
 
-#include <cmsys/ios/sstream>
-
 // cmCMakeHostSystemInformation
 bool cmCMakeHostSystemInformationCommand
 ::InitialPass(std::vector<std::string> const &args, cmExecutionStatus &)
@@ -107,7 +105,7 @@ bool cmCMakeHostSystemInformationCommand
 std::string cmCMakeHostSystemInformationCommand
 ::ValueToString(size_t value) const
 {
-  cmsys_ios::stringstream tmp;
+  std::stringstream tmp;
   tmp << value;
   return tmp.str();
 }
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index 3c878bf..3ef6d35 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -93,6 +93,22 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
     this->SetError("SET failed to set policy.");
     return false;
     }
+  if(args[1] == "CMP0001" &&
+     (status == cmPolicies::WARN || status == cmPolicies::OLD))
+    {
+    if(!(this->Makefile->GetState()
+         ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
+      {
+      // Set it to 2.4 because that is the last version where the
+      // variable had meaning.
+      this->Makefile->AddCacheDefinition
+        ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
+         "For backwards compatibility, what version of CMake "
+         "commands and "
+         "syntax should this version of CMake try to support.",
+         cmState::STRING);
+      }
+    }
   return true;
 }
 
diff --git a/Source/cmCPackPropertiesGenerator.cxx b/Source/cmCPackPropertiesGenerator.cxx
index cf24c13..cbcdd81 100644
--- a/Source/cmCPackPropertiesGenerator.cxx
+++ b/Source/cmCPackPropertiesGenerator.cxx
@@ -1,13 +1,14 @@
 #include "cmCPackPropertiesGenerator.h"
 
+#include "cmOutputConverter.h"
 #include "cmLocalGenerator.h"
 
 cmCPackPropertiesGenerator::cmCPackPropertiesGenerator(
-  cmMakefile* mf,
+  cmLocalGenerator* lg,
   cmInstalledFile const& installedFile,
   std::vector<std::string> const& configurations):
     cmScriptGenerator("CPACK_BUILD_CONFIG", configurations),
-    Makefile(mf),
+    LG(lg),
     InstalledFile(installedFile)
 {
   this->ActionsPerConfig = true;
@@ -17,7 +18,8 @@ void cmCPackPropertiesGenerator::GenerateScriptForConfig(std::ostream& os,
   const std::string& config, Indent const& indent)
 {
   std::string const& expandedFileName =
-      this->InstalledFile.GetNameExpression().Evaluate(this->Makefile, config);
+      this->InstalledFile.GetNameExpression().Evaluate(this->LG->GetMakefile(),
+                                                       config);
 
   cmInstalledFile::PropertyMapType const& properties =
     this->InstalledFile.GetProperties();
@@ -29,15 +31,15 @@ void cmCPackPropertiesGenerator::GenerateScriptForConfig(std::ostream& os,
     cmInstalledFile::Property const& property = i->second;
 
     os << indent << "set_property(INSTALL " <<
-      cmLocalGenerator::EscapeForCMake(expandedFileName) << " PROPERTY " <<
-      cmLocalGenerator::EscapeForCMake(name);
+      cmOutputConverter::EscapeForCMake(expandedFileName) << " PROPERTY " <<
+      cmOutputConverter::EscapeForCMake(name);
 
     for(cmInstalledFile::ExpressionVectorType::const_iterator
       j = property.ValueExpressions.begin();
       j != property.ValueExpressions.end(); ++j)
       {
-      std::string value = (*j)->Evaluate(this->Makefile, config);
-      os << " " << cmLocalGenerator::EscapeForCMake(value);
+      std::string value = (*j)->Evaluate(LG->GetMakefile(), config);
+      os << " " << cmOutputConverter::EscapeForCMake(value);
       }
 
     os << ")\n";
diff --git a/Source/cmCPackPropertiesGenerator.h b/Source/cmCPackPropertiesGenerator.h
index 71e2eaa..eec3df0 100644
--- a/Source/cmCPackPropertiesGenerator.h
+++ b/Source/cmCPackPropertiesGenerator.h
@@ -15,6 +15,8 @@
 #include "cmScriptGenerator.h"
 #include "cmInstalledFile.h"
 
+class cmLocalGenerator;
+
 /** \class cmCPackPropertiesGenerator
  * \brief Support class for generating CPackProperties.cmake.
  *
@@ -23,7 +25,7 @@ class cmCPackPropertiesGenerator: public cmScriptGenerator
 {
 public:
   cmCPackPropertiesGenerator(
-     cmMakefile* mf,
+     cmLocalGenerator* lg,
      cmInstalledFile const& installedFile,
      std::vector<std::string> const& configurations);
 
@@ -31,7 +33,7 @@ protected:
   virtual void GenerateScriptForConfig(std::ostream& os,
     const std::string& config, Indent const& indent);
 
-  cmMakefile* Makefile;
+  cmLocalGenerator* LG;
   cmInstalledFile const& InstalledFile;
 };
 
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index c55ea35..7da334e 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -115,7 +115,9 @@ void CCONV cmAddCacheDefinition(void *arg, const char* name,
 const char* CCONV cmGetProjectName(void *arg)
 {
   cmMakefile *mf = static_cast<cmMakefile *>(arg);
-  return mf->GetProjectName();
+  static std::string name;
+  name = mf->GetProjectName();
+  return name.c_str();
 }
 
 const char* CCONV cmGetHomeDirectory(void *arg)
@@ -426,8 +428,7 @@ int CCONV cmExecuteCommand(void *arg, const char *name,
     {
     // Assume all arguments are quoted.
     lff.Arguments.push_back(
-      cmListFileArgument(args[i], cmListFileArgument::Quoted,
-                         "[CMake-Plugin]", 0));
+      cmListFileArgument(args[i], cmListFileArgument::Quoted, 0));
     }
   cmExecutionStatus status;
   return mf->ExecuteCommand(lff,status);
@@ -526,11 +527,9 @@ void * CCONV cmCreateSourceFile(void)
   return (void*)new cmCPluginAPISourceFile;
 }
 
-void * CCONV cmCreateNewSourceFile(void *arg)
+void * CCONV cmCreateNewSourceFile(void *)
 {
-  cmMakefile *mf = static_cast<cmMakefile *>(arg);
   cmCPluginAPISourceFile *sf = new cmCPluginAPISourceFile;
-  sf->Properties.SetCMakeInstance(mf->GetCMakeInstance());
   return (void*)sf;
 }
 
@@ -630,11 +629,7 @@ const char * CCONV  cmSourceFileGetProperty(void *arg,const char *prop)
       {
       return sf->FullPath.c_str();
       }
-    bool chain = false;
-    // Ignore chain because old code will not expect it and it is a
-    // pain to implement here anyway.
-    return sf->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE,
-                                           chain);
+    return sf->Properties.GetPropertyValue(prop);
     }
 }
 
@@ -662,7 +657,7 @@ void CCONV cmSourceFileSetProperty(void *arg,const char *prop,
   else if(prop)
     {
     if(!value) { value = "NOTFOUND"; }
-    sf->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
+    sf->Properties.SetProperty(prop, value);
     }
 }
 
@@ -801,8 +796,7 @@ void CCONV cmSourceFileSetName2(void *arg, const char* name, const char* dir,
   // Implement the old SetName method code here.
   if(headerFileOnly)
     {
-    sf->Properties.SetProperty("HEADER_FILE_ONLY", "1",
-                               cmProperty::SOURCE_FILE);
+    sf->Properties.SetProperty("HEADER_FILE_ONLY", "1");
     }
   sf->SourceName = name;
   std::string fname = sf->SourceName;
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 8fa19d2..6e55d89 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -293,6 +293,7 @@ cmCTest::cmCTest()
   this->LabelSummary           = true;
   this->ParallelLevel          = 1;
   this->ParallelLevelSetInCli  = false;
+  this->TestLoad               = 0;
   this->SubmitIndex            = 0;
   this->Failover               = false;
   this->BatchJobs              = false;
@@ -392,6 +393,11 @@ void cmCTest::SetParallelLevel(int level)
   this->ParallelLevel = level < 1 ? 1 : level;
 }
 
+void cmCTest::SetTestLoad(unsigned long load)
+{
+  this->TestLoad = load;
+}
+
 //----------------------------------------------------------------------------
 bool cmCTest::ShouldCompressTestOutput()
 {
@@ -513,9 +519,10 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
   cm.SetHomeDirectory("");
   cm.SetHomeOutputDirectory("");
   cmGlobalGenerator gg(&cm);
-  cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
-  cmMakefile *mf = lg->GetMakefile();
-  if ( !this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(), mf) )
+  cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+  cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator(mf.get()));
+  if ( !this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(),
+                                              mf.get()) )
     {
     cmCTestOptionalLog(this, DEBUG,
       "Cannot find custom configuration file tree" << std::endl, quiet);
@@ -819,6 +826,20 @@ bool cmCTest::UpdateCTestConfiguration()
     cmSystemTools::ChangeDirectory(this->BinaryDir);
     }
   this->TimeOut = atoi(this->GetCTestConfiguration("TimeOut").c_str());
+  std::string const& testLoad = this->GetCTestConfiguration("TestLoad");
+  if (!testLoad.empty())
+    {
+    unsigned long load;
+    if (cmSystemTools::StringToULong(testLoad.c_str(), &load))
+      {
+      this->SetTestLoad(load);
+      }
+    else
+      {
+      cmCTestLog(this, WARNING, "Invalid value for 'Test Load' : "
+          << testLoad << std::endl);
+      }
+    }
   if ( this->ProduceXML )
     {
     this->CompressXMLFiles = cmSystemTools::IsOn(
@@ -1199,7 +1220,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string& output,
 
   char* data;
   int length;
-  cmCTestLog(this, HANDLER_OUTPUT,
+  cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
     "   Each . represents " << tick_len << " bytes of output" << std::endl
     << "    " << std::flush);
   while(cmsysProcess_WaitForData(cp, &data, &length, 0))
@@ -1215,10 +1236,10 @@ int cmCTest::RunMakeCommand(const char* command, std::string& output,
     while ( output.size() > (tick * tick_len) )
       {
       tick ++;
-      cmCTestLog(this, HANDLER_OUTPUT, "." << std::flush);
+      cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, "." << std::flush);
       if ( tick % tick_line_len == 0 && tick > 0 )
         {
-        cmCTestLog(this, HANDLER_OUTPUT,
+        cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
                    "  Size: "
                    << int((double(output.size()) / 1024.0) + 1)
                    << "K" << std::endl
@@ -1231,7 +1252,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string& output,
       ofs << cmCTestLogWrite(data, length);
       }
     }
-  cmCTestLog(this, OUTPUT, " Size of output: "
+  cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, " Size of output: "
     << int(double(output.size()) / 1024.0) << "K" << std::endl);
 
   cmsysProcess_WaitForExit(cp, 0);
@@ -1523,9 +1544,8 @@ void cmCTest::StartXML(cmXMLWriter& xml, bool append)
     xml.Attribute("Append", "true");
     }
   xml.Attribute("CompilerName", this->GetCTestConfiguration("Compiler"));
-#ifdef _COMPILER_VERSION
-  xml.Attribute("CompilerVersion", _COMPILER_VERSION);
-#endif
+  xml.Attribute("CompilerVersion",
+    this->GetCTestConfiguration("CompilerVersion"));
   xml.Attribute("OSName", info.GetOSName());
   xml.Attribute("Hostname", info.GetHostname());
   xml.Attribute("OSRelease", info.GetOSRelease());
@@ -1544,6 +1564,13 @@ void cmCTest::StartXML(cmXMLWriter& xml, bool append)
   xml.Attribute("LogicalProcessorsPerPhysical",
                      info.GetLogicalProcessorsPerPhysical());
   xml.Attribute("ProcessorClockFrequency", info.GetProcessorClockFrequency());
+
+  std::string changeId = this->GetCTestConfiguration("ChangeId");
+  if(!changeId.empty())
+    {
+    xml.Attribute("ChangeId", changeId);
+    }
+
   this->AddSiteProperties(xml);
 }
 
@@ -2048,6 +2075,21 @@ bool cmCTest::HandleCommandLineArguments(size_t &i,
       }
     }
 
+  if(this->CheckArgument(arg, "--test-load") && i < args.size() - 1)
+    {
+    i++;
+    unsigned long load;
+    if (cmSystemTools::StringToULong(args[i].c_str(), &load))
+      {
+      this->SetTestLoad(load);
+      }
+    else
+      {
+      cmCTestLog(this, WARNING,
+                 "Invalid value for 'Test Load' : " << args[i] << std::endl);
+      }
+    }
+
   if(this->CheckArgument(arg, "--no-compress-output"))
     {
     this->CompressTestOutput = false;
@@ -2123,7 +2165,46 @@ bool cmCTest::HandleCommandLineArguments(size_t &i,
     {
     this->OutputTestOutputOnTestFailure = true;
     }
-
+  if (this->CheckArgument(arg, "--test-output-size-passed") &&
+      i < args.size() - 1)
+    {
+    i++;
+    long outputSize;
+    if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize))
+      {
+      if (cmCTestTestHandler *pCTestTestHandler =
+          static_cast<cmCTestTestHandler*>(this->TestingHandlers["test"]))
+        {
+        pCTestTestHandler->SetTestOutputSizePassed(int(outputSize));
+        }
+      }
+    else
+      {
+      cmCTestLog(this, WARNING,
+                 "Invalid value for '--test-output-size-passed': " <<
+                 args[i] << "\n");
+      }
+    }
+  if (this->CheckArgument(arg, "--test-output-size-failed") &&
+      i < args.size() - 1)
+    {
+    i++;
+    long outputSize;
+    if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize))
+      {
+      if (cmCTestTestHandler *pCTestTestHandler =
+          static_cast<cmCTestTestHandler*>(this->TestingHandlers["test"]))
+        {
+        pCTestTestHandler->SetTestOutputSizeFailed(int(outputSize));
+        }
+      }
+    else
+      {
+      cmCTestLog(this, WARNING,
+                 "Invalid value for '--test-output-size-failed': " <<
+                 args[i] << "\n");
+      }
+    }
   if(this->CheckArgument(arg, "-N", "--show-only"))
     {
     this->ShowOnly = true;
@@ -3063,6 +3144,7 @@ static const char* cmCTestStringLogType[] =
   "DEBUG",
   "OUTPUT",
   "HANDLER_OUTPUT",
+  "HANDLER_PROGRESS_OUTPUT",
   "HANDLER_VERBOSE_OUTPUT",
   "WARNING",
   "ERROR_MESSAGE",
@@ -3101,6 +3183,11 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg,
     {
     return;
     }
+  if ( logType == cmCTest::HANDLER_PROGRESS_OUTPUT &&
+      ( this->Debug || this->ExtraVerbose ) )
+    {
+    return;
+    }
   if ( this->OutputLogFile )
     {
     bool display = true;
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index db3ea10..73c2807 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -161,6 +161,9 @@ public:
   int GetParallelLevel() { return this->ParallelLevel; }
   void SetParallelLevel(int);
 
+  unsigned long GetTestLoad() { return this->TestLoad; }
+  void SetTestLoad(unsigned long);
+
   /**
    * Check if CTest file exists
    */
@@ -379,6 +382,7 @@ public:
     DEBUG = 0,
     OUTPUT,
     HANDLER_OUTPUT,
+    HANDLER_PROGRESS_OUTPUT,
     HANDLER_VERBOSE_OUTPUT,
     WARNING,
     ERROR_MESSAGE,
@@ -499,6 +503,8 @@ private:
   int                     ParallelLevel;
   bool                    ParallelLevelSetInCli;
 
+  unsigned long           TestLoad;
+
   int                     CompatibilityMode;
 
   // information for the --build-and-test options
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index 108208e..54209c5 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -161,7 +161,6 @@ bool cmCacheManager::LoadCache(const std::string& path,
     // Format is key:type=value
     std::string helpString;
     CacheEntry e;
-    e.Properties.SetCMakeInstance(this->CMakeInstance);
     cmSystemTools::GetLineFromStream(fin, buffer);
     realbuffer = buffer.c_str();
     while(*realbuffer != '0' &&
@@ -323,7 +322,6 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
         {
         // Create an entry and store the property.
         CacheEntry& ne = this->Cache[key];
-        ne.Properties.SetCMakeInstance(this->CMakeInstance);
         ne.Type = cmState::UNINITIALIZED;
         ne.SetProperty(*p, e.Value.c_str());
         }
@@ -645,7 +643,6 @@ void cmCacheManager::AddCacheEntry(const std::string& key,
                                    cmState::CacheEntryType type)
 {
   CacheEntry& e = this->Cache[key];
-  e.Properties.SetCMakeInstance(this->CMakeInstance);
   if ( value )
     {
     e.Value = value;
@@ -744,9 +741,7 @@ cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const
     {
     return this->Value.c_str();
     }
-  bool c = false;
-  return
-    this->Properties.GetPropertyValue(prop, cmProperty::CACHE, c);
+  return this->Properties.GetPropertyValue(prop);
 }
 
 //----------------------------------------------------------------------------
@@ -763,7 +758,7 @@ void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
     }
   else
     {
-    this->Properties.SetProperty(prop, value, cmProperty::CACHE);
+    this->Properties.SetProperty(prop, value);
     }
 }
 
@@ -789,7 +784,7 @@ void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop,
     }
   else
     {
-    this->Properties.AppendProperty(prop, value, cmProperty::CACHE, asString);
+    this->Properties.AppendProperty(prop, value, asString);
     }
 }
 
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx
index c211111..0e04838 100644
--- a/Source/cmCallVisualStudioMacro.cxx
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -498,7 +498,7 @@ int cmCallVisualStudioMacro::CallMacro(
           }
         }
 
-      if(0 == instances.size())
+      if(instances.empty())
         {
         // no instances to call
 
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
index 0548c6b..59bc396 100644
--- a/Source/cmCommand.h
+++ b/Source/cmCommand.h
@@ -102,15 +102,6 @@ public:
     }
 
   /**
-   * This determines if usage of the method is discouraged or not.
-   * This is currently only used for generating the documentation.
-   */
-  virtual bool IsDiscouraged() const
-    {
-    return false;
-    }
-
-  /**
    * This is used to avoid including this command
    * in documentation. This is mainly used by
    * cmMacroHelperCommand and cmFunctionHelperCommand
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index bd098a5..14e9e56 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -14,7 +14,7 @@
 #include "cmSystemTools.h"
 #include "cmMakefile.h"
 #include "cmState.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
 
 #include "cmCommandArgumentLexer.h"
 
@@ -141,8 +141,9 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
         {
         std::ostringstream msg;
         cmListFileContext lfc;
-        lfc.FilePath = this->Makefile->GetLocalGenerator()
-            ->Convert(this->FileName, cmLocalGenerator::HOME);
+        cmOutputConverter converter(this->Makefile->GetStateSnapshot());
+        lfc.FilePath = converter.Convert(this->FileName,
+                                         cmOutputConverter::HOME);
 
         lfc.Line = this->FileLine;
         msg << "uninitialized variable \'" << var << "\'";
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index d375ae6..387afc6 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -80,8 +80,6 @@ private:
   std::string::size_type InputBufferPos;
   std::string InputBuffer;
   std::vector<char> OutputBuffer;
-  int CurrentLine;
-  int Verbose;
 
   void Print(const char* place, const char* str);
   void SafePrintMissing(const char* str, int line, int cnt);
@@ -94,12 +92,14 @@ private:
   std::vector<char*> Variables;
   const cmMakefile* Makefile;
   std::string Result;
+  std::string ErrorString;
   const char* FileName;
+  long FileLine;
+  int CurrentLine;
+  int Verbose;
   bool WarnUninitialized;
   bool CheckSystemVars;
-  long FileLine;
   bool EscapeQuotes;
-  std::string ErrorString;
   bool NoEscapeMode;
   bool ReplaceAtSyntax;
   bool RemoveEmpty;
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
new file mode 100644
index 0000000..252e231
--- /dev/null
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -0,0 +1,431 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmCommonTargetGenerator.h"
+
+#include "cmComputeLinkInformation.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalCommonGenerator.h"
+#include "cmLocalCommonGenerator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+
+cmCommonTargetGenerator::cmCommonTargetGenerator(
+  cmOutputConverter::RelativeRoot wd,
+  cmGeneratorTarget* gt
+  )
+  : WorkingDirectory(wd)
+  , GeneratorTarget(gt)
+  , Target(gt->Target)
+  , Makefile(gt->Makefile)
+  , LocalGenerator(static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator))
+  , GlobalGenerator(static_cast<cmGlobalCommonGenerator*>(
+                      gt->LocalGenerator->GetGlobalGenerator()))
+  , ConfigName(LocalGenerator->GetConfigName())
+  , ModuleDefinitionFile(GeneratorTarget->GetModuleDefinitionFile(ConfigName))
+  , FortranModuleDirectoryComputed(false)
+{
+}
+
+cmCommonTargetGenerator::~cmCommonTargetGenerator()
+{
+}
+
+std::string const& cmCommonTargetGenerator::GetConfigName() const
+{
+  return this->ConfigName;
+}
+
+std::string cmCommonTargetGenerator::Convert(
+  std::string const& source,
+  cmLocalGenerator::RelativeRoot relative,
+  cmLocalGenerator::OutputFormat output)
+{
+  return this->LocalGenerator->Convert(source, relative, output);
+}
+
+//----------------------------------------------------------------------------
+const char* cmCommonTargetGenerator::GetFeature(const std::string& feature)
+{
+  return this->GeneratorTarget->GetFeature(feature, this->ConfigName);
+}
+
+//----------------------------------------------------------------------------
+bool cmCommonTargetGenerator::GetFeatureAsBool(const std::string& feature)
+{
+  return this->GeneratorTarget->GetFeatureAsBool(feature, this->ConfigName);
+}
+
+//----------------------------------------------------------------------------
+void cmCommonTargetGenerator::AddFeatureFlags(
+  std::string& flags, const std::string& lang
+  )
+{
+  // Add language-specific flags.
+  this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);
+
+  if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
+    {
+    this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmCommonTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
+{
+  if(this->ModuleDefinitionFile.empty())
+    {
+    return;
+    }
+
+  // TODO: Create a per-language flag variable.
+  const char* defFileFlag =
+    this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+  if(!defFileFlag)
+    {
+    return;
+    }
+
+  // Append the flag and value.  Use ConvertToLinkReference to help
+  // vs6's "cl -link" pass it to the linker.
+  std::string flag = defFileFlag;
+  flag += (this->LocalGenerator->ConvertToLinkReference(
+             this->ModuleDefinitionFile));
+  this->LocalGenerator->AppendFlags(flags, flag);
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::ComputeFortranModuleDirectory() const
+{
+  std::string mod_dir;
+  const char* target_mod_dir =
+    this->Target->GetProperty("Fortran_MODULE_DIRECTORY");
+  const char* moddir_flag =
+    this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
+  if(target_mod_dir && moddir_flag)
+    {
+    // Compute the full path to the module directory.
+    if(cmSystemTools::FileIsFullPath(target_mod_dir))
+      {
+      // Already a full path.
+      mod_dir = target_mod_dir;
+      }
+    else
+      {
+      // Interpret relative to the current output directory.
+      mod_dir = this->Makefile->GetCurrentBinaryDirectory();
+      mod_dir += "/";
+      mod_dir += target_mod_dir;
+      }
+
+    // Make sure the module output directory exists.
+    cmSystemTools::MakeDirectory(mod_dir);
+    }
+  return mod_dir;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::GetFortranModuleDirectory()
+{
+  // Compute the module directory.
+  if(!this->FortranModuleDirectoryComputed)
+    {
+    this->FortranModuleDirectoryComputed = true;
+    this->FortranModuleDirectory = this->ComputeFortranModuleDirectory();
+    }
+
+  // Return the computed directory.
+  return this->FortranModuleDirectory;
+}
+
+//----------------------------------------------------------------------------
+void cmCommonTargetGenerator::AddFortranFlags(std::string& flags)
+{
+  // Enable module output if necessary.
+  if(const char* modout_flag =
+     this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG"))
+    {
+    this->LocalGenerator->AppendFlags(flags, modout_flag);
+    }
+
+  // Add a module output directory flag if necessary.
+  std::string mod_dir = this->GetFortranModuleDirectory();
+  if (!mod_dir.empty())
+    {
+    mod_dir = this->Convert(mod_dir,
+                            this->WorkingDirectory,
+                            cmLocalGenerator::SHELL);
+    }
+  else
+    {
+    mod_dir =
+      this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
+    }
+  if (!mod_dir.empty())
+    {
+    const char* moddir_flag =
+      this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
+    std::string modflag = moddir_flag;
+    modflag += mod_dir;
+    this->LocalGenerator->AppendFlags(flags, modflag);
+    }
+
+  // If there is a separate module path flag then duplicate the
+  // include path with it.  This compiler does not search the include
+  // path for modules.
+  if(const char* modpath_flag =
+     this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG"))
+    {
+    std::vector<std::string> includes;
+    const std::string& config =
+      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+    this->LocalGenerator->GetIncludeDirectories(includes,
+                                                this->GeneratorTarget,
+                                                "C", config);
+    for(std::vector<std::string>::const_iterator idi = includes.begin();
+        idi != includes.end(); ++idi)
+      {
+      std::string flg = modpath_flag;
+      flg += this->Convert(*idi,
+                           cmLocalGenerator::NONE,
+                           cmLocalGenerator::SHELL);
+      this->LocalGenerator->AppendFlags(flags, flg);
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void
+cmCommonTargetGenerator
+::AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source)
+{
+  const char* srcfmt = source.GetProperty("Fortran_FORMAT");
+  cmLocalGenerator::FortranFormat format =
+    this->LocalGenerator->GetFortranFormat(srcfmt);
+  if(format == cmLocalGenerator::FortranFormatNone)
+    {
+    const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT");
+    format = this->LocalGenerator->GetFortranFormat(tgtfmt);
+    }
+  const char* var = 0;
+  switch (format)
+    {
+    case cmLocalGenerator::FortranFormatFixed:
+      var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break;
+    case cmLocalGenerator::FortranFormatFree:
+      var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break;
+    default: break;
+    }
+  if(var)
+    {
+    this->LocalGenerator->AppendFlags(
+      flags, this->Makefile->GetDefinition(var));
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::GetFrameworkFlags(std::string const& l)
+{
+ if(!this->Makefile->IsOn("APPLE"))
+   {
+   return std::string();
+   }
+
+  std::string fwSearchFlagVar = "CMAKE_" + l + "_FRAMEWORK_SEARCH_FLAG";
+  const char* fwSearchFlag =
+    this->Makefile->GetDefinition(fwSearchFlagVar);
+  if(!(fwSearchFlag && *fwSearchFlag))
+    {
+    return std::string();
+    }
+
+ std::set<std::string> emitted;
+#ifdef __APPLE__  /* don't insert this when crosscompiling e.g. to iphone */
+  emitted.insert("/System/Library/Frameworks");
+#endif
+  std::vector<std::string> includes;
+
+  const std::string& config =
+    this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+  this->LocalGenerator->GetIncludeDirectories(includes,
+                                              this->GeneratorTarget,
+                                              "C", config);
+  // check all include directories for frameworks as this
+  // will already have added a -F for the framework
+  for(std::vector<std::string>::iterator i = includes.begin();
+      i != includes.end(); ++i)
+    {
+    if(this->Target->NameResolvesToFramework(*i))
+      {
+      std::string frameworkDir = *i;
+      frameworkDir += "/../";
+      frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
+      emitted.insert(frameworkDir);
+      }
+    }
+
+  std::string flags;
+  const char* cfg = this->LocalGenerator->GetConfigName().c_str();
+  if(cmComputeLinkInformation* cli =
+     this->GeneratorTarget->GetLinkInformation(cfg))
+    {
+    std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
+    for(std::vector<std::string>::const_iterator i = frameworks.begin();
+        i != frameworks.end(); ++i)
+      {
+      if(emitted.insert(*i).second)
+        {
+        flags += fwSearchFlag;
+        flags += this->LocalGenerator
+                     ->ConvertToOutputFormat(*i, cmLocalGenerator::SHELL);
+        flags += " ";
+        }
+      }
+    }
+  return flags;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::GetFlags(const std::string &l)
+{
+  ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
+  if (i == this->FlagsByLanguage.end())
+    {
+    std::string flags;
+    const char *lang = l.c_str();
+
+    // Add language feature flags.
+    this->AddFeatureFlags(flags, lang);
+
+    this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
+                                               lang, this->ConfigName);
+
+    // Fortran-specific flags computed for this target.
+    if(l == "Fortran")
+      {
+      this->AddFortranFlags(flags);
+      }
+
+    this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
+                                          lang, this->ConfigName);
+
+    this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target,
+                                                   lang);
+
+    // Append old-style preprocessor definition flags.
+    this->LocalGenerator->
+      AppendFlags(flags, this->Makefile->GetDefineFlags());
+
+    // Add framework directory flags.
+    this->LocalGenerator->
+      AppendFlags(flags,this->GetFrameworkFlags(l));
+
+    // Add target-specific flags.
+    this->LocalGenerator->AddCompileOptions(flags, this->Target,
+                                            lang, this->ConfigName);
+
+    ByLanguageMap::value_type entry(l, flags);
+    i = this->FlagsByLanguage.insert(entry).first;
+    }
+  return i->second;
+}
+
+std::string cmCommonTargetGenerator::GetDefines(const std::string &l)
+{
+  ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
+  if (i == this->DefinesByLanguage.end())
+    {
+    std::set<std::string> defines;
+    const char *lang = l.c_str();
+    // Add the export symbol definition for shared library objects.
+    if(const char* exportMacro = this->Target->GetExportMacro())
+      {
+      this->LocalGenerator->AppendDefines(defines, exportMacro);
+      }
+
+    // Add preprocessor definitions for this target and configuration.
+    this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
+                            this->LocalGenerator->GetConfigName(), l);
+
+    std::string definesString;
+    this->LocalGenerator->JoinDefines(defines, definesString, lang);
+
+    ByLanguageMap::value_type entry(l, definesString);
+    i = this->DefinesByLanguage.insert(entry).first;
+    }
+  return i->second;
+}
+
+std::string cmCommonTargetGenerator::GetIncludes(std::string const& l)
+{
+  ByLanguageMap::iterator i = this->IncludesByLanguage.find(l);
+  if (i == this->IncludesByLanguage.end())
+    {
+    std::string includes;
+    this->AddIncludeFlags(includes, l);
+    ByLanguageMap::value_type entry(l, includes);
+    i = this->IncludesByLanguage.insert(entry).first;
+    }
+  return i->second;
+}
+
+std::vector<std::string>
+cmCommonTargetGenerator::GetLinkedTargetDirectories() const
+{
+  std::vector<std::string> dirs;
+  std::set<cmTarget const*> emitted;
+  if (cmComputeLinkInformation* cli =
+      this->GeneratorTarget->GetLinkInformation(this->ConfigName))
+    {
+    cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
+    for(cmComputeLinkInformation::ItemVector::const_iterator
+          i = items.begin(); i != items.end(); ++i)
+      {
+      cmTarget const* linkee = i->Target;
+      if(linkee && !linkee->IsImported()
+                // We can ignore the INTERFACE_LIBRARY items because
+                // Target->GetLinkInformation already processed their
+                // link interface and they don't have any output themselves.
+                && linkee->GetType() != cmTarget::INTERFACE_LIBRARY
+                && emitted.insert(linkee).second)
+        {
+        cmGeneratorTarget* gt =
+          this->GlobalGenerator->GetGeneratorTarget(linkee);
+        cmLocalGenerator* lg = gt->GetLocalGenerator();
+        cmMakefile* mf = linkee->GetMakefile();
+        std::string di = mf->GetCurrentBinaryDirectory();
+        di += "/";
+        di += lg->GetTargetDirectory(*linkee);
+        dirs.push_back(di);
+        }
+      }
+    }
+  return dirs;
+}
+
+std::string cmCommonTargetGenerator::GetManifests()
+{
+  std::vector<cmSourceFile const*> manifest_srcs;
+  this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+
+  std::vector<std::string> manifests;
+  for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin();
+       mi != manifest_srcs.end(); ++mi)
+    {
+    manifests.push_back(this->Convert((*mi)->GetFullPath(),
+                                      this->WorkingDirectory,
+                                      cmOutputConverter::SHELL));
+    }
+
+  return cmJoin(manifests, " ");
+}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
new file mode 100644
index 0000000..a4b2c10
--- /dev/null
+++ b/Source/cmCommonTargetGenerator.h
@@ -0,0 +1,96 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmCommonTargetGenerator_h
+#define cmCommonTargetGenerator_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmLocalGenerator.h"
+
+class cmGeneratorTarget;
+class cmGlobalCommonGenerator;
+class cmLocalCommonGenerator;
+class cmMakefile;
+class cmSourceFile;
+class cmTarget;
+
+/** \class cmCommonTargetGenerator
+ * \brief Common infrastructure for Makefile and Ninja per-target generators
+ */
+class cmCommonTargetGenerator
+{
+public:
+  cmCommonTargetGenerator(cmOutputConverter::RelativeRoot wd,
+                          cmGeneratorTarget* gt);
+  virtual ~cmCommonTargetGenerator();
+
+  std::string const& GetConfigName() const;
+
+protected:
+
+  // Add language feature flags.
+  void AddFeatureFlags(std::string& flags, const std::string& lang);
+
+  // Feature query methods.
+  const char* GetFeature(const std::string& feature);
+  bool GetFeatureAsBool(const std::string& feature);
+
+  // Helper to add flag for windows .def file.
+  void AddModuleDefinitionFlag(std::string& flags);
+
+  cmOutputConverter::RelativeRoot WorkingDirectory;
+  cmGeneratorTarget* GeneratorTarget;
+  cmTarget* Target;
+  cmMakefile* Makefile;
+  cmLocalCommonGenerator* LocalGenerator;
+  cmGlobalCommonGenerator* GlobalGenerator;
+  std::string ConfigName;
+
+  // The windows module definition source file (.def), if any.
+  std::string ModuleDefinitionFile;
+
+  // Target-wide Fortran module output directory.
+  bool FortranModuleDirectoryComputed;
+  std::string FortranModuleDirectory;
+  std::string GetFortranModuleDirectory();
+  virtual std::string ComputeFortranModuleDirectory() const;
+
+  // Compute target-specific Fortran language flags.
+  void AddFortranFlags(std::string& flags);
+
+  std::string Convert(std::string const& source,
+                      cmLocalGenerator::RelativeRoot relative,
+                      cmLocalGenerator::OutputFormat output =
+                      cmLocalGenerator::UNCHANGED);
+
+  void AppendFortranFormatFlags(std::string& flags,
+                                cmSourceFile const& source);
+
+  // Return the a string with -F flags on apple
+  std::string GetFrameworkFlags(std::string const& l);
+
+  virtual void AddIncludeFlags(std::string& flags,
+                               std::string const& lang) = 0;
+
+  typedef std::map<std::string, std::string> ByLanguageMap;
+  std::string GetFlags(const std::string &l);
+  ByLanguageMap FlagsByLanguage;
+  std::string GetDefines(const std::string &l);
+  ByLanguageMap DefinesByLanguage;
+  std::string GetIncludes(std::string const& l);
+  ByLanguageMap IncludesByLanguage;
+  std::string GetManifests();
+
+  std::vector<std::string> GetLinkedTargetDirectories() const;
+};
+
+#endif
diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h
index a2ce946..4dbac4a 100644
--- a/Source/cmComputeComponentGraph.h
+++ b/Source/cmComputeComponentGraph.h
@@ -67,17 +67,17 @@ private:
     int Root;
     int VisitIndex;
   };
-  int TarjanWalkId;
   std::vector<int> TarjanVisited;
   std::vector<int> TarjanComponents;
   std::vector<TarjanEntry> TarjanEntries;
+  std::vector<NodeList> Components;
   std::stack<int> TarjanStack;
+  int TarjanWalkId;
   int TarjanIndex;
   void Tarjan();
   void TarjanVisit(int i);
 
   // Connected components.
-  std::vector<NodeList> Components;
 };
 
 #endif
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index abd9877..1b5c9f4 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -12,14 +12,13 @@
 #include "cmComputeLinkDepends.h"
 
 #include "cmComputeComponentGraph.h"
+#include "cmLocalGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmTarget.h"
 #include "cmake.h"
 #include "cmAlgorithms.h"
 
-#include <cmsys/stl/algorithm>
-
 #include <assert.h>
 
 /*
@@ -173,18 +172,20 @@ items that we know the linker will re-use automatically (shared libs).
 
 //----------------------------------------------------------------------------
 cmComputeLinkDepends
-::cmComputeLinkDepends(cmTarget const* target, const std::string& config)
+::cmComputeLinkDepends(const cmGeneratorTarget* target,
+                       const std::string& config)
 {
   // Store context information.
   this->Target = target;
-  this->Makefile = this->Target->GetMakefile();
-  this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
+  this->Makefile = this->Target->Target->GetMakefile();
+  this->GlobalGenerator =
+      this->Target->GetLocalGenerator()->GetGlobalGenerator();
   this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
 
   // The configuration being linked.
   this->HasConfig = !config.empty();
   this->Config = (this->HasConfig)? config : std::string();
-  this->LinkType = this->Target->ComputeLinkType(this->Config);
+  this->LinkType = this->Target->Target->ComputeLinkType(this->Config);
 
   // Enable debug mode if requested.
   this->DebugMode = this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE");
@@ -361,9 +362,11 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
   // Follow the item's dependencies.
   if(entry.Target)
     {
+    cmGeneratorTarget* gtgt =
+        this->GlobalGenerator->GetGeneratorTarget(entry.Target);
     // Follow the target dependencies.
-    if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config, this->Target))
+    if(cmLinkInterface const* iface =
+       gtgt->GetLinkInterface(this->Config, this->Target->Target))
       {
       const bool isIface =
                       entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
@@ -397,7 +400,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
 //----------------------------------------------------------------------------
 void
 cmComputeLinkDepends
-::FollowSharedDeps(int depender_index, cmTarget::LinkInterface const* iface,
+::FollowSharedDeps(int depender_index, cmLinkInterface const* iface,
                    bool follow_interface)
 {
   // Follow dependencies if we have not followed them already.
@@ -460,8 +463,10 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
   // Target items may have their own dependencies.
   if(entry.Target)
     {
-    if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config, this->Target))
+    cmGeneratorTarget* gtgt =
+        this->GlobalGenerator->GetGeneratorTarget(entry.Target);
+    if(cmLinkInterface const* iface =
+       gtgt->GetLinkInterface(this->Config, this->Target->Target))
       {
       // Follow public and private dependencies transitively.
       this->FollowSharedDeps(index, iface, true);
@@ -551,7 +556,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
 void cmComputeLinkDepends::AddDirectLinkEntries()
 {
   // Add direct link dependencies in this configuration.
-  cmTarget::LinkImplementation const* impl =
+  cmLinkImplementation const* impl =
     this->Target->GetLinkImplementation(this->Config);
   this->AddLinkEntries(-1, impl->Libraries);
   for(std::vector<cmLinkItem>::const_iterator
@@ -634,7 +639,7 @@ cmTarget const* cmComputeLinkDepends::FindTargetToLink(int depender_index,
                                                  const std::string& name)
 {
   // Look for a target in the scope of the depender.
-  cmTarget const* from = this->Target;
+  cmTarget const* from = this->Target->Target;
   if(depender_index >= 0)
     {
     if(cmTarget const* depender = this->EntryList[depender_index].Target)
@@ -931,8 +936,10 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
     {
     if(cmTarget const* target = this->EntryList[*ni].Target)
       {
-      if(cmTarget::LinkInterface const* iface =
-         target->GetLinkInterface(this->Config, this->Target))
+      cmGeneratorTarget* gtgt =
+          this->GlobalGenerator->GetGeneratorTarget(target);
+      if(cmLinkInterface const* iface =
+         gtgt->GetLinkInterface(this->Config, this->Target->Target))
         {
         if(iface->Multiplicity > count)
           {
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 09b9d70..2cbb430 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -22,6 +22,7 @@
 class cmComputeComponentGraph;
 class cmGlobalGenerator;
 class cmMakefile;
+class cmGeneratorTarget;
 class cmTarget;
 class cmake;
 
@@ -31,7 +32,8 @@ class cmake;
 class cmComputeLinkDepends
 {
 public:
-  cmComputeLinkDepends(cmTarget const* target, const std::string& config);
+  cmComputeLinkDepends(cmGeneratorTarget const* target,
+                       const std::string& config);
   ~cmComputeLinkDepends();
 
   // Basic information about each link item.
@@ -57,18 +59,11 @@ public:
 private:
 
   // Context information.
-  cmTarget const* Target;
+  cmGeneratorTarget const* Target;
   cmMakefile* Makefile;
   cmGlobalGenerator const* GlobalGenerator;
   cmake* CMakeInstance;
-  bool DebugMode;
-
-  // Configuration information.
-  bool HasConfig;
   std::string Config;
-  cmTarget::LinkLibraryType LinkType;
-
-  // Output information.
   EntryVector FinalLinkEntries;
 
   typedef cmTarget::LinkLibraryVectorType LinkLibraryVectorType;
@@ -107,7 +102,7 @@ private:
   std::queue<SharedDepEntry> SharedDepQueue;
   std::set<int> SharedDepFollowed;
   void FollowSharedDeps(int depender_index,
-                        cmTarget::LinkInterface const* iface,
+                        cmLinkInterface const* iface,
                         bool follow_interface = false);
   void QueueSharedDependencies(int depender_index,
                                std::vector<cmLinkItem> const& deps);
@@ -131,7 +126,7 @@ private:
   void OrderLinkEntires();
   std::vector<char> ComponentVisited;
   std::vector<int> ComponentOrder;
-  int ComponentOrderId;
+
   struct PendingComponent
   {
     // The real component id.  Needed because the map is indexed by
@@ -158,11 +153,14 @@ private:
 
   // Record of the original link line.
   std::vector<int> OriginalEntries;
+  std::set<cmTarget const*> OldWrongConfigItems;
+  void CheckWrongConfigItem(cmLinkItem const& item);
 
-  // Compatibility help.
+  int ComponentOrderId;
+  cmTarget::LinkLibraryType LinkType;
+  bool HasConfig;
+  bool DebugMode;
   bool OldLinkDirMode;
-  void CheckWrongConfigItem(cmLinkItem const& item);
-  std::set<cmTarget const*> OldWrongConfigItems;
 };
 
 #endif
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index e6cbe60..d35b566 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -14,11 +14,13 @@
 #include "cmComputeLinkDepends.h"
 #include "cmOrderDirectories.h"
 
+#include "cmLocalGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmState.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
 #include "cmMakefile.h"
 #include "cmTarget.h"
+#include "cmGeneratorTarget.h"
 #include "cmake.h"
 #include "cmAlgorithms.h"
 
@@ -241,13 +243,14 @@ because this need be done only for shared libraries without soname-s.
 
 //----------------------------------------------------------------------------
 cmComputeLinkInformation
-::cmComputeLinkInformation(cmTarget const* target, const std::string& config)
+::cmComputeLinkInformation(const cmGeneratorTarget* target,
+                           const std::string& config)
 {
   // Store context information.
   this->Target = target;
-  this->Makefile = this->Target->GetMakefile();
-  this->LocalGenerator = this->Makefile->GetLocalGenerator();
-  this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
+  this->Makefile = this->Target->Target->GetMakefile();
+  this->GlobalGenerator =
+      this->Target->GetLocalGenerator()->GetGlobalGenerator();
   this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
 
   // Check whether to recognize OpenBSD-style library versioned names.
@@ -281,14 +284,14 @@ cmComputeLinkInformation
 
   // Check whether we should skip dependencies on shared library files.
   this->LinkDependsNoShared =
-    this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");
+    this->Target->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");
 
   // On platforms without import libraries there may be a special flag
   // to use when creating a plugin (module) that obtains symbols from
   // the program that will load it.
   this->LoaderFlag = 0;
   if(!this->UseImportLibrary &&
-     this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+     this->Target->Target->GetType() == cmTarget::MODULE_LIBRARY)
     {
     std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
     loader_flag_var += this->LinkLanguage;
@@ -306,10 +309,10 @@ cmComputeLinkInformation
 
   // Get options needed to specify RPATHs.
   this->RuntimeUseChrpath = false;
-  if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+  if(this->Target->Target->GetType() != cmTarget::STATIC_LIBRARY)
     {
     const char* tType =
-      ((this->Target->GetType() == cmTarget::EXECUTABLE)?
+      ((this->Target->Target->GetType() == cmTarget::EXECUTABLE)?
        "EXECUTABLE" : "SHARED_LIBRARY");
     std::string rtVar = "CMAKE_";
     rtVar += tType;
@@ -322,6 +325,7 @@ cmComputeLinkInformation
     this->RuntimeAlways =
       (this->Makefile->
        GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
+
     this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config);
 
     // Get options needed to help find dependent libraries.
@@ -374,9 +378,9 @@ cmComputeLinkInformation
 
   // Add the search path entries requested by the user to path ordering.
   this->OrderLinkerSearchPath
-    ->AddUserDirectories(this->Target->GetLinkDirectories());
+    ->AddUserDirectories(this->Target->Target->GetLinkDirectories());
   this->OrderRuntimeSearchPath
-    ->AddUserDirectories(this->Target->GetLinkDirectories());
+    ->AddUserDirectories(this->Target->Target->GetLinkDirectories());
 
   // Set up the implicit link directories.
   this->LoadImplicitLinkInfo();
@@ -404,12 +408,13 @@ cmComputeLinkInformation
   // order to support such projects we need to add the directories
   // containing libraries linked with a full path to the -L path.
   this->OldLinkDirMode =
-    this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
+    this->Target->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
   if(this->OldLinkDirMode)
     {
     // Construct a mask to not bother with this behavior for link
     // directories already specified by the user.
-    std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
+    std::vector<std::string> const& dirs =
+        this->Target->Target->GetLinkDirectories();
     this->OldLinkDirMask.insert(dirs.begin(), dirs.end());
     }
 
@@ -515,7 +520,8 @@ bool cmComputeLinkInformation::Compute()
 
   // Restore the target link type so the correct system runtime
   // libraries are found.
-  const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
+  const char* lss =
+      this->Target->Target->GetProperty("LINK_SEARCH_END_STATIC");
   if(cmSystemTools::IsOn(lss))
     {
     this->SetCurrentLinkType(LinkStatic);
@@ -536,10 +542,11 @@ bool cmComputeLinkInformation::Compute()
         i != wrongItems.end(); ++i)
       {
       cmTarget const* tgt = *i;
+      cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
       bool implib =
         (this->UseImportLibrary &&
          (tgt->GetType() == cmTarget::SHARED_LIBRARY));
-      std::string lib = tgt->GetFullPath(this->Config , implib, true);
+      std::string lib = gtgt->GetFullPath(this->Config , implib, true);
       this->OldLinkDirItems.push_back(lib);
       }
     }
@@ -565,7 +572,7 @@ bool cmComputeLinkInformation::Compute()
       "name."
       ;
     this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
-                                      this->Target->GetBacktrace());
+                                      this->Target->Target->GetBacktrace());
     }
 
   return true;
@@ -575,7 +582,8 @@ bool cmComputeLinkInformation::Compute()
 void cmComputeLinkInformation::AddImplicitLinkInfo()
 {
   // The link closure lists all languages whose implicit info is needed.
-  cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config);
+  cmGeneratorTarget::LinkClosure const* lc =
+      this->Target->GetLinkClosure(this->Config);
   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
       li != lc->Languages.end(); ++li)
     {
@@ -638,6 +646,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
 
   if(tgt && tgt->IsLinkable())
     {
+    cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
     // This is a CMake target.  Ask the target for its real name.
     if(impexe && this->LoaderFlag)
       {
@@ -646,7 +655,8 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
       // platform.  Add it now.
       std::string linkItem;
       linkItem = this->LoaderFlag;
-      std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
+
+      std::string exe = gtgt->GetFullPath(config, this->UseImportLibrary,
                                          true);
       linkItem += exe;
       this->Items.push_back(Item(linkItem, true, tgt));
@@ -667,7 +677,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
          (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
 
       // Pass the full path to the target file.
-      std::string lib = tgt->GetFullPath(config, implib, true);
+      std::string lib = gtgt->GetFullPath(config, implib, true);
       if(!this->LinkDependsNoShared ||
          tgt->GetType() != cmTarget::SHARED_LIBRARY)
         {
@@ -750,13 +760,17 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
     return;
     }
 
+  cmGeneratorTarget *gtgt = 0;
+
   // Get a full path to the dependent shared library.
   // Add it to the runtime path computation so that the target being
   // linked will be able to find it.
   std::string lib;
   if(tgt)
     {
-    lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
+    gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
+
+    lib = gtgt->GetFullPath(this->Config, this->UseImportLibrary);
     this->AddLibraryRuntimeInfo(lib, tgt);
     }
   else
@@ -781,9 +795,9 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
     }
   if(order)
     {
-    if(tgt)
+    if(gtgt)
       {
-      std::string soName = tgt->GetSOName(this->Config);
+      std::string soName = gtgt->GetSOName(this->Config);
       const char* soname = soName.empty()? 0 : soName.c_str();
       order->AddRuntimeLibrary(lib, soname);
       }
@@ -845,7 +859,8 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
     }
 
   // Lookup the starting link type from the target (linked statically?).
-  const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
+  const char* lss =
+      this->Target->Target->GetProperty("LINK_SEARCH_START_STATIC");
   this->StartLinkType = cmSystemTools::IsOn(lss)? LinkStatic : LinkShared;
   this->CurrentLinkType = this->StartLinkType;
 }
@@ -1131,7 +1146,7 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item)
   // Full path libraries should specify a valid library file name.
   // See documentation of CMP0008.
   std::string generator = this->GlobalGenerator->GetName();
-  if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
+  if(this->Target->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
      (generator.find("Visual Studio") != generator.npos ||
       generator.find("Xcode") != generator.npos))
     {
@@ -1212,7 +1227,7 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
     }
 
   // Check the policy for whether we should use the approach below.
-  switch (this->Target->GetPolicyStatusCMP0060())
+  switch (this->Target->Target->GetPolicyStatusCMP0060())
     {
     case cmPolicies::WARN:
       if (this->CMP0060Warn)
@@ -1395,7 +1410,8 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
 
   // Add the item using the -framework option.
   this->Items.push_back(Item("-framework", false));
-  fw = this->LocalGenerator->EscapeForShell(fw);
+  cmOutputConverter converter(this->Makefile->GetStateSnapshot());
+  fw = converter.EscapeForShell(fw);
   this->Items.push_back(Item(fw, false));
 }
 
@@ -1521,7 +1537,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
   this->OrderLinkerSearchPath->AddLinkLibrary(item);
 
   // Produce any needed message.
-  switch(this->Target->GetPolicyStatusCMP0008())
+  switch(this->Target->Target->GetPolicyStatusCMP0008())
     {
     case cmPolicies::WARN:
       {
@@ -1538,7 +1554,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
           << "  " << item << "\n"
           << "which is a full-path but not a valid library file name.";
         this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
-                                          this->Target->GetBacktrace());
+                                        this->Target->Target->GetBacktrace());
         }
       }
     case cmPolicies::OLD:
@@ -1556,7 +1572,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
           << "  " << item << "\n"
           << "which is a full-path but not a valid library file name.";
       this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
-                                        this->Target->GetBacktrace());
+                                        this->Target->Target->GetBacktrace());
       }
       break;
     }
@@ -1573,7 +1589,7 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
     }
 
   // Enforce policy constraints.
-  switch(this->Target->GetPolicyStatusCMP0003())
+  switch(this->Target->Target->GetPolicyStatusCMP0003())
     {
     case cmPolicies::WARN:
       if(!this->CMakeInstance->GetState()
@@ -1584,7 +1600,7 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
         std::ostringstream w;
         this->PrintLinkPolicyDiagnosis(w);
         this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
-                                          this->Target->GetBacktrace());
+                                        this->Target->Target->GetBacktrace());
         }
     case cmPolicies::OLD:
       // OLD behavior is to add the paths containing libraries with
@@ -1600,7 +1616,7 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
       e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0003) << "\n";
       this->PrintLinkPolicyDiagnosis(e);
       this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
-                                        this->Target->GetBacktrace());
+                                        this->Target->Target->GetBacktrace());
       return false;
       }
     }
@@ -1794,7 +1810,8 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
 
   // Try to get the soname of the library.  Only files with this name
   // could possibly conflict.
-  std::string soName = target->GetSOName(this->Config);
+  cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
+  std::string soName = gtgt->GetSOName(this->Config);
   const char* soname = soName.empty()? 0 : soName.c_str();
 
   // Include this library in the runtime path ordering.
@@ -1901,9 +1918,9 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
   // build tree.
   bool linking_for_install =
     (for_install ||
-     this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
+     this->Target->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
   bool use_install_rpath =
-    (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
+    (outputRuntime && this->Target->Target->HaveInstallTreeRPATH() &&
      linking_for_install);
   bool use_build_rpath =
     (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
@@ -1911,13 +1928,14 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
   bool use_link_rpath =
     outputRuntime && linking_for_install &&
     !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") &&
-    this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
+    this->Target->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
 
   // Construct the RPATH.
   std::set<std::string> emitted;
   if(use_install_rpath)
     {
-    const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
+    const char* install_rpath =
+        this->Target->Target->GetProperty("INSTALL_RPATH");
     cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
     }
   if(use_build_rpath || use_link_rpath)
@@ -1989,7 +2007,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
   // Add runtime paths required by the languages to always be
   // present.  This is done even when skipping rpath support.
   {
-  cmTarget::LinkClosure const* lc =
+  cmGeneratorTarget::LinkClosure const* lc =
     this->Target->GetLinkClosure(this->Config);
   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
       li != lc->Languages.end(); ++li)
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 8847141..8b83574 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -18,9 +18,9 @@
 
 class cmake;
 class cmGlobalGenerator;
-class cmLocalGenerator;
 class cmMakefile;
 class cmTarget;
+class cmGeneratorTarget;
 class cmOrderDirectories;
 
 /** \class cmComputeLinkInformation
@@ -29,7 +29,8 @@ class cmOrderDirectories;
 class cmComputeLinkInformation
 {
 public:
-  cmComputeLinkInformation(cmTarget const* target, const std::string& config);
+  cmComputeLinkInformation(cmGeneratorTarget const* target,
+                           const std::string& config);
   ~cmComputeLinkInformation();
   bool Compute();
 
@@ -73,16 +74,14 @@ private:
   std::set<cmTarget const*> SharedLibrariesLinked;
 
   // Context information.
-  cmTarget const* Target;
+  cmGeneratorTarget const* Target;
   cmMakefile* Makefile;
-  cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator* GlobalGenerator;
   cmake* CMakeInstance;
 
   // Configuration information.
   std::string Config;
   std::string LinkLanguage;
-  bool LinkDependsNoShared;
 
   // Modes for dealing with dependent shared libraries.
   enum SharedDepMode
@@ -93,8 +92,6 @@ private:
     SharedDepModeLink    // List file on link line
   };
 
-  // System info.
-  bool UseImportLibrary;
   const char* LoaderFlag;
   std::string LibLinkFlag;
   std::string LibLinkFileFlag;
@@ -102,22 +99,18 @@ private:
   std::string RuntimeFlag;
   std::string RuntimeSep;
   std::string RuntimeAlways;
-  bool RuntimeUseChrpath;
-  bool NoSONameUsesPath;
-  bool LinkWithRuntimePath;
   std::string RPathLinkFlag;
   SharedDepMode SharedDependencyMode;
 
+  enum LinkType { LinkUnknown, LinkStatic, LinkShared };
+  void SetCurrentLinkType(LinkType lt);
+
   // Link type adjustment.
   void ComputeLinkTypeInfo();
-  enum LinkType { LinkUnknown, LinkStatic, LinkShared };
   LinkType StartLinkType;
   LinkType CurrentLinkType;
   std::string StaticLinkTypeFlag;
   std::string SharedLinkTypeFlag;
-  bool LinkTypeEnabled;
-  void SetCurrentLinkType(LinkType lt);
-  bool ArchivesMayBeShared;
 
   // Link item parsing.
   void ComputeItemParserInfo();
@@ -129,7 +122,6 @@ private:
   cmsys::RegularExpression ExtractSharedLibraryName;
   cmsys::RegularExpression ExtractAnyLibraryName;
   std::string SharedRegexString;
-  bool OpenBSD;
   void AddLinkPrefix(const char* p);
   void AddLinkExtension(const char* e, LinkType type);
   std::string CreateExtensionRegex(std::vector<std::string> const& exts,
@@ -173,20 +165,27 @@ private:
   std::set<std::string> OldLinkDirMask;
   std::vector<std::string> OldLinkDirItems;
   std::vector<std::string> OldUserFlagItems;
-  bool OldLinkDirMode;
-
-  // CMP0060 warnings.
-  bool CMP0060Warn;
   std::set<std::string> CMP0060WarnItems;
-
+  // Dependent library path computation.
+  cmOrderDirectories* OrderDependentRPath;
   // Runtime path computation.
   cmOrderDirectories* OrderRuntimeSearchPath;
+
+  bool OldLinkDirMode;
+  bool OpenBSD;
+  bool LinkDependsNoShared;
+  bool UseImportLibrary;
+  bool RuntimeUseChrpath;
+  bool NoSONameUsesPath;
+  bool LinkWithRuntimePath;
+  bool LinkTypeEnabled;
+  bool ArchivesMayBeShared;
+  bool CMP0060Warn;
+
   void AddLibraryRuntimeInfo(std::string const& fullPath,
                              cmTarget const* target);
   void AddLibraryRuntimeInfo(std::string const& fullPath);
 
-  // Dependent library path computation.
-  cmOrderDirectories* OrderDependentRPath;
 };
 
 #endif
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 87b47b4..9e37c35 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -147,12 +147,12 @@ bool cmComputeTargetDepends::Compute()
 
 //----------------------------------------------------------------------------
 void
-cmComputeTargetDepends::GetTargetDirectDepends(cmTarget const* t,
+cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
                                                cmTargetDependSet& deps)
 {
   // Lookup the index for this target.  All targets should be known by
   // this point.
-  std::map<cmTarget const*, int>::const_iterator tii
+  std::map<cmGeneratorTarget const*, int>::const_iterator tii
                                                   = this->TargetIndex.find(t);
   assert(tii != this->TargetIndex.end());
   int i = tii->second;
@@ -161,7 +161,7 @@ cmComputeTargetDepends::GetTargetDirectDepends(cmTarget const* t,
   EdgeList const& nl = this->FinalGraph[i];
   for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
     {
-    cmTarget const* dep = this->Targets[*ni];
+    cmGeneratorTarget const* dep = this->Targets[*ni];
     cmTargetDependSet::iterator di = deps.insert(dep).first;
     di->SetType(ni->IsStrong());
     }
@@ -180,9 +180,11 @@ void cmComputeTargetDepends::CollectTargets()
         ti != targets.end(); ++ti)
       {
       cmTarget const* target = &ti->second;
+      cmGeneratorTarget* gt =
+          this->GlobalGenerator->GetGeneratorTarget(target);
       int index = static_cast<int>(this->Targets.size());
-      this->TargetIndex[target] = index;
-      this->Targets.push_back(target);
+      this->TargetIndex[gt] = index;
+      this->Targets.push_back(gt);
       }
     }
 }
@@ -204,7 +206,7 @@ void cmComputeTargetDepends::CollectDepends()
 void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
 {
   // Get the depender.
-  cmTarget const* depender = this->Targets[depender_index];
+  cmGeneratorTarget const* depender = this->Targets[depender_index];
   if (depender->GetType() == cmTarget::INTERFACE_LIBRARY)
     {
     return;
@@ -216,10 +218,9 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
   // deal with config-specific dependencies.
   {
   std::set<std::string> emitted;
-  cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(depender);
 
   std::vector<std::string> configs;
-  depender->GetMakefile()->GetConfigurations(configs);
+  depender->Makefile->GetConfigurations(configs);
   if (configs.empty())
     {
     configs.push_back("");
@@ -228,7 +229,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
     it != configs.end(); ++it)
     {
     std::vector<cmSourceFile const*> objectFiles;
-    gt->GetExternalObjects(objectFiles, *it);
+    depender->GetExternalObjects(objectFiles, *it);
     for(std::vector<cmSourceFile const*>::const_iterator
         oi = objectFiles.begin(); oi != objectFiles.end(); ++oi)
       {
@@ -244,15 +245,14 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
             ->IssueMessage(cmake::FATAL_ERROR,
                             "Only executables and non-OBJECT libraries may "
                             "reference target objects.",
-                            depender->GetBacktrace());
+                            depender->Target->GetBacktrace());
           return;
           }
-        const_cast<cmTarget*>(depender)->AddUtility(objLib);
+        const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility(objLib);
         }
       }
 
-    cmTarget::LinkImplementation const* impl =
-      depender->GetLinkImplementation(*it);
+    cmLinkImplementation const* impl = depender->GetLinkImplementation(*it);
 
     // A target should not depend on itself.
     emitted.insert(depender->GetName());
@@ -272,7 +272,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
 
   // Loop over all utility dependencies.
   {
-  std::set<cmLinkItem> const& tutils = depender->GetUtilityItems();
+  std::set<cmLinkItem> const& tutils = depender->Target->GetUtilityItems();
   std::set<std::string> emitted;
   // A target should not depend on itself.
   emitted.insert(depender->GetName());
@@ -290,13 +290,14 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
 
 //----------------------------------------------------------------------------
 void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
-                                                 cmTarget const* dependee,
-                                                 const std::string& config,
-                                               std::set<std::string> &emitted)
+                                             const cmGeneratorTarget* dependee,
+                                             const std::string& config,
+                                             std::set<std::string> &emitted)
 {
-  cmTarget const* depender = this->Targets[depender_index];
-  if(cmTarget::LinkInterface const* iface =
-                                dependee->GetLinkInterface(config, depender))
+  cmGeneratorTarget const* depender = this->Targets[depender_index];
+  if(cmLinkInterface const* iface =
+                                dependee->GetLinkInterface(config,
+                                                           depender->Target))
     {
     for(std::vector<cmLinkItem>::const_iterator
         lib = iface->Libraries.begin();
@@ -317,7 +318,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
                                              cmLinkItem const& dependee_name,
                                              std::set<std::string> &emitted)
 {
-  cmTarget const* depender = this->Targets[depender_index];
+  cmGeneratorTarget const* depender = this->Targets[depender_index];
   cmTarget const* dependee = dependee_name.Target;
   // Skip targets that will not really be linked.  This is probably a
   // name conflict between an external library and an executable
@@ -331,16 +332,17 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
 
   if(dependee)
     {
-    this->AddInterfaceDepends(depender_index, dependee, "", emitted);
+    cmGeneratorTarget* gt =
+        this->GlobalGenerator->GetGeneratorTarget(dependee);
+    this->AddInterfaceDepends(depender_index, gt, "", emitted);
     std::vector<std::string> configs;
-    depender->GetMakefile()->GetConfigurations(configs);
+    depender->Makefile->GetConfigurations(configs);
     for (std::vector<std::string>::const_iterator it = configs.begin();
       it != configs.end(); ++it)
       {
       // A target should not depend on itself.
       emitted.insert(depender->GetName());
-      this->AddInterfaceDepends(depender_index, dependee,
-                                *it, emitted);
+      this->AddInterfaceDepends(depender_index, gt, *it, emitted);
       }
     }
 }
@@ -351,7 +353,7 @@ void cmComputeTargetDepends::AddTargetDepend(
   bool linking)
 {
   // Get the depender.
-  cmTarget const* depender = this->Targets[depender_index];
+  cmGeneratorTarget const* depender = this->Targets[depender_index];
 
   // Check the target's makefile first.
   cmTarget const* dependee = dependee_name.Target;
@@ -362,7 +364,7 @@ void cmComputeTargetDepends::AddTargetDepend(
     cmake::MessageType messageType = cmake::AUTHOR_WARNING;
     bool issueMessage = false;
     std::ostringstream e;
-    switch(depender->GetPolicyStatusCMP0046())
+    switch(depender->Target->GetPolicyStatusCMP0046())
       {
       case cmPolicies::WARN:
         e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0046) << "\n";
@@ -383,7 +385,7 @@ void cmComputeTargetDepends::AddTargetDepend(
         << "\" of target \"" << depender->GetName() << "\" does not exist.";
 
       cmListFileBacktrace const* backtrace =
-        depender->GetUtilityBacktrace(dependee_name);
+        depender->Target->GetUtilityBacktrace(dependee_name);
       if(backtrace)
         {
         cm->IssueMessage(messageType, e.str(), *backtrace);
@@ -408,27 +410,31 @@ void cmComputeTargetDepends::AddTargetDepend(
 
   if(dependee)
     {
-    this->AddTargetDepend(depender_index, dependee, linking);
+    cmGeneratorTarget* gt =
+        this->GlobalGenerator->GetGeneratorTarget(dependee);
+    this->AddTargetDepend(depender_index, gt, linking);
     }
 }
 
 //----------------------------------------------------------------------------
 void cmComputeTargetDepends::AddTargetDepend(int depender_index,
-                                             cmTarget const* dependee,
+                                             const cmGeneratorTarget* dependee,
                                              bool linking)
 {
-  if(dependee->IsImported() ||
+  if(dependee->Target->IsImported() ||
      dependee->GetType() == cmTarget::INTERFACE_LIBRARY)
     {
     // Skip IMPORTED and INTERFACE targets but follow their utility
     // dependencies.
-    std::set<cmLinkItem> const& utils = dependee->GetUtilityItems();
+    std::set<cmLinkItem> const& utils = dependee->Target->GetUtilityItems();
     for(std::set<cmLinkItem>::const_iterator i = utils.begin();
         i != utils.end(); ++i)
       {
       if(cmTarget const* transitive_dependee = i->Target)
         {
-        this->AddTargetDepend(depender_index, transitive_dependee, false);
+        cmGeneratorTarget* gt =
+            this->GlobalGenerator->GetGeneratorTarget(transitive_dependee);
+        this->AddTargetDepend(depender_index, gt, false);
         }
       }
     }
@@ -436,7 +442,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
     {
     // Lookup the index for this target.  All targets should be known by
     // this point.
-    std::map<cmTarget const*, int>::const_iterator tii =
+    std::map<cmGeneratorTarget const*, int>::const_iterator tii =
       this->TargetIndex.find(dependee);
     assert(tii != this->TargetIndex.end());
     int dependee_index = tii->second;
@@ -457,13 +463,13 @@ cmComputeTargetDepends::DisplayGraph(Graph const& graph,
   for(int depender_index = 0; depender_index < n; ++depender_index)
     {
     EdgeList const& nl = graph[depender_index];
-    cmTarget const* depender = this->Targets[depender_index];
+    cmGeneratorTarget const* depender = this->Targets[depender_index];
     fprintf(stderr, "target %d is [%s]\n",
             depender_index, depender->GetName().c_str());
     for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
       {
       int dependee_index = *ni;
-      cmTarget const* dependee = this->Targets[dependee_index];
+      cmGeneratorTarget const* dependee = this->Targets[dependee_index];
       fprintf(stderr, "  depends on target %d [%s] (%s)\n", dependee_index,
               dependee->GetName().c_str(), ni->IsStrong()? "strong" : "weak");
       }
@@ -550,11 +556,11 @@ cmComputeTargetDepends
     {
     // Get the depender.
     int i = *ci;
-    cmTarget const* depender = this->Targets[i];
+    cmGeneratorTarget const* depender = this->Targets[i];
 
     // Describe the depender.
     e << "  \"" << depender->GetName() << "\" of type "
-      << cmTarget::GetTargetTypeName(depender->GetType()) << "\n";
+      << cmTarget::GetTargetTypeName(depender->Target->GetType()) << "\n";
 
     // List its dependencies that are inside the component.
     EdgeList const& nl = this->InitialGraph[i];
@@ -563,7 +569,7 @@ cmComputeTargetDepends
       int j = *ni;
       if(cmap[j] == c)
         {
-        cmTarget const* dependee = this->Targets[j];
+        cmGeneratorTarget const* dependee = this->Targets[j];
         e << "    depends on \"" << dependee->GetName() << "\""
           << " (" << (ni->IsStrong()? "strong" : "weak") << ")\n";
         }
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index 902f342..6100d97 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -21,7 +21,7 @@
 class cmComputeComponentGraph;
 class cmGlobalGenerator;
 class cmLinkItem;
-class cmTarget;
+class cmGeneratorTarget;
 class cmTargetDependSet;
 
 /** \class cmComputeTargetDepends
@@ -39,9 +39,10 @@ public:
 
   bool Compute();
 
-  std::vector<cmTarget const*> const&
+  std::vector<cmGeneratorTarget const*> const&
   GetTargets() const { return this->Targets; }
-  void GetTargetDirectDepends(cmTarget const* t, cmTargetDependSet& deps);
+  void GetTargetDirectDepends(cmGeneratorTarget const* t,
+                              cmTargetDependSet& deps);
 private:
   void CollectTargets();
   void CollectDepends();
@@ -49,13 +50,14 @@ private:
   void AddTargetDepend(int depender_index,
                        cmLinkItem const& dependee_name,
                        bool linking);
-  void AddTargetDepend(int depender_index, cmTarget const* dependee,
+  void AddTargetDepend(int depender_index, cmGeneratorTarget const* dependee,
                        bool linking);
   bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
   void AddInterfaceDepends(int depender_index,
                            cmLinkItem const& dependee_name,
                            std::set<std::string> &emitted);
-  void AddInterfaceDepends(int depender_index, cmTarget const* dependee,
+  void AddInterfaceDepends(int depender_index,
+                           cmGeneratorTarget const* dependee,
                            const std::string& config,
                            std::set<std::string> &emitted);
   cmGlobalGenerator* GlobalGenerator;
@@ -63,8 +65,8 @@ private:
   bool NoCycles;
 
   // Collect all targets.
-  std::vector<cmTarget const*> Targets;
-  std::map<cmTarget const*, int> TargetIndex;
+  std::vector<cmGeneratorTarget const*> Targets;
+  std::map<cmGeneratorTarget const*, int> TargetIndex;
 
   // Represent the target dependency graph.  The entry at each
   // top-level index corresponds to a depender whose dependencies are
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 61847d4..5330acd 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -11,12 +11,18 @@
 ============================================================================*/
 
 #include "cmConditionEvaluator.h"
+#include "cmOutputConverter.h"
 
-cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile):
+cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile,
+                                           const cmListFileContext &context,
+                                           const cmListFileBacktrace& bt):
   Makefile(makefile),
+  ExecutionContext(context),
+  Backtrace(bt),
   Policy12Status(makefile.GetPolicyStatus(cmPolicies::CMP0012)),
   Policy54Status(makefile.GetPolicyStatus(cmPolicies::CMP0054)),
-  Policy57Status(makefile.GetPolicyStatus(cmPolicies::CMP0057))
+  Policy57Status(makefile.GetPolicyStatus(cmPolicies::CMP0057)),
+  Policy64Status(makefile.GetPolicyStatus(cmPolicies::CMP0064))
 {
 
 }
@@ -97,6 +103,25 @@ bool cmConditionEvaluator::IsTrue(
     errorString, status, true);
 }
 
+cmListFileContext cmConditionEvaluator::GetConditionContext(
+    cmMakefile* mf,
+    const cmCommandContext& command,
+    const std::string& filePath)
+{
+  cmListFileContext context =
+      cmListFileContext::FromCommandContext(
+        command,
+        filePath);
+
+  if(!mf->GetCMakeInstance()->GetIsInTryCompile())
+    {
+    cmOutputConverter converter(mf->GetStateSnapshot());
+    context.FilePath = converter.Convert(context.FilePath,
+                                         cmOutputConverter::HOME);
+    }
+  return context;
+}
+
 //=========================================================================
 const char* cmConditionEvaluator::GetDefinitionIfUnquoted(
   cmExpandedCommandArgument const& argument) const
@@ -112,7 +137,8 @@ const char* cmConditionEvaluator::GetDefinitionIfUnquoted(
 
   if(def && argument.WasQuoted() && this->Policy54Status == cmPolicies::WARN)
     {
-    if(!this->Makefile.HasCMP0054AlreadyBeenReported())
+    if(!this->Makefile.HasCMP0054AlreadyBeenReported(
+         this->ExecutionContext))
       {
       std::ostringstream e;
       e << (cmPolicies::GetPolicyWarning(cmPolicies::CMP0054)) << "\n";
@@ -121,7 +147,9 @@ const char* cmConditionEvaluator::GetDefinitionIfUnquoted(
         "when the policy is set to NEW.  "
         "Since the policy is not set the OLD behavior will be used.";
 
-      this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
+      this->Makefile.GetCMakeInstance()
+          ->IssueMessage(cmake::AUTHOR_WARNING, e.str(),
+                         this->Backtrace);
       }
     }
 
@@ -158,7 +186,8 @@ bool cmConditionEvaluator::IsKeyword(std::string const& keyword,
   if(isKeyword && argument.WasQuoted() &&
     this->Policy54Status == cmPolicies::WARN)
     {
-    if(!this->Makefile.HasCMP0054AlreadyBeenReported())
+    if(!this->Makefile.HasCMP0054AlreadyBeenReported(
+         this->ExecutionContext))
       {
       std::ostringstream e;
       e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0054) << "\n";
@@ -167,7 +196,9 @@ bool cmConditionEvaluator::IsKeyword(std::string const& keyword,
         "when the policy is set to NEW.  "
         "Since the policy is not set the OLD behavior will be used.";
 
-      this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
+      this->Makefile.GetCMakeInstance()
+          ->IssueMessage(cmake::AUTHOR_WARNING, e.str(),
+                         this->Backtrace);
       }
     }
 
@@ -299,11 +330,11 @@ void cmConditionEvaluator::IncrementArguments(cmArgumentList &newArgs,
                         cmArgumentList::iterator &argP1,
                         cmArgumentList::iterator &argP2) const
 {
-  if (argP1  != newArgs.end())
+  if (argP1 != newArgs.end())
     {
     argP1++;
     argP2 = argP1;
-    if (argP1  != newArgs.end())
+    if (argP1 != newArgs.end())
       {
       argP2++;
       }
@@ -442,35 +473,35 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList &newArgs,
       argP1 = arg;
       this->IncrementArguments(newArgs,argP1,argP2);
       // does a file exist
-      if (this->IsKeyword("EXISTS", *arg) && argP1  != newArgs.end())
+      if (this->IsKeyword("EXISTS", *arg) && argP1 != newArgs.end())
         {
         this->HandlePredicate(
           cmSystemTools::FileExists(argP1->c_str()),
           reducible, arg, newArgs, argP1, argP2);
         }
       // does a directory with this name exist
-      if (this->IsKeyword("IS_DIRECTORY", *arg) && argP1  != newArgs.end())
+      if (this->IsKeyword("IS_DIRECTORY", *arg) && argP1 != newArgs.end())
         {
         this->HandlePredicate(
           cmSystemTools::FileIsDirectory(argP1->c_str()),
           reducible, arg, newArgs, argP1, argP2);
         }
       // does a symlink with this name exist
-      if (this->IsKeyword("IS_SYMLINK", *arg) && argP1  != newArgs.end())
+      if (this->IsKeyword("IS_SYMLINK", *arg) && argP1 != newArgs.end())
         {
         this->HandlePredicate(
           cmSystemTools::FileIsSymlink(argP1->c_str()),
           reducible, arg, newArgs, argP1, argP2);
         }
       // is the given path an absolute path ?
-      if (this->IsKeyword("IS_ABSOLUTE", *arg) && argP1  != newArgs.end())
+      if (this->IsKeyword("IS_ABSOLUTE", *arg) && argP1 != newArgs.end())
         {
         this->HandlePredicate(
           cmSystemTools::FileIsFullPath(argP1->c_str()),
           reducible, arg, newArgs, argP1, argP2);
         }
       // does a command exist
-      if (this->IsKeyword("COMMAND", *arg) && argP1  != newArgs.end())
+      if (this->IsKeyword("COMMAND", *arg) && argP1 != newArgs.end())
         {
         cmCommand* command =
             this->Makefile.GetState()->GetCommand(argP1->c_str());
@@ -493,8 +524,31 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList &newArgs,
           this->Makefile.FindTargetToUse(argP1->GetValue())?true:false,
           reducible, arg, newArgs, argP1, argP2);
         }
+      // does a test exist
+      if(this->Policy64Status != cmPolicies::OLD &&
+        this->Policy64Status != cmPolicies::WARN)
+        {
+        if (this->IsKeyword("TEST", *arg) && argP1 != newArgs.end())
+          {
+          const cmTest* haveTest = this->Makefile.GetTest(argP1->c_str());
+          this->HandlePredicate(
+            haveTest?true:false,
+            reducible, arg, newArgs, argP1, argP2);
+          }
+        }
+      else if(this->Policy64Status == cmPolicies::WARN &&
+        this->IsKeyword("TEST", *arg))
+        {
+        std::ostringstream e;
+        e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0064) << "\n";
+        e << "TEST will be interpreted as an operator "
+          "when the policy is set to NEW.  "
+          "Since the policy is not set the OLD behavior will be used.";
+
+        this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
+        }
       // is a variable defined
-      if (this->IsKeyword("DEFINED", *arg) && argP1  != newArgs.end())
+      if (this->IsKeyword("DEFINED", *arg) && argP1 != newArgs.end())
         {
         size_t argP1len = argP1->GetValue().size();
         bool bdef = false;
diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h
index c923d76..8600825 100644
--- a/Source/cmConditionEvaluator.h
+++ b/Source/cmConditionEvaluator.h
@@ -22,7 +22,9 @@ class cmConditionEvaluator
 public:
   typedef std::list<cmExpandedCommandArgument> cmArgumentList;
 
-  cmConditionEvaluator(cmMakefile& makefile);
+  cmConditionEvaluator(cmMakefile& makefile,
+                       cmListFileContext const& context,
+                       cmListFileBacktrace const& bt);
 
   // this is a shared function for both If and Else to determine if the
   // arguments were valid, and if so, was the response true. If there is
@@ -31,6 +33,9 @@ public:
       std::string &errorString,
       cmake::MessageType &status);
 
+  static cmListFileContext GetConditionContext(cmMakefile* mf,
+      const cmCommandContext& command, std::string const& filePath);
+
 private:
   // Filter the given variable definition based on policy CMP0054.
   const char* GetDefinitionIfUnquoted(
@@ -91,9 +96,12 @@ private:
       cmake::MessageType &status);
 
   cmMakefile& Makefile;
+  cmListFileContext ExecutionContext;
+  cmListFileBacktrace Backtrace;
   cmPolicies::PolicyStatus Policy12Status;
   cmPolicies::PolicyStatus Policy54Status;
   cmPolicies::PolicyStatus Policy57Status;
+  cmPolicies::PolicyStatus Policy64Status;
 };
 
 #endif
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index dd276a8..3d9c4bf 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -11,7 +11,7 @@
 ============================================================================*/
 #include "cmCoreTryCompile.h"
 #include "cmake.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
 #include "cmGlobalGenerator.h"
 #include "cmAlgorithms.h"
 #include "cmExportTryCompileFileGenerator.h"
@@ -29,7 +29,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
   const char* sourceDirectory = argv[2].c_str();
   const char* projectName = 0;
   std::string targetName;
-  std::vector<std::string> cmakeFlags;
+  std::vector<std::string> cmakeFlags(1, "CMAKE_FLAGS"); // fake argv[0]
   std::vector<std::string> compileDefs;
   std::string outputVariable;
   std::string copyFile;
@@ -53,10 +53,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
     if(argv[i] == "CMAKE_FLAGS")
       {
       doing = DoingCMakeFlags;
-      // CMAKE_FLAGS is the first argument because we need an argv[0] that
-      // is not used, so it matches regular command line parsing which has
-      // the program name as arg 0
-      cmakeFlags.push_back(argv[i]);
       }
     else if(argv[i] == "COMPILE_DEFINITIONS")
       {
@@ -322,7 +318,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
       std::string langFlags = "CMAKE_" + *li + "_FLAGS";
       const char* flags = this->Makefile->GetDefinition(langFlags);
       fprintf(fout, "set(CMAKE_%s_FLAGS %s)\n", li->c_str(),
-              cmLocalGenerator::EscapeForCMake(flags?flags:"").c_str());
+              cmOutputConverter::EscapeForCMake(flags?flags:"").c_str());
       fprintf(fout, "set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}"
               " ${COMPILE_DEFINITIONS}\")\n", li->c_str(), li->c_str());
       }
@@ -355,7 +351,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
         const char* exeLinkFlags =
           this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS");
         fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n",
-                cmLocalGenerator::EscapeForCMake(
+                cmOutputConverter::EscapeForCMake(
                     exeLinkFlags ? exeLinkFlags : "").c_str());
         } break;
       }
@@ -379,7 +375,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
     if (!targets.empty())
       {
       std::string fname = "/" + std::string(targetName) + "Targets.cmake";
-      cmExportTryCompileFileGenerator tcfg;
+      cmExportTryCompileFileGenerator tcfg(gg);
       tcfg.SetExportFile((this->BinaryDirectory + fname).c_str());
       tcfg.SetExports(targets);
       tcfg.SetConfig(this->Makefile->GetSafeDefinition(
@@ -470,6 +466,26 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
       {
       fprintf(fout, "set(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");
       }
+    if (const char *lssDef = this->Makefile->GetDefinition(
+        "CMAKE_LINK_SEARCH_START_STATIC"))
+      {
+      fprintf(fout, "set(CMAKE_LINK_SEARCH_START_STATIC \"%s\")\n", lssDef);
+      }
+    if (const char *lssDef = this->Makefile->GetDefinition(
+        "CMAKE_LINK_SEARCH_END_STATIC"))
+      {
+      fprintf(fout, "set(CMAKE_LINK_SEARCH_END_STATIC \"%s\")\n", lssDef);
+      }
+
+    /* Set the appropriate policy information for ENABLE_EXPORTS */
+    fprintf(fout, "cmake_policy(SET CMP0065 %s)\n",
+       this->Makefile->GetPolicyStatus(cmPolicies::CMP0065) ==
+         cmPolicies::NEW ? "NEW" : "OLD");
+    if(const char *ee = this->Makefile->GetDefinition(
+        "CMAKE_ENABLE_EXPORTS"))
+      {
+      fprintf(fout, "set(CMAKE_ENABLE_EXPORTS %s)\n", ee);
+      }
 
     /* Put the executable at a known location (for COPY_FILE).  */
     fprintf(fout, "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n",
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index 74e17b6..6616218 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -46,7 +46,7 @@ std::string cmCryptoHash::HashString(const std::string& input)
 //----------------------------------------------------------------------------
 std::string cmCryptoHash::HashFile(const std::string& file)
 {
-  cmsys::ifstream fin(file.c_str(), std::ios::in | cmsys_ios_binary);
+  cmsys::ifstream fin(file.c_str(), std::ios::in | std::ios::binary);
   if(!fin)
     {
     return "";
diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx
index 96d3547..ad0c7d3 100644
--- a/Source/cmCurl.cxx
+++ b/Source/cmCurl.cxx
@@ -13,7 +13,7 @@
 #include "cmSystemTools.h"
 
 #define check_curl_result(result, errstr)                               \
-  if (result != CURLE_OK)                                               \
+  if (result != CURLE_OK && result != CURLE_NOT_BUILT_IN)               \
     {                                                                   \
     e += e.empty()? "" : "\n";                                          \
     e += errstr;                                                        \
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 015825d..7c37e3b 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -17,7 +17,7 @@
 
 //----------------------------------------------------------------------------
 cmCustomCommand::cmCustomCommand()
-  : Backtrace(NULL)
+  : Backtrace()
 {
   this->HaveComment = false;
   this->EscapeOldStyle = true;
@@ -26,46 +26,6 @@ cmCustomCommand::cmCustomCommand()
 }
 
 //----------------------------------------------------------------------------
-cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
-  Outputs(r.Outputs),
-  Byproducts(r.Byproducts),
-  Depends(r.Depends),
-  CommandLines(r.CommandLines),
-  HaveComment(r.HaveComment),
-  Comment(r.Comment),
-  WorkingDirectory(r.WorkingDirectory),
-  EscapeAllowMakeVars(r.EscapeAllowMakeVars),
-  EscapeOldStyle(r.EscapeOldStyle),
-  Backtrace(r.Backtrace),
-  UsesTerminal(r.UsesTerminal)
-{
-}
-
-//----------------------------------------------------------------------------
-cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r)
-{
-  if(this == &r)
-    {
-    return *this;
-    }
-
-  this->Outputs = r.Outputs;
-  this->Byproducts= r.Byproducts;
-  this->Depends = r.Depends;
-  this->CommandLines = r.CommandLines;
-  this->HaveComment = r.HaveComment;
-  this->Comment = r.Comment;
-  this->WorkingDirectory = r.WorkingDirectory;
-  this->EscapeAllowMakeVars = r.EscapeAllowMakeVars;
-  this->EscapeOldStyle = r.EscapeOldStyle;
-  this->ImplicitDepends = r.ImplicitDepends;
-  this->Backtrace = r.Backtrace;
-  this->UsesTerminal = r.UsesTerminal;
-
-  return *this;
-}
-
-//----------------------------------------------------------------------------
 cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
                                  const std::vector<std::string>& outputs,
                                  const std::vector<std::string>& byproducts,
@@ -77,15 +37,13 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
   Byproducts(byproducts),
   Depends(depends),
   CommandLines(commandLines),
-  HaveComment(comment?true:false),
+  Backtrace(),
   Comment(comment?comment:""),
   WorkingDirectory(workingDirectory?workingDirectory:""),
+  HaveComment(comment?true:false),
   EscapeAllowMakeVars(false),
-  EscapeOldStyle(true),
-  Backtrace(NULL)
+  EscapeOldStyle(true)
 {
-  this->EscapeOldStyle = true;
-  this->EscapeAllowMakeVars = false;
   if(mf)
     {
     this->Backtrace = mf->GetBacktrace();
@@ -93,11 +51,6 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
 }
 
 //----------------------------------------------------------------------------
-cmCustomCommand::~cmCustomCommand()
-{
-}
-
-//----------------------------------------------------------------------------
 const std::vector<std::string>& cmCustomCommand::GetOutputs() const
 {
   return this->Outputs;
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 0bfaef2..f9b38c3 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -26,8 +26,6 @@ class cmCustomCommand
 public:
   /** Default and copy constructors for STL containers.  */
   cmCustomCommand();
-  cmCustomCommand(const cmCustomCommand& r);
-  cmCustomCommand& operator=(cmCustomCommand const& r);
 
   /** Main constructor specifies all information for the command.  */
   cmCustomCommand(cmMakefile const* mf,
@@ -38,8 +36,6 @@ public:
                   const char* comment,
                   const char* workingDirectory);
 
-  ~cmCustomCommand();
-
   /** Get the output file produced by the command.  */
   const std::vector<std::string>& GetOutputs() const;
 
@@ -93,13 +89,13 @@ private:
   std::vector<std::string> Byproducts;
   std::vector<std::string> Depends;
   cmCustomCommandLines CommandLines;
-  bool HaveComment;
+  cmListFileBacktrace Backtrace;
+  ImplicitDependsList ImplicitDepends;
   std::string Comment;
   std::string WorkingDirectory;
+  bool HaveComment;
   bool EscapeAllowMakeVars;
   bool EscapeOldStyle;
-  cmListFileBacktrace Backtrace;
-  ImplicitDependsList ImplicitDepends;
   bool UsesTerminal;
 };
 
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index d23f815..7f3b651 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -12,16 +12,17 @@
 #include "cmCustomCommandGenerator.h"
 
 #include "cmMakefile.h"
-#include "cmCustomCommand.h"
 #include "cmLocalGenerator.h"
+#include "cmCustomCommand.h"
+#include "cmOutputConverter.h"
 #include "cmGeneratorExpression.h"
 
 //----------------------------------------------------------------------------
 cmCustomCommandGenerator::cmCustomCommandGenerator(
-  cmCustomCommand const& cc, const std::string& config, cmMakefile* mf):
-  CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()),
+  cmCustomCommand const& cc, const std::string& config, cmLocalGenerator* lg):
+  CC(cc), Config(config), LG(lg),
   OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()),
-  GE(new cmGeneratorExpression(&cc.GetBacktrace())), DependsDone(false)
+  GE(new cmGeneratorExpression(cc.GetBacktrace())), DependsDone(false)
 {
 }
 
@@ -41,13 +42,16 @@ unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
 std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
 {
   std::string const& argv0 = this->CC.GetCommandLines()[c][0];
-  cmTarget* target = this->Makefile->FindTargetToUse(argv0);
+  cmGeneratorTarget* target =
+      this->LG->GetMakefile()->FindGeneratorTargetToUse(argv0);
   if(target && target->GetType() == cmTarget::EXECUTABLE &&
-     (target->IsImported() || !this->Makefile->IsOn("CMAKE_CROSSCOMPILING")))
+     (target->Target->IsImported()
+      || !this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")))
     {
     return target->GetLocation(this->Config);
     }
-  return this->GE->Parse(argv0)->Evaluate(this->Makefile, this->Config);
+  return this->GE->Parse(argv0)->Evaluate(this->LG->GetMakefile(),
+                                          this->Config);
 }
 
 //----------------------------------------------------------------------------
@@ -87,8 +91,9 @@ cmCustomCommandGenerator
   cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
   for(unsigned int j=1;j < commandLine.size(); ++j)
     {
-    std::string arg = this->GE->Parse(commandLine[j])->Evaluate(this->Makefile,
-                                                               this->Config);
+    std::string arg =
+        this->GE->Parse(commandLine[j])->Evaluate(this->LG->GetMakefile(),
+                                                  this->Config);
     cmd += " ";
     if(this->OldStyle)
       {
@@ -96,7 +101,8 @@ cmCustomCommandGenerator
       }
     else
       {
-      cmd += this->LG->EscapeForShell(arg, this->MakeVars);
+      cmOutputConverter converter(this->LG->GetMakefile()->GetStateSnapshot());
+      cmd += converter.EscapeForShell(arg, this->MakeVars);
       }
     }
 }
@@ -140,7 +146,7 @@ std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
                                               = this->GE->Parse(*i);
       std::vector<std::string> result;
       cmSystemTools::ExpandListArgument(
-                  cge->Evaluate(this->Makefile, this->Config), result);
+            cge->Evaluate(this->LG->GetMakefile(), this->Config), result);
       for (std::vector<std::string>::iterator it = result.begin();
           it != result.end(); ++it)
         {
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index b4ae014..a637fed 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -15,7 +15,6 @@
 #include "cmStandardIncludes.h"
 
 class cmCustomCommand;
-class cmMakefile;
 class cmLocalGenerator;
 class cmGeneratorExpression;
 
@@ -23,7 +22,6 @@ class cmCustomCommandGenerator
 {
   cmCustomCommand const& CC;
   std::string Config;
-  cmMakefile* Makefile;
   cmLocalGenerator* LG;
   bool OldStyle;
   bool MakeVars;
@@ -33,7 +31,7 @@ class cmCustomCommandGenerator
 public:
   cmCustomCommandGenerator(cmCustomCommand const& cc,
                            const std::string& config,
-                           cmMakefile* mf);
+                           cmLocalGenerator* lg);
   ~cmCustomCommandGenerator();
   cmCustomCommand const& GetCC() const { return this->CC; }
   unsigned int GetNumberOfCommands() const;
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index 2dab169..b06fb5c 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -56,9 +56,9 @@ void cmDefinitions::Raise(const std::string& key,
 }
 
 bool cmDefinitions::HasKey(const std::string& key,
-                           StackConstIter begin, StackConstIter end)
+                           StackIter begin, StackIter end)
 {
-  for (StackConstIter it = begin; it != end; ++it)
+  for (StackIter it = begin; it != end; ++it)
     {
     MapType::const_iterator i = it->Map.find(key);
     if (i != it->Map.end())
@@ -94,12 +94,12 @@ std::vector<std::string> cmDefinitions::UnusedKeys() const
 }
 
 //----------------------------------------------------------------------------
-cmDefinitions cmDefinitions::MakeClosure(StackConstIter begin,
-                                         StackConstIter end)
+cmDefinitions cmDefinitions::MakeClosure(StackIter begin,
+                                         StackIter end)
 {
   cmDefinitions closure;
   std::set<std::string> undefined;
-  for (StackConstIter it = begin; it != end; ++it)
+  for (StackIter it = begin; it != end; ++it)
     {
     // Consider local definitions.
     for(MapType::const_iterator mi = it->Map.begin();
@@ -125,12 +125,12 @@ cmDefinitions cmDefinitions::MakeClosure(StackConstIter begin,
 
 //----------------------------------------------------------------------------
 std::vector<std::string>
-cmDefinitions::ClosureKeys(StackConstIter begin, StackConstIter end)
+cmDefinitions::ClosureKeys(StackIter begin, StackIter end)
 {
   std::set<std::string> bound;
   std::vector<std::string> defined;
 
-  for (StackConstIter it = begin; it != end; ++it)
+  for (StackIter it = begin; it != end; ++it)
     {
     defined.reserve(defined.size() + it->Map.size());
     for(MapType::const_iterator mi = it->Map.begin();
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index 5fdcaab..411867c 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -13,6 +13,9 @@
 #define cmDefinitions_h
 
 #include "cmStandardIncludes.h"
+
+#include "cmLinkedTree.h"
+
 #if defined(CMAKE_BUILD_WITH_CMAKE)
 #ifdef CMake_HAVE_CXX11_UNORDERED_MAP
 #include <unordered_map>
@@ -32,26 +35,26 @@
  */
 class cmDefinitions
 {
-  typedef std::list<cmDefinitions>::reverse_iterator StackIter;
-  typedef std::list<cmDefinitions>::const_reverse_iterator StackConstIter;
+  typedef cmLinkedTree<cmDefinitions>::iterator StackIter;
 public:
   static const char* Get(const std::string& key,
                          StackIter begin, StackIter end);
 
-  static void Raise(const std::string& key, StackIter begin, StackIter end);
+  static void Raise(const std::string& key,
+                    StackIter begin, StackIter end);
 
   static bool HasKey(const std::string& key,
-                     StackConstIter begin, StackConstIter end);
+                     StackIter begin, StackIter end);
 
   /** Set (or unset if null) a value associated with a key.  */
   void Set(const std::string& key, const char* value);
 
   std::vector<std::string> UnusedKeys() const;
 
-  static std::vector<std::string> ClosureKeys(StackConstIter begin,
-                                              StackConstIter end);
+  static std::vector<std::string> ClosureKeys(StackIter begin,
+                                              StackIter end);
 
-  static cmDefinitions MakeClosure(StackConstIter begin, StackConstIter end);
+  static cmDefinitions MakeClosure(StackIter begin, StackIter end);
 
 private:
   // String with existence boolean.
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 1b2586c..856dcd4 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -16,84 +16,15 @@
 #include "cmMakefile.h"
 #include "cmGeneratedFileStream.h"
 
-#include "cmDependsFortranParser.h" /* Interface to parser object.  */
+#include "cmFortranParser.h" /* Interface to parser object.  */
 #include <cmsys/FStream.hxx>
 #include <assert.h>
-#include <stack>
 
 // TODO: Test compiler for the case of the mod file.  Some always
 // use lower case and some always use upper case.  I do not know if any
 // use the case from the source code.
 
 //----------------------------------------------------------------------------
-// Information about a single source file.
-class cmDependsFortranSourceInfo
-{
-public:
-  // The name of the source file.
-  std::string Source;
-
-  // Set of provided and required modules.
-  std::set<std::string> Provides;
-  std::set<std::string> Requires;
-
-  // Set of files included in the translation unit.
-  std::set<std::string> Includes;
-};
-
-//----------------------------------------------------------------------------
-// Parser methods not included in generated interface.
-
-// Get the current buffer processed by the lexer.
-YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner);
-
-// The parser entry point.
-int cmDependsFortran_yyparse(yyscan_t);
-
-//----------------------------------------------------------------------------
-// Define parser object internal structure.
-struct cmDependsFortranFile
-{
-  cmDependsFortranFile(FILE* file, YY_BUFFER_STATE buffer,
-                       const std::string& dir):
-    File(file), Buffer(buffer), Directory(dir) {}
-  FILE* File;
-  YY_BUFFER_STATE Buffer;
-  std::string Directory;
-};
-
-struct cmDependsFortranParser_s
-{
-  cmDependsFortranParser_s(cmDependsFortran* self,
-                           std::set<std::string>& ppDefines,
-                           cmDependsFortranSourceInfo& info);
-  ~cmDependsFortranParser_s();
-
-  // Pointer back to the main class.
-  cmDependsFortran* Self;
-
-  // Lexical scanner instance.
-  yyscan_t Scanner;
-
-  // Stack of open files in the translation unit.
-  std::stack<cmDependsFortranFile> FileStack;
-
-  // Buffer for string literals.
-  std::string TokenString;
-
-  // Flag for whether lexer is reading from inside an interface.
-  bool InInterface;
-
-  int OldStartcond;
-  std::set<std::string> PPDefinitions;
-  size_t InPPFalseBranch;
-  std::stack<bool> SkipToEnd;
-
-  // Information about the parsed source.
-  cmDependsFortranSourceInfo& Info;
-};
-
-//----------------------------------------------------------------------------
 class cmDependsFortranInternals
 {
 public:
@@ -105,18 +36,18 @@ public:
   TargetRequiresMap TargetRequires;
 
   // Information about each object file.
-  typedef std::map<std::string, cmDependsFortranSourceInfo> ObjectInfoMap;
+  typedef std::map<std::string, cmFortranSourceInfo> ObjectInfoMap;
   ObjectInfoMap ObjectInfo;
 
-  cmDependsFortranSourceInfo& CreateObjectInfo(const char* obj,
+  cmFortranSourceInfo& CreateObjectInfo(const char* obj,
                                                const char* src)
     {
-    std::map<std::string, cmDependsFortranSourceInfo>::iterator i =
+    std::map<std::string, cmFortranSourceInfo>::iterator i =
       this->ObjectInfo.find(obj);
     if(i == this->ObjectInfo.end())
       {
-      std::map<std::string, cmDependsFortranSourceInfo>::value_type
-        entry(obj, cmDependsFortranSourceInfo());
+      std::map<std::string, cmFortranSourceInfo>::value_type
+        entry(obj, cmFortranSourceInfo());
       i = this->ObjectInfo.insert(entry).first;
       i->second.Source = src;
       }
@@ -126,7 +57,7 @@ public:
 
 //----------------------------------------------------------------------------
 cmDependsFortran::cmDependsFortran():
-  PPDefinitions(0), Internal(0)
+  Internal(0)
 {
 }
 
@@ -159,7 +90,7 @@ cmDependsFortran
       {
       def = it->substr(0, assignment);
       }
-    this->PPDefinitions.push_back(def);
+    this->PPDefinitions.insert(def);
     }
 }
 
@@ -192,22 +123,18 @@ bool cmDependsFortran::WriteDependencies(
     {
     const std::string& src = *it;
     // Get the information object for this source.
-    cmDependsFortranSourceInfo& info =
+    cmFortranSourceInfo& info =
       this->Internal->CreateObjectInfo(obj.c_str(), src.c_str());
 
-    // Make a copy of the macros defined via ADD_DEFINITIONS
-    std::set<std::string> ppDefines(this->PPDefinitions.begin(),
-                                    this->PPDefinitions.end());
-
-    // Create the parser object. The constructor takes ppMacro and info per
-    // reference, so we may look into the resulting objects later.
-    cmDependsFortranParser parser(this, ppDefines, info);
+    // Create the parser object. The constructor takes info by reference,
+    // so we may look into the resulting objects later.
+    cmFortranParser parser(this->IncludePath, this->PPDefinitions, info);
 
     // Push on the starting file.
-    cmDependsFortranParser_FilePush(&parser, src.c_str());
+    cmFortranParser_FilePush(&parser, src.c_str());
 
     // Parse the translation unit.
-    if(cmDependsFortran_yyparse(parser.Scanner) != 0)
+    if(cmFortran_yyparse(parser.Scanner) != 0)
       {
       // Failed to parse the file.  Report failure to write dependencies.
       okay = false;
@@ -227,14 +154,10 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
   const char* stamp_dir = this->TargetDirectory.c_str();
 
   // Get the directory in which module files will be created.
-  const char* mod_dir;
   cmMakefile* mf = this->LocalGenerator->GetMakefile();
-  if(const char* target_mod_dir =
-     mf->GetDefinition("CMAKE_Fortran_TARGET_MODULE_DIR"))
-    {
-    mod_dir = target_mod_dir;
-    }
-  else
+  std::string mod_dir =
+    mf->GetSafeDefinition("CMAKE_Fortran_TARGET_MODULE_DIR");
+  if (mod_dir.empty())
     {
     mod_dir =
       this->LocalGenerator->GetMakefile()->GetCurrentBinaryDirectory();
@@ -318,7 +241,7 @@ void cmDependsFortran::LocateModules()
   for(ObjectInfoMap::const_iterator infoI = objInfo.begin();
       infoI != objInfo.end(); ++infoI)
     {
-    cmDependsFortranSourceInfo const& info = infoI->second;
+    cmFortranSourceInfo const& info = infoI->second;
     // Include this module in the set provided by this target.
     this->Internal->TargetProvides.insert(info.Provides.begin(),
                                           info.Provides.end());
@@ -428,8 +351,9 @@ void cmDependsFortran::ConsiderModule(const char* name,
 bool
 cmDependsFortran
 ::WriteDependenciesReal(const char *obj,
-                        cmDependsFortranSourceInfo const& info,
-                        const char* mod_dir, const char* stamp_dir,
+                        cmFortranSourceInfo const& info,
+                        std::string const& mod_dir,
+                        const char* stamp_dir,
                         std::ostream& makeDepends,
                         std::ostream& internalDepends)
 {
@@ -701,7 +625,7 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
 // is later used for longer sequences it should be re-written using an
 // efficient string search algorithm such as Boyer-Moore.
 static
-bool cmDependsFortranStreamContainsSequence(std::istream& ifs,
+bool cmFortranStreamContainsSequence(std::istream& ifs,
                                             const char* seq, int len)
 {
   assert(len > 0);
@@ -734,7 +658,7 @@ bool cmDependsFortranStreamContainsSequence(std::istream& ifs,
 
 //----------------------------------------------------------------------------
 // Helper function to compare the remaining content in two streams.
-static bool cmDependsFortranStreamsDiffer(std::istream& ifs1,
+static bool cmFortranStreamsDiffer(std::istream& ifs1,
                                           std::istream& ifs2)
 {
   // Compare the remaining content.
@@ -837,7 +761,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
       const char seq[1] = {'\n'};
       const int seqlen = 1;
 
-      if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen))
+      if(!cmFortranStreamContainsSequence(finModFile, seq, seqlen))
         {
         // The module is of unexpected format.  Assume it is different.
         std::cerr << compilerId << " fortran module " << modFile
@@ -845,7 +769,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
         return true;
         }
 
-      if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
+      if(!cmFortranStreamContainsSequence(finStampFile, seq, seqlen))
         {
         // The stamp must differ if the sequence is not contained.
         return true;
@@ -857,7 +781,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
     const char seq[2] = {'\n', '\0'};
     const int seqlen = 2;
 
-    if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen))
+    if(!cmFortranStreamContainsSequence(finModFile, seq, seqlen))
       {
       // The module is of unexpected format.  Assume it is different.
       std::cerr << compilerId << " fortran module " << modFile
@@ -865,7 +789,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
       return true;
       }
 
-    if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
+    if(!cmFortranStreamContainsSequence(finStampFile, seq, seqlen))
       {
       // The stamp must differ if the sequence is not contained.
       return true;
@@ -875,7 +799,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
   // Compare the remaining content.  If no compiler id matched above,
   // including the case none was given, this will compare the whole
   // content.
-  if(!cmDependsFortranStreamsDiffer(finModFile, finStampFile))
+  if(!cmFortranStreamsDiffer(finModFile, finStampFile))
     {
     return false;
     }
@@ -883,396 +807,3 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
    // The modules are different.
    return true;
 }
-
-//----------------------------------------------------------------------------
-bool cmDependsFortran::FindIncludeFile(const char* dir,
-                                       const char* includeName,
-                                       std::string& fileName)
-{
-  // If the file is a full path, include it directly.
-  if(cmSystemTools::FileIsFullPath(includeName))
-    {
-    fileName = includeName;
-    return cmSystemTools::FileExists(fileName.c_str(), true);
-    }
-  else
-    {
-    // Check for the file in the directory containing the including
-    // file.
-    std::string fullName = dir;
-    fullName += "/";
-    fullName += includeName;
-    if(cmSystemTools::FileExists(fullName.c_str(), true))
-      {
-      fileName = fullName;
-      return true;
-      }
-
-    // Search the include path for the file.
-    for(std::vector<std::string>::const_iterator i =
-          this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
-      {
-      fullName = *i;
-      fullName += "/";
-      fullName += includeName;
-      if(cmSystemTools::FileExists(fullName.c_str(), true))
-        {
-        fileName = fullName;
-        return true;
-        }
-      }
-    }
-  return false;
-}
-
-//----------------------------------------------------------------------------
-cmDependsFortranParser_s
-::cmDependsFortranParser_s(cmDependsFortran* self,
-                           std::set<std::string>& ppDefines,
-                           cmDependsFortranSourceInfo& info):
-  Self(self), PPDefinitions(ppDefines), Info(info)
-{
-  this->InInterface = 0;
-  this->InPPFalseBranch = 0;
-
-  // Initialize the lexical scanner.
-  cmDependsFortran_yylex_init(&this->Scanner);
-  cmDependsFortran_yyset_extra(this, this->Scanner);
-
-  // Create a dummy buffer that is never read but is the fallback
-  // buffer when the last file is popped off the stack.
-  YY_BUFFER_STATE buffer =
-    cmDependsFortran_yy_create_buffer(0, 4, this->Scanner);
-  cmDependsFortran_yy_switch_to_buffer(buffer, this->Scanner);
-}
-
-//----------------------------------------------------------------------------
-cmDependsFortranParser_s::~cmDependsFortranParser_s()
-{
-  cmDependsFortran_yylex_destroy(this->Scanner);
-}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortranParser_FilePush(cmDependsFortranParser* parser,
-                                    const char* fname)
-{
-  // Open the new file and push it onto the stack.  Save the old
-  // buffer with it on the stack.
-  if(FILE* file = cmsys::SystemTools::Fopen(fname, "rb"))
-    {
-    YY_BUFFER_STATE current =
-      cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner);
-    std::string dir = cmSystemTools::GetParentDirectory(fname);
-    cmDependsFortranFile f(file, current, dir);
-    YY_BUFFER_STATE buffer =
-      cmDependsFortran_yy_create_buffer(0, 16384, parser->Scanner);
-    cmDependsFortran_yy_switch_to_buffer(buffer, parser->Scanner);
-    parser->FileStack.push(f);
-    return 1;
-    }
-  else
-    {
-    return 0;
-    }
-}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortranParser_FilePop(cmDependsFortranParser* parser)
-{
-  // Pop one file off the stack and close it.  Switch the lexer back
-  // to the next one on the stack.
-  if(parser->FileStack.empty())
-    {
-    return 0;
-    }
-  else
-    {
-    cmDependsFortranFile f = parser->FileStack.top(); parser->FileStack.pop();
-    fclose(f.File);
-    YY_BUFFER_STATE current =
-      cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner);
-    cmDependsFortran_yy_delete_buffer(current, parser->Scanner);
-    cmDependsFortran_yy_switch_to_buffer(f.Buffer, parser->Scanner);
-    return 1;
-    }
-}
-
-//----------------------------------------------------------------------------
-int cmDependsFortranParser_Input(cmDependsFortranParser* parser,
-                                 char* buffer, size_t bufferSize)
-{
-  // Read from the file on top of the stack.  If the stack is empty,
-  // the end of the translation unit has been reached.
-  if(!parser->FileStack.empty())
-    {
-    FILE* file = parser->FileStack.top().File;
-    return (int)fread(buffer, 1, bufferSize, file);
-    }
-  return 0;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_StringStart(cmDependsFortranParser* parser)
-{
-  parser->TokenString = "";
-}
-
-//----------------------------------------------------------------------------
-const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser)
-{
-  return parser->TokenString.c_str();
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser,
-                                         char c)
-{
-  parser->TokenString += c;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser,
-                                           bool in)
-{
-  if(parser->InPPFalseBranch)
-    {
-    return;
-    }
-
-  parser->InInterface = in;
-}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser)
-{
-  return parser->InInterface;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_SetOldStartcond(cmDependsFortranParser* parser,
-                                            int arg)
-{
-  parser->OldStartcond = arg;
-}
-
-//----------------------------------------------------------------------------
-int cmDependsFortranParser_GetOldStartcond(cmDependsFortranParser* parser)
-{
-  return parser->OldStartcond;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_Error(cmDependsFortranParser*, const char*)
-{
-  // If there is a parser error just ignore it.  The source will not
-  // compile and the user will edit it.  Then dependencies will have
-  // to be regenerated anyway.
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser,
-                                    const char* name)
-{
-  if(!parser->InPPFalseBranch)
-    {
-    parser->Info.Requires.insert(cmSystemTools::LowerCase(name) );
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser,
-                                        const char* name)
-{
-  if(parser->InPPFalseBranch)
-    {
-    return;
-    }
-
-  // If processing an include statement there must be an open file.
-  assert(!parser->FileStack.empty());
-
-  // Get the directory containing the source in which the include
-  // statement appears.  This is always the first search location for
-  // Fortran include files.
-  std::string dir = parser->FileStack.top().Directory;
-
-  // Find the included file.  If it cannot be found just ignore the
-  // problem because either the source will not compile or the user
-  // does not care about depending on this included source.
-  std::string fullName;
-  if(parser->Self->FindIncludeFile(dir.c_str(), name, fullName))
-    {
-    // Found the included file.  Save it in the set of included files.
-    parser->Info.Includes.insert(fullName);
-
-    // Parse it immediately to translate the source inline.
-    cmDependsFortranParser_FilePush(parser, fullName.c_str());
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser,
-                                       const char* name)
-{
-  if(!parser->InPPFalseBranch && !parser->InInterface)
-    {
-    parser->Info.Provides.insert(cmSystemTools::LowerCase(name));
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleDefine(cmDependsFortranParser* parser,
-                                       const char* macro)
-{
-  if(!parser->InPPFalseBranch)
-    {
-    parser->PPDefinitions.insert(macro);
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleUndef(cmDependsFortranParser* parser,
-                                      const char* macro)
-{
-  if(!parser->InPPFalseBranch)
-    {
-    std::set<std::string>::iterator match;
-    match = parser->PPDefinitions.find(macro);
-    if(match != parser->PPDefinitions.end())
-      {
-      parser->PPDefinitions.erase(match);
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser* parser,
-                                      const char* macro)
-{
-  // A new PP branch has been opened
-  parser->SkipToEnd.push(false);
-
-  if (parser->InPPFalseBranch)
-    {
-    parser->InPPFalseBranch++;
-    }
-  else if(parser->PPDefinitions.find(macro) == parser->PPDefinitions.end())
-    {
-    parser->InPPFalseBranch=1;
-    }
-  else
-    {
-    parser->SkipToEnd.top() = true;
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser* parser,
-  const char* macro)
-{
-  // A new PP branch has been opened
-  parser->SkipToEnd.push(false);
-
-  if (parser->InPPFalseBranch)
-    {
-    parser->InPPFalseBranch++;
-    }
-  else if(parser->PPDefinitions.find(macro) != parser->PPDefinitions.end())
-    {
-    parser->InPPFalseBranch = 1;
-    }
-  else
-    {
-    // ignore other branches
-    parser->SkipToEnd.top() = true;
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleIf(cmDependsFortranParser* parser)
-{
-  /* Note: The current parser is _not_ able to get statements like
-   *   #if 0
-   *   #if 1
-   *   #if MYSMBOL
-   *   #if defined(MYSYMBOL)
-   *   #if defined(MYSYMBOL) && ...
-   * right.  The same for #elif.  Thus in
-   *   #if SYMBOL_1
-   *     ..
-   *   #elif SYMBOL_2
-   *     ...
-   *     ...
-   *   #elif SYMBOL_N
-   *     ..
-   *   #else
-   *     ..
-   *   #endif
-   * _all_ N+1 branches are considered.  If you got something like this
-   *   #if defined(MYSYMBOL)
-   *   #if !defined(MYSYMBOL)
-   * use
-   *   #ifdef MYSYMBOL
-   *   #ifndef MYSYMBOL
-   * instead.
-   */
-
-  // A new PP branch has been opened
-  // Never skip!  See note above.
-  parser->SkipToEnd.push(false);
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleElif(cmDependsFortranParser* parser)
-{
-  /* Note: There are parser limitations.  See the note at
-   * cmDependsFortranParser_RuleIf(..)
-   */
-
-  // Always taken unless an #ifdef or #ifndef-branch has been taken
-  // already.  If the second condition isn't meet already
-  // (parser->InPPFalseBranch == 0) correct it.
-  if(!parser->SkipToEnd.empty() &&
-     parser->SkipToEnd.top() && !parser->InPPFalseBranch)
-    {
-    parser->InPPFalseBranch = 1;
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleElse(cmDependsFortranParser* parser)
-{
-  // if the parent branch is false do nothing!
-  if(parser->InPPFalseBranch > 1)
-    {
-    return;
-    }
-
-  // parser->InPPFalseBranch is either 0 or 1.  We change it depending on
-  // parser->SkipToEnd.top()
-  if(!parser->SkipToEnd.empty() &&
-     parser->SkipToEnd.top())
-    {
-    parser->InPPFalseBranch = 1;
-    }
-  else
-    {
-    parser->InPPFalseBranch = 0;
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleEndif(cmDependsFortranParser* parser)
-{
-  if(!parser->SkipToEnd.empty())
-    {
-    parser->SkipToEnd.pop();
-    }
-
-  // #endif doesn't know if there was a "#else" in before, so it
-  // always decreases InPPFalseBranch
-  if(parser->InPPFalseBranch)
-    {
-    parser->InPPFalseBranch--;
-    }
-}
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index cb40796..a8a4013 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -9,13 +9,13 @@
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the License for more information.
 ============================================================================*/
-#ifndef cmDependsFortran_h
-#define cmDependsFortran_h
+#ifndef cmFortran_h
+#define cmFortran_h
 
 #include "cmDepends.h"
 
 class cmDependsFortranInternals;
-class cmDependsFortranSourceInfo;
+class cmFortranSourceInfo;
 
 /** \class cmDependsFortran
  * \brief Dependency scanner for Fortran object files.
@@ -46,12 +46,6 @@ public:
   static bool  ModulesDiffer(const char* modFile, const char* stampFile,
                              const char* compilerId);
 
-  /** Method to find an included file in the include path.  Fortran
-      always searches the directory containing the including source
-      first.  */
-  bool FindIncludeFile(const char* dir, const char* includeName,
-                       std::string& fileName);
-
 protected:
   // Finalize the dependency information for the target.
   virtual bool Finalize(std::ostream& makeDepends,
@@ -71,15 +65,16 @@ protected:
 
   // Actually write the depenencies to the streams.
   bool WriteDependenciesReal(const char *obj,
-                             cmDependsFortranSourceInfo const& info,
-                             const char* mod_dir, const char* stamp_dir,
+                             cmFortranSourceInfo const& info,
+                             std::string const& mod_dir,
+                             const char* stamp_dir,
                              std::ostream& makeDepends,
                              std::ostream& internalDepends);
 
   // The source file from which to start scanning.
   std::string SourceFile;
 
-  std::vector<std::string> PPDefinitions;
+  std::set<std::string> PPDefinitions;
 
   // Internal implementation details.
   cmDependsFortranInternals* Internal;
diff --git a/Source/cmDependsFortranLexer.cxx b/Source/cmDependsFortranLexer.cxx
deleted file mode 100644
index 1eff1e4..0000000
--- a/Source/cmDependsFortranLexer.cxx
+++ /dev/null
@@ -1,2414 +0,0 @@
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-#line 2 "cmDependsFortranLexer.cxx"
-
-#line 4 "cmDependsFortranLexer.cxx"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else   /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif  /* defined (__STDC__) */
-#endif  /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
-   are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-/* Enter a start condition.  This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yyg->yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state.  The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yyg->yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE cmDependsFortran_yyrestart(yyin ,yyscanner )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-    #define YY_LESS_LINENO(n)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
-        do \
-                { \
-                /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-                *yy_cp = yyg->yy_hold_char; \
-                YY_RESTORE_YY_MORE_OFFSET \
-                yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
-                YY_DO_BEFORE_ACTION; /* set up yytext again */ \
-                } \
-        while ( 0 )
-
-#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-        {
-        FILE *yy_input_file;
-
-        char *yy_ch_buf;                /* input buffer */
-        char *yy_buf_pos;               /* current position in input buffer */
-
-        /* Size of input buffer in bytes, not including room for EOB
-         * characters.
-         */
-        yy_size_t yy_buf_size;
-
-        /* Number of characters read into yy_ch_buf, not including EOB
-         * characters.
-         */
-        int yy_n_chars;
-
-        /* Whether we "own" the buffer - i.e., we know we created it,
-         * and can realloc() it to grow it, and should free() it to
-         * delete it.
-         */
-        int yy_is_our_buffer;
-
-        /* Whether this is an "interactive" input source; if so, and
-         * if we're using stdio for input, then we want to use getc()
-         * instead of fread(), to make sure we stop fetching input after
-         * each newline.
-         */
-        int yy_is_interactive;
-
-        /* Whether we're considered to be at the beginning of a line.
-         * If so, '^' rules will be active on the next match, otherwise
-         * not.
-         */
-        int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-
-        /* Whether to try to fill the input buffer when we reach the
-         * end of it.
-         */
-        int yy_fill_buffer;
-
-        int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
-        /* When an EOF's been seen but there's still some text to process
-         * then we mark the buffer as YY_EOF_PENDING, to indicate that we
-         * shouldn't try reading from the input source any more.  We might
-         * still have a bunch of tokens to match, though, because of
-         * possible backing-up.
-         *
-         * When we actually see the EOF, we change the status to "new"
-         * (via cmDependsFortran_yyrestart()), so that the user can continue scanning by
-         * just pointing yyin at a new input file.
-         */
-#define YY_BUFFER_EOF_PENDING 2
-
-        };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
-                          ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
-                          : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-
-void cmDependsFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void cmDependsFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void cmDependsFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner );
-
-static void cmDependsFortran_yyensure_buffer_stack (yyscan_t yyscanner );
-static void cmDependsFortran_yy_load_buffer_state (yyscan_t yyscanner );
-static void cmDependsFortran_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-
-#define YY_FLUSH_BUFFER cmDependsFortran_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-
-YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *cmDependsFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *cmDependsFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void cmDependsFortran_yyfree (void * ,yyscan_t yyscanner );
-
-#define yy_new_buffer cmDependsFortran_yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
-        { \
-        if ( ! YY_CURRENT_BUFFER ){ \
-        cmDependsFortran_yyensure_buffer_stack (yyscanner); \
-                YY_CURRENT_BUFFER_LVALUE =    \
-            cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
-        } \
-        YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
-        }
-
-#define yy_set_bol(at_bol) \
-        { \
-        if ( ! YY_CURRENT_BUFFER ){\
-        cmDependsFortran_yyensure_buffer_stack (yyscanner); \
-                YY_CURRENT_BUFFER_LVALUE =    \
-            cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
-        } \
-        YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
-        }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define cmDependsFortran_yywrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-typedef int yy_state_type;
-
-#define yytext_ptr yytext_r
-
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
-        yyg->yytext_ptr = yy_bp; \
-        yyleng = (size_t) (yy_cp - yy_bp); \
-        yyg->yy_hold_char = *yy_cp; \
-        *yy_cp = '\0'; \
-        yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 44
-#define YY_END_OF_BUFFER 45
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-        {
-        flex_int32_t yy_verify;
-        flex_int32_t yy_nxt;
-        };
-static yyconst flex_int16_t yy_accept[165] =
-    {   0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       45,   39,   41,   40,   43,    1,   39,   32,    2,   34,
-       39,   40,   37,   39,   38,   39,   38,   41,   39,   40,
-       39,   38,    9,    8,    9,    4,    3,   39,    0,   10,
-        0,    0,    0,    0,    0,   32,   32,   33,   35,   37,
-       39,   38,    0,   42,   38,    0,    0,    0,    0,    0,
-        0,    0,    0,   39,    0,   11,   38,    0,    0,    5,
-        0,    0,    0,   28,    0,    0,   32,   32,   32,   32,
-        0,    0,    0,    0,    0,   22,    0,    0,    0,    0,
-        0,    6,    0,    0,    0,    0,    0,    0,    0,    0,
-
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,   29,   30,    0,    0,    0,    0,    0,    0,
-        0,   23,   24,    0,    0,    0,    0,    0,    0,    0,
-        0,   31,   26,    0,    0,   19,    0,    0,   25,   20,
-        0,    0,   18,    0,    0,   17,   27,    0,    0,   16,
-       21,    0,    7,   36,    7,   14,    0,   13,   15,    0,
-        0,    0,   12,    0
-    } ;
-
-static yyconst flex_int32_t yy_ec[256] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    5,    6,    7,    8,    9,    1,   10,   11,    1,
-        1,   12,    1,   13,    1,    1,    1,   14,   14,   14,
-       14,   14,   14,   14,   14,   14,   14,   15,   16,   17,
-       18,   19,   20,    1,   21,   21,   22,   23,   24,   25,
-       21,   21,   26,   21,   21,   27,   21,   28,   21,   21,
-       21,   21,   29,   21,   30,   21,   21,   21,   21,   21,
-        1,   31,    1,    1,   32,    1,   21,   21,   33,   34,
-
-       35,   36,   21,   21,   37,   21,   21,   38,   21,   39,
-       21,   21,   21,   21,   40,   21,   41,   21,   21,   21,
-       21,   21,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
-    } ;
-
-static yyconst flex_int32_t yy_meta[42] =
-    {   0,
-        1,    2,    2,    3,    4,    3,    3,    1,    1,    3,
-        3,    1,    3,    5,    1,    3,    1,    3,    6,    1,
-        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-        1,    5,    7,    7,    7,    7,    7,    7,    7,    7,
-        7
-    } ;
-
-static yyconst flex_int16_t yy_base[174] =
-    {   0,
-        0,   40,    0,   41,  188,   48,   44,   54,   56,   65,
-      186,    0,  505,  505,  171,  505,   81,   74,  505,  505,
-      158,  505,  151,  137,    0,   85,  122,   87,  153,  145,
-      194,  226,  505,  143,   91,  505,  505,    0,  142,  505,
-      266,   34,   70,   74,   34,  122,  141,  505,    0,  505,
-      112,    0,   98,  505,    0,  154,  306,    0,   43,  133,
-      139,   46,  130,  347,  130,  505,    0,  121,  163,  179,
-      104,  156,  129,  176,  147,  178,  214,  267,  273,  292,
-      279,  179,  249,  280,  257,  265,  288,  289,  116,  107,
-      317,  505,  287,  289,  291,  302,  307,  310,  307,  311,
-
-      316,  326,  329,  333,  332,  336,  347,  345,  349,  101,
-       86,  346,  505,  505,  350,  351,  353,  350,  357,  362,
-      362,  505,  505,  367,  369,  371,  366,  372,   56,   47,
-      374,  505,  505,  374,  379,  505,  374,  387,  505,  505,
-      387,  391,  505,  117,    0,  505,  505,  392,  394,  505,
-      505,  394,  505,  505,  505,  505,  395,  419,  505,  429,
-        0,   25,  505,  505,  446,  453,  459,  462,  469,  476,
-      483,  490,  497
-    } ;
-
-static yyconst flex_int16_t yy_def[174] =
-    {   0,
-      164,    1,    1,    1,    1,    1,  165,  165,  165,  165,
-      164,  166,  164,  164,  167,  164,  166,  164,  164,  164,
-      166,  164,  164,  166,  168,  166,  168,  164,  166,  164,
-      169,  164,  164,  164,  164,  164,  164,  166,  167,  164,
-      164,  164,  164,  164,  164,  164,  170,  164,  166,  164,
-      166,  168,  164,  164,   27,  164,  164,   57,  164,  164,
-      164,  164,  164,  169,  169,  164,   32,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  170,  170,  170,  170,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  171,  172,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      173,  173,  164,    0,  164,  164,  164,  164,  164,  164,
-      164,  164,  164
-    } ;
-
-static yyconst flex_int16_t yy_nxt[547] =
-    {   0,
-       12,   13,   14,   13,   13,   15,   16,   12,   17,   18,
-       19,   12,   20,   12,   21,   22,   12,   23,   12,   24,
-       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
-       26,   27,   25,   25,   25,   25,   25,   25,   25,   25,
-       25,   28,   28,  163,   28,   28,   34,   29,   29,   28,
-       30,  145,   28,   35,   36,   29,   34,   71,   34,   31,
-      144,   76,   37,   35,   36,   35,   83,   34,   71,   32,
-       32,   37,   76,   88,   35,   46,   46,   83,   46,   47,
-       32,   32,   41,   48,   88,   41,   53,   54,   56,   53,
-      130,   56,   69,   70,   57,   69,   72,   73,   74,   53,
-
-       54,   75,   53,   42,   43,  129,   44,   72,   73,   74,
-       45,  111,   75,   81,   42,   43,   81,   44,  154,  154,
-      110,   45,   38,   46,   46,   90,   46,   47,   93,   38,
-       38,   48,   66,   38,   89,   55,   38,   82,   38,   93,
-       38,   38,   78,   46,   40,   78,   79,   68,   82,   63,
-       80,   96,   38,   55,   58,   56,   51,   58,   56,   84,
-       85,   57,   96,   86,   69,   70,   87,   69,   99,   50,
-       84,   85,   49,   40,   86,   59,   60,   87,   61,   99,
-       91,   94,   62,   91,   95,  164,   59,   60,   92,   61,
-       30,  164,   94,   62,   64,   95,   66,  164,   97,  164,
-
-      100,   64,   64,   98,  164,   64,  101,   64,   64,   97,
-       64,  100,   64,   64,   98,   78,   46,  101,   78,   79,
-      164,  164,  164,   80,   64,   64,   65,   65,   66,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65,   67,
-       65,   65,   65,   65,   65,   65,   67,   67,   67,   67,
-       67,   67,   67,   67,   67,   67,   65,   67,   67,   67,
-       67,   67,   67,   67,   67,   67,   67,   41,   78,   46,
-       41,   78,   79,  102,   78,   46,   80,   78,   79,  105,
-       81,  164,   80,   81,  102,  164,  164,  106,   42,   43,
-      105,   44,  107,   78,   46,   45,   78,   79,  106,   42,
-
-       43,   80,   44,  107,   82,  103,   45,   58,  104,  108,
-       58,  109,  112,  113,  114,   82,  103,  164,   91,  104,
-      108,   91,  109,  112,  113,  114,   92,  115,   59,   60,
-      116,   61,  117,  118,  119,   62,  164,  120,  115,   59,
-       60,  116,   61,  117,  118,  119,   62,   64,  120,   66,
-      164,  121,  164,  122,   64,   64,  123,  124,   64,  125,
-       64,   64,  121,   64,  122,   64,   64,  123,  124,  126,
-      125,  127,  128,  131,  132,  133,  134,   64,   64,  135,
-      126,  136,  127,  128,  131,  132,  133,  134,  137,  138,
-      135,  139,  136,  140,  141,  142,  143,  146,  147,  137,
-
-      138,  148,  139,  149,  140,  141,  142,  143,  146,  147,
-      150,  151,  148,  152,  149,  156,  157,  158,  159,  164,
-      160,  150,  151,  160,  152,  164,  156,  157,  158,  159,
-      160,  164,  164,  160,  164,  161,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  161,   33,   33,   33,   33,
-       33,   33,   33,   38,  164,  164,  164,   38,   38,   39,
-       39,   39,   39,   39,   39,   39,   52,  164,   52,   65,
-       65,   65,   65,   65,   65,   65,   77,   77,   77,   77,
-       77,   77,   77,  153,  153,  153,  164,  153,  153,  153,
-      155,  164,  155,  164,  155,  155,  155,  162,  162,  162,
-
-      162,  162,  164,  162,   11,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164
-    } ;
-
-static yyconst flex_int16_t yy_chk[547] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    4,  162,    2,    4,    7,    2,    4,    6,
-        6,  130,    6,    7,    7,    6,    8,   42,    9,    6,
-      129,   45,    9,    8,    8,    9,   59,   10,   42,    6,
-        6,   10,   45,   62,   10,   18,   18,   59,   18,   18,
-        6,    6,   17,   18,   62,   17,   26,   26,   28,   26,
-      111,   28,   35,   35,   28,   35,   43,   43,   44,   53,
-
-       53,   44,   53,   17,   17,  110,   17,   43,   43,   44,
-       17,   90,   44,   51,   17,   17,   51,   17,  144,  144,
-       89,   17,   27,   46,   46,   68,   46,   46,   71,   27,
-       27,   46,   65,   27,   63,   27,   27,   51,   27,   71,
-       27,   27,   47,   47,   39,   47,   47,   34,   51,   30,
-       47,   73,   27,   27,   29,   56,   24,   29,   56,   60,
-       60,   56,   73,   61,   69,   69,   61,   69,   75,   23,
-       60,   60,   21,   15,   61,   29,   29,   61,   29,   75,
-       70,   72,   29,   70,   72,   11,   29,   29,   70,   29,
-        5,    0,   72,   29,   31,   72,   31,    0,   74,    0,
-
-       76,   31,   31,   74,    0,   31,   82,   31,   31,   74,
-       31,   76,   31,   31,   74,   77,   77,   82,   77,   77,
-        0,    0,    0,   77,   31,   31,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   32,   41,   78,   78,
-       41,   78,   78,   83,   79,   79,   78,   79,   79,   85,
-       81,    0,   79,   81,   83,    0,    0,   86,   41,   41,
-       85,   41,   86,   80,   80,   41,   80,   80,   86,   41,
-
-       41,   80,   41,   86,   81,   84,   41,   57,   84,   87,
-       57,   88,   93,   94,   95,   81,   84,    0,   91,   84,
-       87,   91,   88,   93,   94,   95,   91,   96,   57,   57,
-       97,   57,   98,   99,  100,   57,    0,  101,   96,   57,
-       57,   97,   57,   98,   99,  100,   57,   64,  101,   64,
-        0,  102,    0,  103,   64,   64,  104,  105,   64,  106,
-       64,   64,  102,   64,  103,   64,   64,  104,  105,  107,
-      106,  108,  109,  112,  115,  116,  117,   64,   64,  118,
-      107,  119,  108,  109,  112,  115,  116,  117,  120,  121,
-      118,  124,  119,  125,  126,  127,  128,  131,  134,  120,
-
-      121,  135,  124,  137,  125,  126,  127,  128,  131,  134,
-      138,  141,  135,  142,  137,  148,  149,  152,  157,    0,
-      158,  138,  141,  158,  142,    0,  148,  149,  152,  157,
-      160,    0,    0,  160,    0,  158,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,  160,  165,  165,  165,  165,
-      165,  165,  165,  166,    0,    0,    0,  166,  166,  167,
-      167,  167,  167,  167,  167,  167,  168,    0,  168,  169,
-      169,  169,  169,  169,  169,  169,  170,  170,  170,  170,
-      170,  170,  170,  171,  171,  171,    0,  171,  171,  171,
-      172,    0,  172,    0,  172,  172,  172,  173,  173,  173,
-
-      173,  173,    0,  173,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
-      164,  164,  164,  164,  164,  164
-    } ;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "cmDependsFortranLexer.in.l"
-#line 2 "cmDependsFortranLexer.in.l"
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-/*-------------------------------------------------------------------------
-  Portions of this source have been derived from makedepf90 version 2.8.8,
-
-   Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann at iki.fi>
-
-  The code was originally distributed under the GPL but permission
-  from the copyright holder has been obtained to distribute this
-  derived work under the CMake license.
--------------------------------------------------------------------------*/
-
-/*
-
-This file must be translated to C and modified to build everywhere.
-
-Run flex like this:
-
-  flex -i --prefix=cmDependsFortran_yy --header-file=cmDependsFortranLexer.h -ocmDependsFortranLexer.cxx cmDependsFortranLexer.in.l
-
-Modify cmDependsFortranLexer.cxx:
-  - remove TABs
-  - remove "yyscanner" argument from these methods:
-      yy_fatal_error, cmDependsFortran_yyalloc, cmDependsFortran_yyrealloc, cmDependsFortran_yyfree
-  - remove "yyscanner = NULL" from end of cmDependsFortran_yylex_destroy
-  - remove all YY_BREAK lines occurring right after return statements
-  - change while ( 1 ) to for(;;)
-
-Modify cmDependsFortranLexer.h:
-  - remove TABs
-  - remove the yy_init_globals function
-  - remove the block that includes unistd.h
-  - remove #line directives (avoids bogus warning on old Sun)
-
-*/
-
-#include "cmStandardLexer.h"
-
-#define cmDependsFortranLexer_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object.  */
-
-/* Replace the lexer input function.  */
-#undef YY_INPUT
-#define YY_INPUT(buf, result, max_size) \
-  { result = cmDependsFortranParser_Input(yyextra, buf, max_size); }
-
-/* Include the set of tokens from the parser.  */
-#include "cmDependsFortranParserTokens.h"
-
-/*--------------------------------------------------------------------------*/
-
-
-#line 678 "cmDependsFortranLexer.cxx"
-
-#define INITIAL 0
-#define free_fmt 1
-#define fixed_fmt 2
-#define str_sq 3
-#define str_dq 4
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-/* Holds the entire state of the reentrant scanner. */
-struct yyguts_t
-    {
-
-    /* User-defined. Not touched by flex. */
-    YY_EXTRA_TYPE yyextra_r;
-
-    /* The rest are the same as the globals declared in the non-reentrant scanner. */
-    FILE *yyin_r, *yyout_r;
-    size_t yy_buffer_stack_top; /**< index of top of stack. */
-    size_t yy_buffer_stack_max; /**< capacity of stack. */
-    YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
-    char yy_hold_char;
-    int yy_n_chars;
-    int yyleng_r;
-    char *yy_c_buf_p;
-    int yy_init;
-    int yy_start;
-    int yy_did_buffer_switch_on_eof;
-    int yy_start_stack_ptr;
-    int yy_start_stack_depth;
-    int *yy_start_stack;
-    yy_state_type yy_last_accepting_state;
-    char* yy_last_accepting_cpos;
-
-    int yylineno_r;
-    int yy_flex_debug_r;
-
-    char *yytext_r;
-    int yy_more_flag;
-    int yy_more_len;
-
-    }; /* end struct yyguts_t */
-
-static int yy_init_globals (yyscan_t yyscanner );
-
-int cmDependsFortran_yylex_init (yyscan_t* scanner);
-
-int cmDependsFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int cmDependsFortran_yylex_destroy (yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_debug (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE cmDependsFortran_yyget_extra (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *cmDependsFortran_yyget_in (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_in  (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *cmDependsFortran_yyget_out (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_out  (FILE * out_str ,yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_leng (yyscan_t yyscanner );
-
-char *cmDependsFortran_yyget_text (yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_lineno (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int cmDependsFortran_yywrap (yyscan_t yyscanner );
-#else
-extern int cmDependsFortran_yywrap (yyscan_t yyscanner );
-#endif
-#endif
-
-    static void yyunput (int c,char *buf_ptr  ,yyscan_t yyscanner);
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
-#else
-static int input (yyscan_t yyscanner );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
-#endif
-
-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-        if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-                { \
-                int c = '*'; \
-                size_t n; \
-                for ( n = 0; n < max_size && \
-                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
-                        buf[n] = (char) c; \
-                if ( c == '\n' ) \
-                        buf[n++] = (char) c; \
-                if ( c == EOF && ferror( yyin ) ) \
-                        YY_FATAL_ERROR( "input in flex scanner failed" ); \
-                result = n; \
-                } \
-        else \
-                { \
-                errno=0; \
-                while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-                        { \
-                        if( errno != EINTR) \
-                                { \
-                                YY_FATAL_ERROR( "input in flex scanner failed" ); \
-                                break; \
-                                } \
-                        errno=0; \
-                        clearerr(yyin); \
-                        } \
-                }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int cmDependsFortran_yylex (yyscan_t yyscanner);
-
-#define YY_DECL int cmDependsFortran_yylex (yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
-        if ( yyleng > 0 ) \
-                YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
-                                (yytext[yyleng - 1] == '\n'); \
-        YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
-        yy_state_type yy_current_state;
-        char *yy_cp, *yy_bp;
-        int yy_act;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-#line 71 "cmDependsFortranLexer.in.l"
-
-
-#line 914 "cmDependsFortranLexer.cxx"
-
-        if ( !yyg->yy_init )
-                {
-                yyg->yy_init = 1;
-
-#ifdef YY_USER_INIT
-                YY_USER_INIT;
-#endif
-
-                if ( ! yyg->yy_start )
-                        yyg->yy_start = 1;      /* first start state */
-
-                if ( ! yyin )
-                        yyin = stdin;
-
-                if ( ! yyout )
-                        yyout = stdout;
-
-                if ( ! YY_CURRENT_BUFFER ) {
-                        cmDependsFortran_yyensure_buffer_stack (yyscanner);
-                        YY_CURRENT_BUFFER_LVALUE =
-                                cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
-                }
-
-                cmDependsFortran_yy_load_buffer_state(yyscanner );
-                }
-
-        for(;;)             /* loops until end-of-file is reached */
-                {
-                yy_cp = yyg->yy_c_buf_p;
-
-                /* Support of yytext. */
-                *yy_cp = yyg->yy_hold_char;
-
-                /* yy_bp points to the position in yy_ch_buf of the start of
-                 * the current run.
-                 */
-                yy_bp = yy_cp;
-
-                yy_current_state = yyg->yy_start;
-                yy_current_state += YY_AT_BOL();
-yy_match:
-                do
-                        {
-                        YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
-                        if ( yy_accept[yy_current_state] )
-                                {
-                                yyg->yy_last_accepting_state = yy_current_state;
-                                yyg->yy_last_accepting_cpos = yy_cp;
-                                }
-                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-                                {
-                                yy_current_state = (int) yy_def[yy_current_state];
-                                if ( yy_current_state >= 165 )
-                                        yy_c = yy_meta[(unsigned int) yy_c];
-                                }
-                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-                        ++yy_cp;
-                        }
-                while ( yy_base[yy_current_state] != 505 );
-
-yy_find_action:
-                yy_act = yy_accept[yy_current_state];
-                if ( yy_act == 0 )
-                        { /* have to back up */
-                        yy_cp = yyg->yy_last_accepting_cpos;
-                        yy_current_state = yyg->yy_last_accepting_state;
-                        yy_act = yy_accept[yy_current_state];
-                        }
-
-                YY_DO_BEFORE_ACTION;
-
-do_action:      /* This label is used only to access EOF actions. */
-
-                switch ( yy_act )
-        { /* beginning of action switch */
-                        case 0: /* must back up */
-                        /* undo the effects of YY_DO_BEFORE_ACTION */
-                        *yy_cp = yyg->yy_hold_char;
-                        yy_cp = yyg->yy_last_accepting_cpos;
-                        yy_current_state = yyg->yy_last_accepting_state;
-                        goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 73 "cmDependsFortranLexer.in.l"
-{
-  cmDependsFortranParser_StringStart(yyextra);
-  cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
-  BEGIN(str_dq);
-}
-        YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 79 "cmDependsFortranLexer.in.l"
-{
-  cmDependsFortranParser_StringStart(yyextra);
-  cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
-  BEGIN(str_sq);
-}
-        YY_BREAK
-case 3:
-#line 86 "cmDependsFortranLexer.in.l"
-case 4:
-YY_RULE_SETUP
-#line 86 "cmDependsFortranLexer.in.l"
-{
-  BEGIN(cmDependsFortranParser_GetOldStartcond(yyextra) );
-  yylvalp->string = strdup(cmDependsFortranParser_StringEnd(yyextra));
-  return STRING;
-}
-case 5:
-/* rule 5 can match eol */
-#line 93 "cmDependsFortranLexer.in.l"
-case 6:
-/* rule 6 can match eol */
-YY_RULE_SETUP
-#line 93 "cmDependsFortranLexer.in.l"
-/* Ignore (continued strings, free fmt) */
-        YY_BREAK
-case 7:
-/* rule 7 can match eol */
-YY_RULE_SETUP
-#line 95 "cmDependsFortranLexer.in.l"
-{
-  if (cmDependsFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
-    ; /* Ignore (cont. strings, fixed fmt) */
-  else
-    {
-    unput(yytext[strlen(yytext)-1]);
-    }
-}
-        YY_BREAK
-case 8:
-/* rule 8 can match eol */
-YY_RULE_SETUP
-#line 105 "cmDependsFortranLexer.in.l"
-{
-  unput ('\n');
-  BEGIN(INITIAL);
-  return UNTERMINATED_STRING;
-}
-case 9:
-YY_RULE_SETUP
-#line 111 "cmDependsFortranLexer.in.l"
-{
-  cmDependsFortranParser_StringAppend(yyextra, yytext[0]);
-}
-        YY_BREAK
-case 10:
-/* rule 10 can match eol */
-YY_RULE_SETUP
-#line 115 "cmDependsFortranLexer.in.l"
-{ return EOSTMT; } /* Treat comments like */
-case 11:
-/* rule 11 can match eol */
-YY_RULE_SETUP
-#line 116 "cmDependsFortranLexer.in.l"
-{ return EOSTMT; } /* empty lines */
-case 12:
-/* rule 12 can match eol */
-YY_RULE_SETUP
-#line 118 "cmDependsFortranLexer.in.l"
-{
-  yytext[yyleng-1] = 0;
-  yylvalp->string = strdup(strchr(yytext, '<')+1);
-  return CPP_INCLUDE_ANGLE;
-}
-case 13:
-YY_RULE_SETUP
-#line 123 "cmDependsFortranLexer.in.l"
-{ return CPP_INCLUDE; }
-case 14:
-YY_RULE_SETUP
-#line 124 "cmDependsFortranLexer.in.l"
-{ return F90PPR_INCLUDE; }
-case 15:
-YY_RULE_SETUP
-#line 125 "cmDependsFortranLexer.in.l"
-{ return COCO_INCLUDE; }
-case 16:
-YY_RULE_SETUP
-#line 127 "cmDependsFortranLexer.in.l"
-{ return CPP_DEFINE; }
-case 17:
-YY_RULE_SETUP
-#line 128 "cmDependsFortranLexer.in.l"
-{ return F90PPR_DEFINE; }
-case 18:
-YY_RULE_SETUP
-#line 130 "cmDependsFortranLexer.in.l"
-{ return CPP_UNDEF; }
-case 19:
-YY_RULE_SETUP
-#line 131 "cmDependsFortranLexer.in.l"
-{ return F90PPR_UNDEF; }
-case 20:
-YY_RULE_SETUP
-#line 133 "cmDependsFortranLexer.in.l"
-{ return CPP_IFDEF; }
-case 21:
-YY_RULE_SETUP
-#line 134 "cmDependsFortranLexer.in.l"
-{ return CPP_IFNDEF; }
-case 22:
-YY_RULE_SETUP
-#line 135 "cmDependsFortranLexer.in.l"
-{ return CPP_IF; }
-case 23:
-YY_RULE_SETUP
-#line 136 "cmDependsFortranLexer.in.l"
-{ return CPP_ELIF; }
-case 24:
-YY_RULE_SETUP
-#line 137 "cmDependsFortranLexer.in.l"
-{ return CPP_ELSE; }
-case 25:
-YY_RULE_SETUP
-#line 138 "cmDependsFortranLexer.in.l"
-{ return CPP_ENDIF; }
-case 26:
-YY_RULE_SETUP
-#line 140 "cmDependsFortranLexer.in.l"
-{ return F90PPR_IFDEF; }
-case 27:
-YY_RULE_SETUP
-#line 141 "cmDependsFortranLexer.in.l"
-{ return F90PPR_IFNDEF; }
-case 28:
-YY_RULE_SETUP
-#line 142 "cmDependsFortranLexer.in.l"
-{ return F90PPR_IF; }
-case 29:
-YY_RULE_SETUP
-#line 143 "cmDependsFortranLexer.in.l"
-{ return F90PPR_ELIF; }
-case 30:
-YY_RULE_SETUP
-#line 144 "cmDependsFortranLexer.in.l"
-{ return F90PPR_ELSE; }
-case 31:
-YY_RULE_SETUP
-#line 145 "cmDependsFortranLexer.in.l"
-{ return F90PPR_ENDIF; }
-/* Line continuations, possible involving comments.  */
-case 32:
-/* rule 32 can match eol */
-YY_RULE_SETUP
-#line 148 "cmDependsFortranLexer.in.l"
-
-        YY_BREAK
-case 33:
-/* rule 33 can match eol */
-YY_RULE_SETUP
-#line 149 "cmDependsFortranLexer.in.l"
-
-        YY_BREAK
-case 34:
-YY_RULE_SETUP
-#line 151 "cmDependsFortranLexer.in.l"
-{ return COMMA; }
-case 35:
-YY_RULE_SETUP
-#line 153 "cmDependsFortranLexer.in.l"
-{ return DCOLON; }
-case 36:
-/* rule 36 can match eol */
-YY_RULE_SETUP
-#line 155 "cmDependsFortranLexer.in.l"
-{ return GARBAGE; }
-case 37:
-YY_RULE_SETUP
-#line 157 "cmDependsFortranLexer.in.l"
-{ return ASSIGNMENT_OP; }
-case 38:
-YY_RULE_SETUP
-#line 159 "cmDependsFortranLexer.in.l"
-{
-  yylvalp->string = strdup(yytext);
-  return WORD;
-}
-case 39:
-YY_RULE_SETUP
-#line 164 "cmDependsFortranLexer.in.l"
-{ return GARBAGE; }
-case 40:
-/* rule 40 can match eol */
-YY_RULE_SETUP
-#line 166 "cmDependsFortranLexer.in.l"
-{ return EOSTMT; }
-case 41:
-YY_RULE_SETUP
-#line 169 "cmDependsFortranLexer.in.l"
-/* Ignore */
-        YY_BREAK
-case 42:
-/* rule 42 can match eol */
-YY_RULE_SETUP
-#line 170 "cmDependsFortranLexer.in.l"
-/* Ignore line-endings preceeded by \ */
-        YY_BREAK
-case 43:
-YY_RULE_SETUP
-#line 172 "cmDependsFortranLexer.in.l"
-{ return *yytext; }
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(free_fmt):
-case YY_STATE_EOF(fixed_fmt):
-case YY_STATE_EOF(str_sq):
-case YY_STATE_EOF(str_dq):
-#line 174 "cmDependsFortranLexer.in.l"
-{
-  if(!cmDependsFortranParser_FilePop(yyextra) )
-    {
-    return YY_NULL;
-    }
-}
-        YY_BREAK
-case 44:
-YY_RULE_SETUP
-#line 181 "cmDependsFortranLexer.in.l"
-ECHO;
-        YY_BREAK
-#line 1270 "cmDependsFortranLexer.cxx"
-
-        case YY_END_OF_BUFFER:
-                {
-                /* Amount of text matched not including the EOB char. */
-                int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
-
-                /* Undo the effects of YY_DO_BEFORE_ACTION. */
-                *yy_cp = yyg->yy_hold_char;
-                YY_RESTORE_YY_MORE_OFFSET
-
-                if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
-                        {
-                        /* We're scanning a new file or input source.  It's
-                         * possible that this happened because the user
-                         * just pointed yyin at a new source and called
-                         * cmDependsFortran_yylex().  If so, then we have to assure
-                         * consistency between YY_CURRENT_BUFFER and our
-                         * globals.  Here is the right place to do so, because
-                         * this is the first action (other than possibly a
-                         * back-up) that will match for the new input source.
-                         */
-                        yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-                        YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-                        YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
-                        }
-
-                /* Note that here we test for yy_c_buf_p "<=" to the position
-                 * of the first EOB in the buffer, since yy_c_buf_p will
-                 * already have been incremented past the NUL character
-                 * (since all states make transitions on EOB to the
-                 * end-of-buffer state).  Contrast this with the test
-                 * in input().
-                 */
-                if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
-                        { /* This was really a NUL. */
-                        yy_state_type yy_next_state;
-
-                        yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
-
-                        yy_current_state = yy_get_previous_state( yyscanner );
-
-                        /* Okay, we're now positioned to make the NUL
-                         * transition.  We couldn't have
-                         * yy_get_previous_state() go ahead and do it
-                         * for us because it doesn't know how to deal
-                         * with the possibility of jamming (and we don't
-                         * want to build jamming into it because then it
-                         * will run more slowly).
-                         */
-
-                        yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
-
-                        yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-
-                        if ( yy_next_state )
-                                {
-                                /* Consume the NUL. */
-                                yy_cp = ++yyg->yy_c_buf_p;
-                                yy_current_state = yy_next_state;
-                                goto yy_match;
-                                }
-
-                        else
-                                {
-                                yy_cp = yyg->yy_c_buf_p;
-                                goto yy_find_action;
-                                }
-                        }
-
-                else switch ( yy_get_next_buffer( yyscanner ) )
-                        {
-                        case EOB_ACT_END_OF_FILE:
-                                {
-                                yyg->yy_did_buffer_switch_on_eof = 0;
-
-                                if ( cmDependsFortran_yywrap(yyscanner ) )
-                                        {
-                                        /* Note: because we've taken care in
-                                         * yy_get_next_buffer() to have set up
-                                         * yytext, we can now set up
-                                         * yy_c_buf_p so that if some total
-                                         * hoser (like flex itself) wants to
-                                         * call the scanner after we return the
-                                         * YY_NULL, it'll still work - another
-                                         * YY_NULL will get returned.
-                                         */
-                                        yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
-
-                                        yy_act = YY_STATE_EOF(YY_START);
-                                        goto do_action;
-                                        }
-
-                                else
-                                        {
-                                        if ( ! yyg->yy_did_buffer_switch_on_eof )
-                                                YY_NEW_FILE;
-                                        }
-                                break;
-                                }
-
-                        case EOB_ACT_CONTINUE_SCAN:
-                                yyg->yy_c_buf_p =
-                                        yyg->yytext_ptr + yy_amount_of_matched_text;
-
-                                yy_current_state = yy_get_previous_state( yyscanner );
-
-                                yy_cp = yyg->yy_c_buf_p;
-                                yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-                                goto yy_match;
-
-                        case EOB_ACT_LAST_MATCH:
-                                yyg->yy_c_buf_p =
-                                &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
-
-                                yy_current_state = yy_get_previous_state( yyscanner );
-
-                                yy_cp = yyg->yy_c_buf_p;
-                                yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-                                goto yy_find_action;
-                        }
-                break;
-                }
-
-        default:
-                YY_FATAL_ERROR(
-                        "fatal flex scanner internal error--no action found" );
-        } /* end of action switch */
-                } /* end of scanning one token */
-} /* end of cmDependsFortran_yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- *      EOB_ACT_LAST_MATCH -
- *      EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- *      EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-        char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-        char *source = yyg->yytext_ptr;
-        int number_to_move, i;
-        int ret_val;
-
-        if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
-                YY_FATAL_ERROR(
-                "fatal flex scanner internal error--end of buffer missed" );
-
-        if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
-                { /* Don't try to fill the buffer, so this is an EOF. */
-                if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
-                        {
-                        /* We matched a single character, the EOB, so
-                         * treat this as a final EOF.
-                         */
-                        return EOB_ACT_END_OF_FILE;
-                        }
-
-                else
-                        {
-                        /* We matched some text prior to the EOB, first
-                         * process it.
-                         */
-                        return EOB_ACT_LAST_MATCH;
-                        }
-                }
-
-        /* Try to read more data. */
-
-        /* First move last chars to start of buffer. */
-        number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
-
-        for ( i = 0; i < number_to_move; ++i )
-                *(dest++) = *(source++);
-
-        if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
-                /* don't do the read, it's not guaranteed to return an EOF,
-                 * just force an EOF
-                 */
-                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
-
-        else
-                {
-                        int num_to_read =
-                        YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
-                while ( num_to_read <= 0 )
-                        { /* Not enough room in the buffer - grow it. */
-
-                        /* just a shorter name for the current buffer */
-                        YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
-                        int yy_c_buf_p_offset =
-                                (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
-
-                        if ( b->yy_is_our_buffer )
-                                {
-                                int new_size = b->yy_buf_size * 2;
-
-                                if ( new_size <= 0 )
-                                        b->yy_buf_size += b->yy_buf_size / 8;
-                                else
-                                        b->yy_buf_size *= 2;
-
-                                b->yy_ch_buf = (char *)
-                                        /* Include room in for 2 EOB chars. */
-                                        cmDependsFortran_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
-                                }
-                        else
-                                /* Can't grow it, we don't own it. */
-                                b->yy_ch_buf = 0;
-
-                        if ( ! b->yy_ch_buf )
-                                YY_FATAL_ERROR(
-                                "fatal error - scanner input buffer overflow" );
-
-                        yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
-                        num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-                                                number_to_move - 1;
-
-                        }
-
-                if ( num_to_read > YY_READ_BUF_SIZE )
-                        num_to_read = YY_READ_BUF_SIZE;
-
-                /* Read in more data. */
-                YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                        yyg->yy_n_chars, (size_t) num_to_read );
-
-                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
-                }
-
-        if ( yyg->yy_n_chars == 0 )
-                {
-                if ( number_to_move == YY_MORE_ADJ )
-                        {
-                        ret_val = EOB_ACT_END_OF_FILE;
-                        cmDependsFortran_yyrestart(yyin  ,yyscanner);
-                        }
-
-                else
-                        {
-                        ret_val = EOB_ACT_LAST_MATCH;
-                        YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
-                                YY_BUFFER_EOF_PENDING;
-                        }
-                }
-
-        else
-                ret_val = EOB_ACT_CONTINUE_SCAN;
-
-        if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
-                /* Extend the array by 50%, plus the number we really need. */
-                yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
-                YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cmDependsFortran_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
-                if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-                        YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
-        }
-
-        yyg->yy_n_chars += number_to_move;
-        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
-        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
-        yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
-        return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-    static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
-{
-        yy_state_type yy_current_state;
-        char *yy_cp;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        yy_current_state = yyg->yy_start;
-        yy_current_state += YY_AT_BOL();
-
-        for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
-                {
-                YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
-                if ( yy_accept[yy_current_state] )
-                        {
-                        yyg->yy_last_accepting_state = yy_current_state;
-                        yyg->yy_last_accepting_cpos = yy_cp;
-                        }
-                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-                        {
-                        yy_current_state = (int) yy_def[yy_current_state];
-                        if ( yy_current_state >= 165 )
-                                yy_c = yy_meta[(unsigned int) yy_c];
-                        }
-                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-                }
-
-        return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- *      next_state = yy_try_NUL_trans( current_state );
- */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
-{
-        int yy_is_jam;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
-        char *yy_cp = yyg->yy_c_buf_p;
-
-        YY_CHAR yy_c = 1;
-        if ( yy_accept[yy_current_state] )
-                {
-                yyg->yy_last_accepting_state = yy_current_state;
-                yyg->yy_last_accepting_cpos = yy_cp;
-                }
-        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-                {
-                yy_current_state = (int) yy_def[yy_current_state];
-                if ( yy_current_state >= 165 )
-                        yy_c = yy_meta[(unsigned int) yy_c];
-                }
-        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-        yy_is_jam = (yy_current_state == 164);
-
-        return yy_is_jam ? 0 : yy_current_state;
-}
-
-    static void yyunput (int c, char * yy_bp , yyscan_t yyscanner)
-{
-        char *yy_cp;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-    yy_cp = yyg->yy_c_buf_p;
-
-        /* undo effects of setting up yytext */
-        *yy_cp = yyg->yy_hold_char;
-
-        if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-                { /* need to shift things up to make room */
-                /* +2 for EOB chars. */
-                int number_to_move = yyg->yy_n_chars + 2;
-                char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-                                        YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
-                char *source =
-                                &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
-                while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-                        *--dest = *--source;
-
-                yy_cp += (int) (dest - source);
-                yy_bp += (int) (dest - source);
-                YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-                        yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
-                if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-                        YY_FATAL_ERROR( "flex scanner push-back overflow" );
-                }
-
-        *--yy_cp = (char) c;
-
-        yyg->yytext_ptr = yy_bp;
-        yyg->yy_hold_char = *yy_cp;
-        yyg->yy_c_buf_p = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (yyscan_t yyscanner)
-#else
-    static int input  (yyscan_t yyscanner)
-#endif
-
-{
-        int c;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        *yyg->yy_c_buf_p = yyg->yy_hold_char;
-
-        if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
-                {
-                /* yy_c_buf_p now points to the character we want to return.
-                 * If this occurs *before* the EOB characters, then it's a
-                 * valid NUL; if not, then we've hit the end of the buffer.
-                 */
-                if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
-                        /* This was really a NUL. */
-                        *yyg->yy_c_buf_p = '\0';
-
-                else
-                        { /* need more input */
-                        int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
-                        ++yyg->yy_c_buf_p;
-
-                        switch ( yy_get_next_buffer( yyscanner ) )
-                                {
-                                case EOB_ACT_LAST_MATCH:
-                                        /* This happens because yy_g_n_b()
-                                         * sees that we've accumulated a
-                                         * token and flags that we need to
-                                         * try matching the token before
-                                         * proceeding.  But for input(),
-                                         * there's no matching to consider.
-                                         * So convert the EOB_ACT_LAST_MATCH
-                                         * to EOB_ACT_END_OF_FILE.
-                                         */
-
-                                        /* Reset buffer status. */
-                                        cmDependsFortran_yyrestart(yyin ,yyscanner);
-
-                                        /*FALLTHROUGH*/
-
-                                case EOB_ACT_END_OF_FILE:
-                                        {
-                                        if ( cmDependsFortran_yywrap(yyscanner ) )
-                                                return EOF;
-
-                                        if ( ! yyg->yy_did_buffer_switch_on_eof )
-                                                YY_NEW_FILE;
-#ifdef __cplusplus
-                                        return yyinput(yyscanner);
-#else
-                                        return input(yyscanner);
-#endif
-                                        }
-
-                                case EOB_ACT_CONTINUE_SCAN:
-                                        yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
-                                        break;
-                                }
-                        }
-                }
-
-        c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
-        *yyg->yy_c_buf_p = '\0';        /* preserve yytext */
-        yyg->yy_hold_char = *++yyg->yy_c_buf_p;
-
-        YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
-
-        return c;
-}
-#endif  /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * @param yyscanner The scanner object.
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void cmDependsFortran_yyrestart  (FILE * input_file , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        if ( ! YY_CURRENT_BUFFER ){
-        cmDependsFortran_yyensure_buffer_stack (yyscanner);
-                YY_CURRENT_BUFFER_LVALUE =
-            cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
-        }
-
-        cmDependsFortran_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
-        cmDependsFortran_yy_load_buffer_state(yyscanner );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * @param yyscanner The scanner object.
- */
-    void cmDependsFortran_yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        /* TODO. We should be able to replace this entire function body
-         * with
-         *              cmDependsFortran_yypop_buffer_state();
-         *              cmDependsFortran_yypush_buffer_state(new_buffer);
-     */
-        cmDependsFortran_yyensure_buffer_stack (yyscanner);
-        if ( YY_CURRENT_BUFFER == new_buffer )
-                return;
-
-        if ( YY_CURRENT_BUFFER )
-                {
-                /* Flush out information for old buffer. */
-                *yyg->yy_c_buf_p = yyg->yy_hold_char;
-                YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
-                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
-                }
-
-        YY_CURRENT_BUFFER_LVALUE = new_buffer;
-        cmDependsFortran_yy_load_buffer_state(yyscanner );
-
-        /* We don't actually know whether we did this switch during
-         * EOF (cmDependsFortran_yywrap()) processing, but the only time this flag
-         * is looked at is after cmDependsFortran_yywrap() is called, so it's safe
-         * to go ahead and always set it.
-         */
-        yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-static void cmDependsFortran_yy_load_buffer_state  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-        yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-        yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-        yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-        yyg->yy_hold_char = *yyg->yy_c_buf_p;
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * @param yyscanner The scanner object.
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE cmDependsFortran_yy_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
-{
-        YY_BUFFER_STATE b;
-
-        b = (YY_BUFFER_STATE) cmDependsFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
-        if ( ! b )
-                YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_create_buffer()" );
-
-        b->yy_buf_size = size;
-
-        /* yy_ch_buf has to be 2 characters longer than the size given because
-         * we need to put in 2 end-of-buffer characters.
-         */
-        b->yy_ch_buf = (char *) cmDependsFortran_yyalloc(b->yy_buf_size + 2 ,yyscanner );
-        if ( ! b->yy_ch_buf )
-                YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_create_buffer()" );
-
-        b->yy_is_our_buffer = 1;
-
-        cmDependsFortran_yy_init_buffer(b,file ,yyscanner);
-
-        return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with cmDependsFortran_yy_create_buffer()
- * @param yyscanner The scanner object.
- */
-    void cmDependsFortran_yy_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        if ( ! b )
-                return;
-
-        if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-                YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
-        if ( b->yy_is_our_buffer )
-                cmDependsFortran_yyfree((void *) b->yy_ch_buf ,yyscanner );
-
-        cmDependsFortran_yyfree((void *) b ,yyscanner );
-}
-
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a cmDependsFortran_yyrestart() or at EOF.
- */
-    static void cmDependsFortran_yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)
-
-{
-        int oerrno = errno;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        cmDependsFortran_yy_flush_buffer(b ,yyscanner);
-
-        b->yy_input_file = file;
-        b->yy_fill_buffer = 1;
-
-    /* If b is the current buffer, then cmDependsFortran_yy_init_buffer was _probably_
-     * called from cmDependsFortran_yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
-
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-
-        errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * @param yyscanner The scanner object.
- */
-    void cmDependsFortran_yy_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-        if ( ! b )
-                return;
-
-        b->yy_n_chars = 0;
-
-        /* We always need two end-of-buffer characters.  The first causes
-         * a transition to the end-of-buffer state.  The second causes
-         * a jam in that state.
-         */
-        b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
-        b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
-        b->yy_buf_pos = &b->yy_ch_buf[0];
-
-        b->yy_at_bol = 1;
-        b->yy_buffer_status = YY_BUFFER_NEW;
-
-        if ( b == YY_CURRENT_BUFFER )
-                cmDependsFortran_yy_load_buffer_state(yyscanner );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  @param yyscanner The scanner object.
- */
-void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-        if (new_buffer == NULL)
-                return;
-
-        cmDependsFortran_yyensure_buffer_stack(yyscanner);
-
-        /* This block is copied from cmDependsFortran_yy_switch_to_buffer. */
-        if ( YY_CURRENT_BUFFER )
-                {
-                /* Flush out information for old buffer. */
-                *yyg->yy_c_buf_p = yyg->yy_hold_char;
-                YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
-                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
-                }
-
-        /* Only push if top exists. Otherwise, replace top. */
-        if (YY_CURRENT_BUFFER)
-                yyg->yy_buffer_stack_top++;
-        YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-        /* copied from cmDependsFortran_yy_switch_to_buffer. */
-        cmDependsFortran_yy_load_buffer_state(yyscanner );
-        yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  @param yyscanner The scanner object.
- */
-void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-        if (!YY_CURRENT_BUFFER)
-                return;
-
-        cmDependsFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
-        YY_CURRENT_BUFFER_LVALUE = NULL;
-        if (yyg->yy_buffer_stack_top > 0)
-                --yyg->yy_buffer_stack_top;
-
-        if (YY_CURRENT_BUFFER) {
-                cmDependsFortran_yy_load_buffer_state(yyscanner );
-                yyg->yy_did_buffer_switch_on_eof = 1;
-        }
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void cmDependsFortran_yyensure_buffer_stack (yyscan_t yyscanner)
-{
-        int num_to_alloc;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        if (!yyg->yy_buffer_stack) {
-
-                /* First allocation is just for 2 elements, since we don't know if this
-                 * scanner will even need a stack. We use 2 instead of 1 to avoid an
-                 * immediate realloc on the next call.
-         */
-                num_to_alloc = 1;
-                yyg->yy_buffer_stack = (struct yy_buffer_state**)cmDependsFortran_yyalloc
-                                                                (num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                                , yyscanner);
-                if ( ! yyg->yy_buffer_stack )
-                        YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yyensure_buffer_stack()" );
-
-                memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
-                yyg->yy_buffer_stack_max = num_to_alloc;
-                yyg->yy_buffer_stack_top = 0;
-                return;
-        }
-
-        if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
-
-                /* Increase the buffer to prepare for a possible push. */
-                int grow_size = 8 /* arbitrary grow size */;
-
-                num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
-                yyg->yy_buffer_stack = (struct yy_buffer_state**)cmDependsFortran_yyrealloc
-                                                                (yyg->yy_buffer_stack,
-                                                                num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                                , yyscanner);
-                if ( ! yyg->yy_buffer_stack )
-                        YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yyensure_buffer_stack()" );
-
-                /* zero only the new slots.*/
-                memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
-                yyg->yy_buffer_stack_max = num_to_alloc;
-        }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
-{
-        YY_BUFFER_STATE b;
-
-        if ( size < 2 ||
-             base[size-2] != YY_END_OF_BUFFER_CHAR ||
-             base[size-1] != YY_END_OF_BUFFER_CHAR )
-                /* They forgot to leave room for the EOB's. */
-                return 0;
-
-        b = (YY_BUFFER_STATE) cmDependsFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
-        if ( ! b )
-                YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_scan_buffer()" );
-
-        b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
-        b->yy_buf_pos = b->yy_ch_buf = base;
-        b->yy_is_our_buffer = 0;
-        b->yy_input_file = 0;
-        b->yy_n_chars = b->yy_buf_size;
-        b->yy_is_interactive = 0;
-        b->yy_at_bol = 1;
-        b->yy_fill_buffer = 0;
-        b->yy_buffer_status = YY_BUFFER_NEW;
-
-        cmDependsFortran_yy_switch_to_buffer(b ,yyscanner );
-
-        return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to cmDependsFortran_yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       cmDependsFortran_yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE cmDependsFortran_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
-{
-
-        return cmDependsFortran_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to cmDependsFortran_yylex() will
- * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
-{
-        YY_BUFFER_STATE b;
-        char *buf;
-        yy_size_t n;
-        int i;
-
-        /* Get memory for full buffer, including space for trailing EOB's. */
-        n = _yybytes_len + 2;
-        buf = (char *) cmDependsFortran_yyalloc(n ,yyscanner );
-        if ( ! buf )
-                YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_scan_bytes()" );
-
-        for ( i = 0; i < _yybytes_len; ++i )
-                buf[i] = yybytes[i];
-
-        buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
-        b = cmDependsFortran_yy_scan_buffer(buf,n ,yyscanner);
-        if ( ! b )
-                YY_FATAL_ERROR( "bad buffer in cmDependsFortran_yy_scan_bytes()" );
-
-        /* It's okay to grow etc. this buffer, and we should throw it
-         * away when we're done.
-         */
-        b->yy_is_our_buffer = 1;
-
-        return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg , yyscan_t)
-{
-        (void) fprintf( stderr, "%s\n", msg );
-        exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
-        do \
-                { \
-                /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-                yytext[yyleng] = yyg->yy_hold_char; \
-                yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
-                yyg->yy_hold_char = *yyg->yy_c_buf_p; \
-                *yyg->yy_c_buf_p = '\0'; \
-                yyleng = yyless_macro_arg; \
-                } \
-        while ( 0 )
-
-/* Accessor  methods (get/set functions) to struct members. */
-
-/** Get the user-defined data for this scanner.
- * @param yyscanner The scanner object.
- */
-YY_EXTRA_TYPE cmDependsFortran_yyget_extra  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yyextra;
-}
-
-/** Get the current line number.
- * @param yyscanner The scanner object.
- */
-int cmDependsFortran_yyget_lineno  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        if (! YY_CURRENT_BUFFER)
-            return 0;
-
-    return yylineno;
-}
-
-/** Get the current column number.
- * @param yyscanner The scanner object.
- */
-int cmDependsFortran_yyget_column  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        if (! YY_CURRENT_BUFFER)
-            return 0;
-
-    return yycolumn;
-}
-
-/** Get the input stream.
- * @param yyscanner The scanner object.
- */
-FILE *cmDependsFortran_yyget_in  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yyin;
-}
-
-/** Get the output stream.
- * @param yyscanner The scanner object.
- */
-FILE *cmDependsFortran_yyget_out  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yyout;
-}
-
-/** Get the length of the current token.
- * @param yyscanner The scanner object.
- */
-int cmDependsFortran_yyget_leng  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yyleng;
-}
-
-/** Get the current token.
- * @param yyscanner The scanner object.
- */
-
-char *cmDependsFortran_yyget_text  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yytext;
-}
-
-/** Set the user-defined data. This data is never touched by the scanner.
- * @param user_defined The data to be associated with this scanner.
- * @param yyscanner The scanner object.
- */
-void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yyextra = user_defined ;
-}
-
-/** Set the current line number.
- * @param line_number The line number to set.
- * @param yyscanner The scanner object.
- */
-void cmDependsFortran_yyset_lineno (int  line_number , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        /* lineno is only valid if an input buffer exists. */
-        if (! YY_CURRENT_BUFFER )
-           yy_fatal_error( "cmDependsFortran_yyset_lineno called with no buffer" , yyscanner);
-
-    yylineno = line_number;
-}
-
-/** Set the current column.
- * @param column_no The column number to set.
- * @param yyscanner The scanner object.
- */
-void cmDependsFortran_yyset_column (int  column_no , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        /* column is only valid if an input buffer exists. */
-        if (! YY_CURRENT_BUFFER )
-           yy_fatal_error( "cmDependsFortran_yyset_column called with no buffer" , yyscanner);
-
-    yycolumn = column_no;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * @param yyscanner The scanner object.
- * @see cmDependsFortran_yy_switch_to_buffer
- */
-void cmDependsFortran_yyset_in (FILE *  in_str , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yyin = in_str ;
-}
-
-void cmDependsFortran_yyset_out (FILE *  out_str , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yyout = out_str ;
-}
-
-int cmDependsFortran_yyget_debug  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yy_flex_debug;
-}
-
-void cmDependsFortran_yyset_debug (int  bdebug , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yy_flex_debug = bdebug ;
-}
-
-/* Accessor methods for yylval and yylloc */
-
-/* User-visible API */
-
-/* cmDependsFortran_yylex_init is special because it creates the scanner itself, so it is
- * the ONLY reentrant function that doesn't take the scanner as the last argument.
- * That's why we explicitly handle the declaration, instead of using our macros.
- */
-
-int cmDependsFortran_yylex_init(yyscan_t* ptr_yy_globals)
-
-{
-    if (ptr_yy_globals == NULL){
-        errno = EINVAL;
-        return 1;
-    }
-
-    *ptr_yy_globals = (yyscan_t) cmDependsFortran_yyalloc ( sizeof( struct yyguts_t ), NULL );
-
-    if (*ptr_yy_globals == NULL){
-        errno = ENOMEM;
-        return 1;
-    }
-
-    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
-    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
-    return yy_init_globals ( *ptr_yy_globals );
-}
-
-/* cmDependsFortran_yylex_init_extra has the same functionality as cmDependsFortran_yylex_init, but follows the
- * convention of taking the scanner as the last argument. Note however, that
- * this is a *pointer* to a scanner, as it will be allocated by this call (and
- * is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to cmDependsFortran_yyalloc in
- * the yyextra field.
- */
-
-int cmDependsFortran_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
-{
-    struct yyguts_t dummy_yyguts;
-
-    cmDependsFortran_yyset_extra (yy_user_defined, &dummy_yyguts);
-
-    if (ptr_yy_globals == NULL){
-        errno = EINVAL;
-        return 1;
-    }
-
-    *ptr_yy_globals = (yyscan_t) cmDependsFortran_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
-    if (*ptr_yy_globals == NULL){
-        errno = ENOMEM;
-        return 1;
-    }
-
-    /* By setting to 0xAA, we expose bugs in
-    yy_init_globals. Leave at 0x00 for releases. */
-    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
-    cmDependsFortran_yyset_extra (yy_user_defined, *ptr_yy_globals);
-
-    return yy_init_globals ( *ptr_yy_globals );
-}
-
-static int yy_init_globals (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from cmDependsFortran_yylex_destroy(), so don't allocate here.
-     */
-
-    yyg->yy_buffer_stack = 0;
-    yyg->yy_buffer_stack_top = 0;
-    yyg->yy_buffer_stack_max = 0;
-    yyg->yy_c_buf_p = (char *) 0;
-    yyg->yy_init = 0;
-    yyg->yy_start = 0;
-
-    yyg->yy_start_stack_ptr = 0;
-    yyg->yy_start_stack_depth = 0;
-    yyg->yy_start_stack =  NULL;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
-    yyin = stdin;
-    yyout = stdout;
-#else
-    yyin = (FILE *) 0;
-    yyout = (FILE *) 0;
-#endif
-
-    /* For future reference: Set errno on error, since we are called by
-     * cmDependsFortran_yylex_init()
-     */
-    return 0;
-}
-
-/* cmDependsFortran_yylex_destroy is for both reentrant and non-reentrant scanners. */
-int cmDependsFortran_yylex_destroy  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-    /* Pop the buffer stack, destroying each element. */
-        while(YY_CURRENT_BUFFER){
-                cmDependsFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
-                YY_CURRENT_BUFFER_LVALUE = NULL;
-                cmDependsFortran_yypop_buffer_state(yyscanner);
-        }
-
-        /* Destroy the stack itself. */
-        cmDependsFortran_yyfree(yyg->yy_buffer_stack ,yyscanner);
-        yyg->yy_buffer_stack = NULL;
-
-    /* Destroy the start condition stack. */
-        cmDependsFortran_yyfree(yyg->yy_start_stack ,yyscanner );
-        yyg->yy_start_stack = NULL;
-
-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * cmDependsFortran_yylex() is called, initialization will occur. */
-    yy_init_globals( yyscanner);
-
-    /* Destroy the main struct (reentrant only). */
-    cmDependsFortran_yyfree ( yyscanner , yyscanner );
-    return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
-{
-        int i;
-        for ( i = 0; i < n; ++i )
-                s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
-{
-        int n;
-        for ( n = 0; s[n]; ++n )
-                ;
-
-        return n;
-}
-#endif
-
-void *cmDependsFortran_yyalloc (yy_size_t  size , yyscan_t)
-{
-        return (void *) malloc( size );
-}
-
-void *cmDependsFortran_yyrealloc  (void * ptr, yy_size_t  size , yyscan_t)
-{
-        /* The cast to (char *) in the following accommodates both
-         * implementations that use char* generic pointers, and those
-         * that use void* generic pointers.  It works with the latter
-         * because both ANSI C and C++ allow castless assignment from
-         * any pointer type to void*, and deal with argument conversions
-         * as though doing an assignment.
-         */
-        return (void *) realloc( (char *) ptr, size );
-}
-
-void cmDependsFortran_yyfree (void * ptr , yyscan_t)
-{
-        free( (char *) ptr );   /* see cmDependsFortran_yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 181 "cmDependsFortranLexer.in.l"
-
-
-
-/*--------------------------------------------------------------------------*/
-YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
-{
-  /* Hack into the internal flex-generated scanner to get the buffer.  */
-  struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-  return YY_CURRENT_BUFFER;
-}
-
diff --git a/Source/cmDependsFortranLexer.h b/Source/cmDependsFortranLexer.h
deleted file mode 100644
index 8e24cfd..0000000
--- a/Source/cmDependsFortranLexer.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-#ifndef cmDependsFortran_yyHEADER_H
-#define cmDependsFortran_yyHEADER_H 1
-#define cmDependsFortran_yyIN_HEADER 1
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else   /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif  /* defined (__STDC__) */
-#endif  /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
-   are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-        {
-        FILE *yy_input_file;
-
-        char *yy_ch_buf;                /* input buffer */
-        char *yy_buf_pos;               /* current position in input buffer */
-
-        /* Size of input buffer in bytes, not including room for EOB
-         * characters.
-         */
-        yy_size_t yy_buf_size;
-
-        /* Number of characters read into yy_ch_buf, not including EOB
-         * characters.
-         */
-        int yy_n_chars;
-
-        /* Whether we "own" the buffer - i.e., we know we created it,
-         * and can realloc() it to grow it, and should free() it to
-         * delete it.
-         */
-        int yy_is_our_buffer;
-
-        /* Whether this is an "interactive" input source; if so, and
-         * if we're using stdio for input, then we want to use getc()
-         * instead of fread(), to make sure we stop fetching input after
-         * each newline.
-         */
-        int yy_is_interactive;
-
-        /* Whether we're considered to be at the beginning of a line.
-         * If so, '^' rules will be active on the next match, otherwise
-         * not.
-         */
-        int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-
-        /* Whether to try to fill the input buffer when we reach the
-         * end of it.
-         */
-        int yy_fill_buffer;
-
-        int yy_buffer_status;
-
-        };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-void cmDependsFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void cmDependsFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void cmDependsFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner );
-
-YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *cmDependsFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *cmDependsFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void cmDependsFortran_yyfree (void * ,yyscan_t yyscanner );
-
-/* Begin user sect3 */
-
-#define cmDependsFortran_yywrap(n) 1
-#define YY_SKIP_YYWRAP
-
-#define yytext_ptr yytext_r
-
-#ifdef YY_HEADER_EXPORT_START_CONDITIONS
-#define INITIAL 0
-#define free_fmt 1
-#define fixed_fmt 2
-#define str_sq 3
-#define str_dq 4
-
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-int cmDependsFortran_yylex_init (yyscan_t* scanner);
-
-int cmDependsFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int cmDependsFortran_yylex_destroy (yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_debug (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE cmDependsFortran_yyget_extra (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *cmDependsFortran_yyget_in (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_in  (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *cmDependsFortran_yyget_out (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_out  (FILE * out_str ,yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_leng (yyscan_t yyscanner );
-
-char *cmDependsFortran_yyget_text (yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_lineno (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int cmDependsFortran_yywrap (yyscan_t yyscanner );
-#else
-extern int cmDependsFortran_yywrap (yyscan_t yyscanner );
-#endif
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int cmDependsFortran_yylex (yyscan_t yyscanner);
-
-#define YY_DECL int cmDependsFortran_yylex (yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef YY_DO_BEFORE_ACTION
-
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
-#endif
-
-#undef cmDependsFortran_yyIN_HEADER
-#endif /* cmDependsFortran_yyHEADER_H */
diff --git a/Source/cmDependsFortranLexer.in.l b/Source/cmDependsFortranLexer.in.l
deleted file mode 100644
index 0148802..0000000
--- a/Source/cmDependsFortranLexer.in.l
+++ /dev/null
@@ -1,190 +0,0 @@
-%{
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-/*-------------------------------------------------------------------------
-  Portions of this source have been derived from makedepf90 version 2.8.8,
-
-   Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann at iki.fi>
-
-  The code was originally distributed under the GPL but permission
-  from the copyright holder has been obtained to distribute this
-  derived work under the CMake license.
--------------------------------------------------------------------------*/
-
-/*
-
-This file must be translated to C and modified to build everywhere.
-
-Run flex like this:
-
-  flex -i --prefix=cmDependsFortran_yy --header-file=cmDependsFortranLexer.h -ocmDependsFortranLexer.cxx cmDependsFortranLexer.in.l
-
-Modify cmDependsFortranLexer.cxx:
-  - remove TABs
-  - remove use of the 'register' storage class specifier
-  - remove "yyscanner" argument from these methods:
-      yy_fatal_error, cmDependsFortran_yyalloc, cmDependsFortran_yyrealloc, cmDependsFortran_yyfree
-  - remove "yyscanner = NULL" from end of cmDependsFortran_yylex_destroy
-  - remove all YY_BREAK lines occurring right after return statements
-  - change while ( 1 ) to for(;;)
-
-Modify cmDependsFortranLexer.h:
-  - remove TABs
-  - remove the yy_init_globals function
-  - remove the block that includes unistd.h
-  - remove #line directives (avoids bogus warning on old Sun)
-
-*/
-
-#include "cmStandardLexer.h"
-
-#define cmDependsFortranLexer_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object.  */
-
-/* Replace the lexer input function.  */
-#undef YY_INPUT
-#define YY_INPUT(buf, result, max_size) \
-  { result = cmDependsFortranParser_Input(yyextra, buf, max_size); }
-
-/* Include the set of tokens from the parser.  */
-#include "cmDependsFortranParserTokens.h"
-
-/*--------------------------------------------------------------------------*/
-%}
-
-
-%option reentrant
-%option noyywrap
-%pointer
-
-%s free_fmt fixed_fmt
-%x str_sq str_dq
-
-%%
-
-\"              {
-  cmDependsFortranParser_StringStart(yyextra);
-  cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
-  BEGIN(str_dq);
-}
-
-'               {
-  cmDependsFortranParser_StringStart(yyextra);
-  cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
-  BEGIN(str_sq);
-}
-
-<str_dq>\" |
-<str_sq>'  {
-  BEGIN(cmDependsFortranParser_GetOldStartcond(yyextra) );
-  yylvalp->string = strdup(cmDependsFortranParser_StringEnd(yyextra));
-  return STRING;
-}
-
-<str_dq,str_sq>&[ \t]*\n |
-<str_dq,str_sq>&[ \t]*\n[ \t]*&  /* Ignore (continued strings, free fmt) */
-
-<fixed_fmt,str_dq,str_sq>\n[ ]{5}[^ \t\n] {
-  if (cmDependsFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
-    ; /* Ignore (cont. strings, fixed fmt) */
-  else
-    {
-    unput(yytext[strlen(yytext)-1]);
-    }
-}
-
-
-<str_dq,str_sq>\n {
-  unput ('\n');
-  BEGIN(INITIAL);
-  return UNTERMINATED_STRING;
-}
-
-<str_sq,str_dq>. {
-  cmDependsFortranParser_StringAppend(yyextra, yytext[0]);
-}
-
-!.*\n                   { return EOSTMT; } /* Treat comments like */
-<fixed_fmt>^[cC*dD].*\n { return EOSTMT; } /* empty lines */
-
-^[ \t]*#[ \t]*include[ \t]*<[^>]+> {
-  yytext[yyleng-1] = 0;
-  yylvalp->string = strdup(strchr(yytext, '<')+1);
-  return CPP_INCLUDE_ANGLE;
-}
-^[ \t]*#[ \t]*include  { return CPP_INCLUDE; }
-\$[ \t]*include { return F90PPR_INCLUDE; }
-\?\?[ \t]*include { return COCO_INCLUDE; }
-
-^[ \t]*#[ \t]*define   { return CPP_DEFINE; }
-\$[ \t]*DEFINE   { return F90PPR_DEFINE; }
-
-^[ \t]*#[ \t]*undef    { return CPP_UNDEF; }
-\$[ \t]*UNDEF   { return F90PPR_UNDEF; }
-
-^[ \t]*#[ \t]*ifdef    { return CPP_IFDEF; }
-^[ \t]*#[ \t]*ifndef   { return CPP_IFNDEF; }
-^[ \t]*#[ \t]*if       { return CPP_IF; }
-^[ \t]*#[ \t]*elif     { return CPP_ELIF; }
-^[ \t]*#[ \t]*else     { return CPP_ELSE; }
-^[ \t]*#[ \t]*endif    { return CPP_ENDIF; }
-
-$[ \t]*ifdef    { return F90PPR_IFDEF; }
-$[ \t]*ifndef   { return F90PPR_IFNDEF; }
-$[ \t]*if       { return F90PPR_IF; }
-$[ \t]*elif     { return F90PPR_ELIF; }
-$[ \t]*else     { return F90PPR_ELSE; }
-$[ \t]*endif    { return F90PPR_ENDIF; }
-
- /* Line continuations, possible involving comments.  */
-&([ \t\n]*|!.*)*
-&([ \t\n]*|!.*)*&
-
-, { return COMMA; }
-
-:: { return DCOLON; }
-
-<fixed_fmt>\n[ ]{5}[^ ]  { return GARBAGE; }
-
-=|=>                     { return ASSIGNMENT_OP; }
-
-[a-zA-Z_][a-zA-Z_0-9]* {
-  yylvalp->string = strdup(yytext);
-  return WORD;
-}
-
-[^ \t\n\r;,!'"a-zA-Z=&]+ { return GARBAGE; }
-
-;|\n { return EOSTMT; }
-
-
-[ \t\r,]         /* Ignore */
-\\[ \t]*\n       /* Ignore line-endings preceeded by \ */
-
-. { return *yytext; }
-
-<<EOF>> {
-  if(!cmDependsFortranParser_FilePop(yyextra) )
-    {
-    return YY_NULL;
-    }
-}
-
-%%
-
-/*--------------------------------------------------------------------------*/
-YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
-{
-  /* Hack into the internal flex-generated scanner to get the buffer.  */
-  struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-  return YY_CURRENT_BUFFER;
-}
diff --git a/Source/cmDependsFortranParser.cxx b/Source/cmDependsFortranParser.cxx
deleted file mode 100644
index 9d51025..0000000
--- a/Source/cmDependsFortranParser.cxx
+++ /dev/null
@@ -1,2088 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.5.  */
-
-/* Bison implementation for Yacc-like parsers in C
-
-      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
-   simplifying the original so-called "semantic" parser.  */
-
-/* All symbols defined below should begin with yy or YY, to avoid
-   infringing on user name space.  This should be done even for local
-   variables, as they might otherwise be expanded by user macros.
-   There are some unavoidable exceptions within include files to
-   define necessary library symbols; they are noted "INFRINGES ON
-   USER NAME SPACE" below.  */
-
-/* Identify Bison output.  */
-#define YYBISON 1
-
-/* Bison version.  */
-#define YYBISON_VERSION "2.5"
-
-/* Skeleton name.  */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers.  */
-#define YYPURE 1
-
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
-/* Using locations.  */
-#define YYLSP_NEEDED 0
-
-/* Substitute the variable and function names.  */
-#define yyparse         cmDependsFortran_yyparse
-#define yylex           cmDependsFortran_yylex
-#define yyerror         cmDependsFortran_yyerror
-#define yylval          cmDependsFortran_yylval
-#define yychar          cmDependsFortran_yychar
-#define yydebug         cmDependsFortran_yydebug
-#define yynerrs         cmDependsFortran_yynerrs
-
-
-/* Copy the first part of user declarations.  */
-
-/* Line 268 of yacc.c  */
-#line 1 "cmDependsFortranParser.y"
-
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-/*-------------------------------------------------------------------------
-  Portions of this source have been derived from makedepf90 version 2.8.8,
-
-   Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann at iki.fi>
-
-  The code was originally distributed under the GPL but permission
-  from the copyright holder has been obtained to distribute this
-  derived work under the CMake license.
--------------------------------------------------------------------------*/
-
-/*
-
-This file must be translated to C and modified to build everywhere.
-
-Run bison like this:
-
-  bison --yacc --name-prefix=cmDependsFortran_yy
-        --defines=cmDependsFortranParserTokens.h
-         -ocmDependsFortranParser.cxx
-          cmDependsFortranParser.y
-
-Modify cmDependsFortranParser.cxx:
-  - remove TABs
-  - Remove the yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
-*/
-
-/*-------------------------------------------------------------------------*/
-#define cmDependsFortranParser_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object.  */
-#include "cmDependsFortranParserTokens.h" /* Need YYSTYPE for YY_DECL.  */
-
-#include <cmsys/String.h>
-
-/* Configure the parser to use a lexer object.  */
-#define YYPARSE_PARAM yyscanner
-#define YYLEX_PARAM yyscanner
-#define YYERROR_VERBOSE 1
-#define cmDependsFortran_yyerror(x) \
-        cmDependsFortranError(yyscanner, x)
-
-/* Forward declare the lexer entry point.  */
-YY_DECL;
-
-/* Helper function to forward error callback.  */
-static void cmDependsFortranError(yyscan_t yyscanner, const char* message)
-{
-  cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-  cmDependsFortranParser_Error(parser, message);
-}
-
-static bool cmDependsFortranParserIsKeyword(const char* word,
-                                            const char* keyword)
-{
-  return cmsysString_strcasecmp(word, keyword) == 0;
-}
-
-/* Disable some warnings in the generated code.  */
-#ifdef _MSC_VER
-# pragma warning (disable: 4102) /* Unused goto label.  */
-# pragma warning (disable: 4065) /* Switch contains default but no case. */
-# pragma warning (disable: 4701) /* Local variable may not be initialized.  */
-# pragma warning (disable: 4702) /* Unreachable code.  */
-# pragma warning (disable: 4127) /* Conditional expression is constant.  */
-# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
-#endif
-
-
-/* Line 268 of yacc.c  */
-#line 165 "cmDependsFortranParser.cxx"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     EOSTMT = 258,
-     ASSIGNMENT_OP = 259,
-     GARBAGE = 260,
-     CPP_INCLUDE = 261,
-     F90PPR_INCLUDE = 262,
-     COCO_INCLUDE = 263,
-     F90PPR_DEFINE = 264,
-     CPP_DEFINE = 265,
-     F90PPR_UNDEF = 266,
-     CPP_UNDEF = 267,
-     CPP_IFDEF = 268,
-     CPP_IFNDEF = 269,
-     CPP_IF = 270,
-     CPP_ELSE = 271,
-     CPP_ELIF = 272,
-     CPP_ENDIF = 273,
-     F90PPR_IFDEF = 274,
-     F90PPR_IFNDEF = 275,
-     F90PPR_IF = 276,
-     F90PPR_ELSE = 277,
-     F90PPR_ELIF = 278,
-     F90PPR_ENDIF = 279,
-     COMMA = 280,
-     DCOLON = 281,
-     CPP_TOENDL = 282,
-     UNTERMINATED_STRING = 283,
-     STRING = 284,
-     WORD = 285,
-     CPP_INCLUDE_ANGLE = 286
-   };
-#endif
-/* Tokens.  */
-#define EOSTMT 258
-#define ASSIGNMENT_OP 259
-#define GARBAGE 260
-#define CPP_INCLUDE 261
-#define F90PPR_INCLUDE 262
-#define COCO_INCLUDE 263
-#define F90PPR_DEFINE 264
-#define CPP_DEFINE 265
-#define F90PPR_UNDEF 266
-#define CPP_UNDEF 267
-#define CPP_IFDEF 268
-#define CPP_IFNDEF 269
-#define CPP_IF 270
-#define CPP_ELSE 271
-#define CPP_ELIF 272
-#define CPP_ENDIF 273
-#define F90PPR_IFDEF 274
-#define F90PPR_IFNDEF 275
-#define F90PPR_IF 276
-#define F90PPR_ELSE 277
-#define F90PPR_ELIF 278
-#define F90PPR_ENDIF 279
-#define COMMA 280
-#define DCOLON 281
-#define CPP_TOENDL 282
-#define UNTERMINATED_STRING 283
-#define STRING 284
-#define WORD 285
-#define CPP_INCLUDE_ANGLE 286
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-{
-
-/* Line 293 of yacc.c  */
-#line 89 "cmDependsFortranParser.y"
-
-  char* string;
-
-
-
-/* Line 293 of yacc.c  */
-#line 269 "cmDependsFortranParser.cxx"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-
-/* Copy the second part of user declarations.  */
-
-
-/* Line 343 of yacc.c  */
-#line 281 "cmDependsFortranParser.cxx"
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
-#else
-typedef short int yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-#  define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-#  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# else
-#  define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
-#  if ENABLE_NLS
-#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
-#  endif
-# endif
-# ifndef YY_
-#  define YY_(msgid) msgid
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E.  */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
-#else
-# define YYUSE(e) /* empty */
-#endif
-
-/* Identity function, used to suppress warnings about constant conditions.  */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int yyi)
-#else
-static int
-YYID (yyi)
-    int yyi;
-#endif
-{
-  return yyi;
-}
-#endif
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
-
-# ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
-#   ifdef __GNUC__
-#    define YYSTACK_ALLOC __builtin_alloca
-#   elif defined __BUILTIN_VA_ARG_INCR
-#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-#   elif defined _AIX
-#    define YYSTACK_ALLOC __alloca
-#   elif defined _MSC_VER
-#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-#    define alloca _alloca
-#   else
-#    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-
-# ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-    /* The OS might guarantee only one guard page at the bottom of the stack,
-       and a page size can be as small as 4096 bytes.  So we cannot safely
-       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
-       to allow for a few compiler-allocated temporary stack slots.  */
-#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-#  endif
-# else
-#  define YYSTACK_ALLOC YYMALLOC
-#  define YYSTACK_FREE YYFREE
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-#  endif
-#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
-       && ! ((defined YYMALLOC || defined malloc) \
-             && (defined YYFREE || defined free)))
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef EXIT_SUCCESS
-#    define EXIT_SUCCESS 0
-#   endif
-#  endif
-#  ifndef YYMALLOC
-#   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-#  ifndef YYFREE
-#   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
-     && (! defined __cplusplus \
-         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member.  */
-union yyalloc
-{
-  yytype_int16 yyss_alloc;
-  YYSTYPE yyvs_alloc;
-};
-
-/* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
-   N elements.  */
-# define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
-      + YYSTACK_GAP_MAXIMUM)
-
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
-    do                                                                  \
-      {                                                                 \
-        YYSIZE_T yynewbytes;                                            \
-        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
-        Stack = &yyptr->Stack_alloc;                                    \
-        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-        yyptr += yynewbytes / sizeof (*yyptr);                          \
-      }                                                                 \
-    while (YYID (0))
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)              \
-      do                                        \
-        {                                       \
-          YYSIZE_T yyi;                         \
-          for (yyi = 0; yyi < (Count); yyi++)   \
-            (To)[yyi] = (From)[yyi];            \
-        }                                       \
-      while (YYID (0))
-#  endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
-/* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  2
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   276
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  32
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  16
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  53
-/* YYNRULES -- Number of states.  */
-#define YYNSTATES  97
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   286
-
-#define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
-static const yytype_uint8 yytranslate[] =
-{
-       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
-   YYRHS.  */
-static const yytype_uint8 yyprhs[] =
-{
-       0,     0,     3,     4,     7,     9,    11,    16,    19,    24,
-      30,    38,    43,    47,    52,    57,    62,    67,    72,    76,
-      80,    84,    88,    93,    97,    99,   101,   103,   105,   107,
-     109,   111,   113,   115,   117,   119,   121,   123,   125,   127,
-     129,   131,   133,   135,   137,   139,   140,   143,   145,   147,
-     149,   151,   153,   155
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
-static const yytype_int8 yyrhs[] =
-{
-      33,     0,    -1,    -1,    33,    34,    -1,    36,    -1,    35,
-      -1,    30,     4,    46,     3,    -1,    30,     3,    -1,    30,
-      30,    46,     3,    -1,    30,    26,    30,    46,     3,    -1,
-      30,    25,    30,    26,    30,    46,     3,    -1,    30,    29,
-      46,     3,    -1,    31,    46,     3,    -1,    37,    29,    46,
-       3,    -1,    38,    30,    46,     3,    -1,    39,    30,    46,
-       3,    -1,    40,    30,    46,     3,    -1,    41,    30,    46,
-       3,    -1,    42,    46,     3,    -1,    43,    46,     3,    -1,
-      44,    46,     3,    -1,    45,    46,     3,    -1,    30,     5,
-      46,     3,    -1,     5,    46,     3,    -1,     3,    -1,     1,
-      -1,     6,    -1,     7,    -1,     8,    -1,    10,    -1,     9,
-      -1,    12,    -1,    11,    -1,    13,    -1,    19,    -1,    14,
-      -1,    20,    -1,    15,    -1,    21,    -1,    17,    -1,    23,
-      -1,    16,    -1,    22,    -1,    18,    -1,    24,    -1,    -1,
-      46,    47,    -1,    30,    -1,    29,    -1,     5,    -1,     4,
-      -1,    26,    -1,    25,    -1,    28,    -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,   111,   111,   111,   113,   113,   115,   121,   131,   161,
-     172,   185,   196,   203,   210,   216,   222,   228,   234,   239,
-     244,   249,   254,   258,   259,   260,   265,   265,   265,   266,
-     266,   267,   267,   268,   268,   269,   269,   270,   270,   271,
-     271,   272,   272,   273,   273,   274,   274,   277,   278,   279,
-     280,   281,   282,   283
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "EOSTMT", "ASSIGNMENT_OP", "GARBAGE",
-  "CPP_INCLUDE", "F90PPR_INCLUDE", "COCO_INCLUDE", "F90PPR_DEFINE",
-  "CPP_DEFINE", "F90PPR_UNDEF", "CPP_UNDEF", "CPP_IFDEF", "CPP_IFNDEF",
-  "CPP_IF", "CPP_ELSE", "CPP_ELIF", "CPP_ENDIF", "F90PPR_IFDEF",
-  "F90PPR_IFNDEF", "F90PPR_IF", "F90PPR_ELSE", "F90PPR_ELIF",
-  "F90PPR_ENDIF", "COMMA", "DCOLON", "CPP_TOENDL", "UNTERMINATED_STRING",
-  "STRING", "WORD", "CPP_INCLUDE_ANGLE", "$accept", "code", "stmt",
-  "assignment_stmt", "keyword_stmt", "include", "define", "undef", "ifdef",
-  "ifndef", "if", "elif", "else", "endif", "other", "misc_code", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
-     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
-     285,   286
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    32,    33,    33,    34,    34,    35,    36,    36,    36,
-      36,    36,    36,    36,    36,    36,    36,    36,    36,    36,
-      36,    36,    36,    36,    36,    36,    37,    37,    37,    38,
-      38,    39,    39,    40,    40,    41,    41,    42,    42,    43,
-      43,    44,    44,    45,    45,    46,    46,    47,    47,    47,
-      47,    47,    47,    47
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     0,     2,     1,     1,     4,     2,     4,     5,
-       7,     4,     3,     4,     4,     4,     4,     4,     3,     3,
-       3,     3,     4,     3,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     0,     2,     1,     1,     1,
-       1,     1,     1,     1
-};
-
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
-   Performed when YYTABLE doesn't specify something else to do.  Zero
-   means the default is an error.  */
-static const yytype_uint8 yydefact[] =
-{
-       2,     0,     1,    25,    24,    45,    26,    27,    28,    30,
-      29,    32,    31,    33,    35,    37,    41,    39,    43,    34,
-      36,    38,    42,    40,    44,     0,    45,     3,     5,     4,
-       0,     0,     0,     0,     0,    45,    45,    45,    45,     0,
-       7,    45,    45,     0,     0,    45,    45,     0,    45,    45,
-      45,    45,    45,     0,     0,     0,     0,    23,    50,    49,
-      52,    51,    53,    48,    47,    46,     0,     0,     0,    45,
-       0,     0,    12,     0,     0,     0,     0,     0,    18,    19,
-      20,    21,     6,    22,     0,     0,    11,     8,    13,    14,
-      15,    16,    17,    45,     9,     0,    10
-};
-
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int8 yydefgoto[] =
-{
-      -1,     1,    27,    28,    29,    30,    31,    32,    33,    34,
-      35,    36,    37,    38,    39,    65
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -29
-static const yytype_int16 yypact[] =
-{
-     -29,    39,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,
-     -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,
-     -29,   -29,   -29,   -29,   -29,   246,   -29,   -29,   -29,   -29,
-     -28,   -27,   -22,   -17,   -16,   -29,   -29,   -29,   -29,     2,
-     -29,   -29,   -29,   -13,   -12,   -29,   -29,    61,   -29,   -29,
-     -29,   -29,   -29,    68,    74,    80,   108,   -29,   -29,   -29,
-     -29,   -29,   -29,   -29,   -29,   -29,   114,   120,   -24,   -29,
-     126,   154,   -29,   160,   166,   172,   200,   206,   -29,   -29,
-     -29,   -29,   -29,   -29,    -9,   212,   -29,   -29,   -29,   -29,
-     -29,   -29,   -29,   -29,   -29,   218,   -29
-};
-
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int8 yypgoto[] =
-{
-     -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,
-     -29,   -29,   -29,   -29,   -26,   -29
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
-   positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -1
-static const yytype_uint8 yytable[] =
-{
-      47,    48,    84,    49,     0,    57,    58,    59,    50,    53,
-      54,    55,    56,    51,    52,    66,    67,    68,    69,    70,
-      71,    93,    73,    74,    75,    76,    77,    60,    61,     0,
-      62,    63,    64,     0,     0,     0,     0,     0,     0,     2,
-       3,     0,     4,    85,     5,     6,     7,     8,     9,    10,
-      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-      21,    22,    23,    24,    72,    58,    59,    95,     0,    25,
-      26,    78,    58,    59,     0,     0,     0,    79,    58,    59,
-       0,     0,     0,    80,    58,    59,    60,    61,     0,    62,
-      63,    64,     0,    60,    61,     0,    62,    63,    64,    60,
-      61,     0,    62,    63,    64,    60,    61,     0,    62,    63,
-      64,    81,    58,    59,     0,     0,     0,    82,    58,    59,
-       0,     0,     0,    83,    58,    59,     0,     0,     0,    86,
-      58,    59,     0,    60,    61,     0,    62,    63,    64,    60,
-      61,     0,    62,    63,    64,    60,    61,     0,    62,    63,
-      64,    60,    61,     0,    62,    63,    64,    87,    58,    59,
-       0,     0,     0,    88,    58,    59,     0,     0,     0,    89,
-      58,    59,     0,     0,     0,    90,    58,    59,     0,    60,
-      61,     0,    62,    63,    64,    60,    61,     0,    62,    63,
-      64,    60,    61,     0,    62,    63,    64,    60,    61,     0,
-      62,    63,    64,    91,    58,    59,     0,     0,     0,    92,
-      58,    59,     0,     0,     0,    94,    58,    59,     0,     0,
-       0,    96,    58,    59,     0,    60,    61,     0,    62,    63,
-      64,    60,    61,     0,    62,    63,    64,    60,    61,     0,
-      62,    63,    64,    60,    61,     0,    62,    63,    64,    40,
-      41,    42,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    43,    44,     0,     0,    45,    46
-};
-
-#define yypact_value_is_default(yystate) \
-  ((yystate) == (-29))
-
-#define yytable_value_is_error(yytable_value) \
-  YYID (0)
-
-static const yytype_int8 yycheck[] =
-{
-      26,    29,    26,    30,    -1,     3,     4,     5,    30,    35,
-      36,    37,    38,    30,    30,    41,    42,    30,    30,    45,
-      46,    30,    48,    49,    50,    51,    52,    25,    26,    -1,
-      28,    29,    30,    -1,    -1,    -1,    -1,    -1,    -1,     0,
-       1,    -1,     3,    69,     5,     6,     7,     8,     9,    10,
-      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-      21,    22,    23,    24,     3,     4,     5,    93,    -1,    30,
-      31,     3,     4,     5,    -1,    -1,    -1,     3,     4,     5,
-      -1,    -1,    -1,     3,     4,     5,    25,    26,    -1,    28,
-      29,    30,    -1,    25,    26,    -1,    28,    29,    30,    25,
-      26,    -1,    28,    29,    30,    25,    26,    -1,    28,    29,
-      30,     3,     4,     5,    -1,    -1,    -1,     3,     4,     5,
-      -1,    -1,    -1,     3,     4,     5,    -1,    -1,    -1,     3,
-       4,     5,    -1,    25,    26,    -1,    28,    29,    30,    25,
-      26,    -1,    28,    29,    30,    25,    26,    -1,    28,    29,
-      30,    25,    26,    -1,    28,    29,    30,     3,     4,     5,
-      -1,    -1,    -1,     3,     4,     5,    -1,    -1,    -1,     3,
-       4,     5,    -1,    -1,    -1,     3,     4,     5,    -1,    25,
-      26,    -1,    28,    29,    30,    25,    26,    -1,    28,    29,
-      30,    25,    26,    -1,    28,    29,    30,    25,    26,    -1,
-      28,    29,    30,     3,     4,     5,    -1,    -1,    -1,     3,
-       4,     5,    -1,    -1,    -1,     3,     4,     5,    -1,    -1,
-      -1,     3,     4,     5,    -1,    25,    26,    -1,    28,    29,
-      30,    25,    26,    -1,    28,    29,    30,    25,    26,    -1,
-      28,    29,    30,    25,    26,    -1,    28,    29,    30,     3,
-       4,     5,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    25,    26,    -1,    -1,    29,    30
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
-{
-       0,    33,     0,     1,     3,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    30,    31,    34,    35,    36,
-      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
-       3,     4,     5,    25,    26,    29,    30,    46,    29,    30,
-      30,    30,    30,    46,    46,    46,    46,     3,     4,     5,
-      25,    26,    28,    29,    30,    47,    46,    46,    30,    30,
-      46,    46,     3,    46,    46,    46,    46,    46,     3,     3,
-       3,     3,     3,     3,    26,    46,     3,     3,     3,     3,
-       3,     3,     3,    30,     3,    46,     3
-};
-
-#define yyerrok         (yyerrstatus = 0)
-#define yyclearin       (yychar = YYEMPTY)
-#define YYEMPTY         (-2)
-#define YYEOF           0
-
-#define YYACCEPT        goto yyacceptlab
-#define YYABORT         goto yyabortlab
-#define YYERROR         goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror.  This remains here temporarily
-   to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  However,
-   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
-   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
-   discussed.  */
-
-#define YYFAIL          goto yyerrlab
-#if defined YYFAIL
-  /* This is here to suppress warnings from the GCC cpp's
-     -Wunused-macros.  Normally we don't worry about that warning, but
-     some users do, and we want to make it easy for users to remove
-     YYFAIL uses, which will produce warnings from Bison 2.5.  */
-#endif
-
-#define YYRECOVERING()  (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY && yylen == 1)                          \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (1);                                           \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (YYID (0))
-
-
-#define YYTERROR        1
-#define YYERRCODE       256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-   If N is 0, then set CURRENT to the empty location which ends
-   the previous symbol: RHS[0] (always defined).  */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)                                \
-    do                                                                  \
-      if (YYID (N))                                                    \
-        {                                                               \
-          (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
-          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
-          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
-          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
-        }                                                               \
-      else                                                              \
-        {                                                               \
-          (Current).first_line   = (Current).last_line   =              \
-            YYRHSLOC (Rhs, 0).last_line;                                \
-          (Current).first_column = (Current).last_column =              \
-            YYRHSLOC (Rhs, 0).last_column;                              \
-        }                                                               \
-    while (YYID (0))
-#endif
-
-
-/* This macro is provided for backward compatibility. */
-
-#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments.  */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, YYLEX_PARAM)
-#else
-# define YYLEX yylex (&yylval)
-#endif
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)                        \
-do {                                            \
-  if (yydebug)                                  \
-    YYFPRINTF Args;                             \
-} while (YYID (0))
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
-do {                                                                      \
-  if (yydebug)                                                            \
-    {                                                                     \
-      YYFPRINTF (stderr, "%s ", Title);                                   \
-      yy_symbol_print (stderr,                                            \
-                  Type, Value); \
-      YYFPRINTF (stderr, "\n");                                           \
-    }                                                                     \
-} while (YYID (0))
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-#endif
-{
-  if (!yyvaluep)
-    return;
-# ifdef YYPRINT
-  if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
-  YYUSE (yyoutput);
-# endif
-  switch (yytype)
-    {
-      default:
-        break;
-    }
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-#endif
-{
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-  else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
-  YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included).                                                   |
-`------------------------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
-#endif
-{
-  YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
-  YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top)                            \
-do {                                                            \
-  if (yydebug)                                                  \
-    yy_stack_print ((Bottom), (Top));                           \
-} while (YYID (0))
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced.  |
-`------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
-#else
-static void
-yy_reduce_print (yyvsp, yyrule)
-    YYSTYPE *yyvsp;
-    int yyrule;
-#endif
-{
-  int yynrhs = yyr2[yyrule];
-  int yyi;
-  unsigned long int yylno = yyrline[yyrule];
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
-             yyrule - 1, yylno);
-  /* The symbols being reduced.  */
-  for (yyi = 0; yyi < yynrhs; yyi++)
-    {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
-                                       );
-      YYFPRINTF (stderr, "\n");
-    }
-}
-
-# define YY_REDUCE_PRINT(Rule)          \
-do {                                    \
-  if (yydebug)                          \
-    yy_reduce_print (yyvsp, Rule); \
-} while (YYID (0))
-
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-   if the built-in stack extension method is used).
-
-   Do not make this value too large; the results are undefined if
-   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
-   evaluated with infinite-precision integer arithmetic.  */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-#  if defined __GLIBC__ && defined _STRING_H
-#   define yystrlen strlen
-#  else
-/* Return the length of YYSTR.  */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static YYSIZE_T
-yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
-    const char *yystr;
-#endif
-{
-  YYSIZE_T yylen;
-  for (yylen = 0; yystr[yylen]; yylen++)
-    continue;
-  return yylen;
-}
-#  endif
-# endif
-
-# ifndef yystpcpy
-#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-#   define yystpcpy stpcpy
-#  else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-   YYDEST.  */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
-    char *yydest;
-    const char *yysrc;
-#endif
-{
-  char *yyd = yydest;
-  const char *yys = yysrc;
-
-  while ((*yyd++ = *yys++) != '\0')
-    continue;
-
-  return yyd - 1;
-}
-#  endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
-   quotes and backslashes, so that it's suitable for yyerror.  The
-   heuristic is that double-quoting is unnecessary unless the string
-   contains an apostrophe, a comma, or backslash (other than
-   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
-   null, do not copy; instead, return the length of what the result
-   would have been.  */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
-  if (*yystr == '"')
-    {
-      YYSIZE_T yyn = 0;
-      char const *yyp = yystr;
-
-      for (;;)
-        switch (*++yyp)
-          {
-          case '\'':
-          case ',':
-            goto do_not_strip_quotes;
-
-          case '\\':
-            if (*++yyp != '\\')
-              goto do_not_strip_quotes;
-            /* Fall through.  */
-          default:
-            if (yyres)
-              yyres[yyn] = *yyp;
-            yyn++;
-            break;
-
-          case '"':
-            if (yyres)
-              yyres[yyn] = '\0';
-            return yyn;
-          }
-    do_not_strip_quotes: ;
-    }
-
-  if (! yyres)
-    return yystrlen (yystr);
-
-  return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
-   about the unexpected token YYTOKEN for the state stack whose top is
-   YYSSP.
-
-   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
-   not large enough to hold the message.  In that case, also set
-   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
-   required number of bytes is too large to store.  */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
-                yytype_int16 *yyssp, int yytoken)
-{
-  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
-  YYSIZE_T yysize1;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = 0;
-  /* Arguments of yyformat. */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-  /* Number of reported tokens (one for the "unexpected", one per
-     "expected"). */
-  int yycount = 0;
-
-  /* There are many possibilities here to consider:
-     - Assume YYFAIL is not used.  It's too flawed to consider.  See
-       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
-       for details.  YYERROR is fine as it does not invoke this
-       function.
-     - If this state is a consistent state with a default action, then
-       the only way this function was invoked is if the default action
-       is an error action.  In that case, don't check for expected
-       tokens because there are none.
-     - The only way there can be no lookahead present (in yychar) is if
-       this state is a consistent state with a default action.  Thus,
-       detecting the absence of a lookahead is sufficient to determine
-       that there is no unexpected or expected token to report.  In that
-       case, just report a simple "syntax error".
-     - Don't assume there isn't a lookahead just because this state is a
-       consistent state with a default action.  There might have been a
-       previous inconsistent state, consistent state with a non-default
-       action, or user semantic action that manipulated yychar.
-     - Of course, the expected token list depends on states to have
-       correct lookahead information, and it depends on the parser not
-       to perform extra reductions after fetching a lookahead from the
-       scanner and before detecting a syntax error.  Thus, state merging
-       (from LALR or IELR) and default reductions corrupt the expected
-       token list.  However, the list is correct for canonical LR with
-       one exception: it will still contain any token that will not be
-       accepted due to an error action in a later state.
-  */
-  if (yytoken != YYEMPTY)
-    {
-      int yyn = yypact[*yyssp];
-      yyarg[yycount++] = yytname[yytoken];
-      if (!yypact_value_is_default (yyn))
-        {
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for
-             this state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytname[yyx];
-                yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-                if (! (yysize <= yysize1
-                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                  return 2;
-                yysize = yysize1;
-              }
-        }
-    }
-
-  switch (yycount)
-    {
-# define YYCASE_(N, S)                      \
-      case N:                               \
-        yyformat = S;                       \
-      break
-      YYCASE_(0, YY_("syntax error"));
-      YYCASE_(1, YY_("syntax error, unexpected %s"));
-      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
-      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
-      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
-      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
-    }
-
-  yysize1 = yysize + yystrlen (yyformat);
-  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-    return 2;
-  yysize = yysize1;
-
-  if (*yymsg_alloc < yysize)
-    {
-      *yymsg_alloc = 2 * yysize;
-      if (! (yysize <= *yymsg_alloc
-             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
-        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
-    }
-
-  /* Avoid sprintf, as that infringes on the user's name space.
-     Don't have undefined behavior even if the translation
-     produced a string with the wrong number of "%s"s.  */
-  {
-    char *yyp = *yymsg;
-    int yyi = 0;
-    while ((*yyp = *yyformat) != '\0')
-      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-        {
-          yyp += yytnamerr (yyp, yyarg[yyi++]);
-          yyformat += 2;
-        }
-      else
-        {
-          yyp++;
-          yyformat++;
-        }
-  }
-  return 0;
-}
-#endif /* YYERROR_VERBOSE */
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol.  |
-`-----------------------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep)
-    const char *yymsg;
-    int yytype;
-    YYSTYPE *yyvaluep;
-#endif
-{
-  YYUSE (yyvaluep);
-
-  if (!yymsg)
-    yymsg = "Deleting";
-  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
-  switch (yytype)
-    {
-
-      default:
-        break;
-    }
-}
-
-
-/* Prevent warnings from -Wmissing-prototypes.  */
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-/*----------.
-| yyparse.  |
-`----------*/
-
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
-    void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
-{
-/* The lookahead symbol.  */
-int yychar;
-
-/* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval;
-
-    /* Number of syntax errors so far.  */
-    int yynerrs;
-
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
-
-    /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
-
-       Refer to the stacks thru separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
-
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
-
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
-
-    YYSIZE_T yystacksize;
-
-  int yyn;
-  int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
-  char yymsgbuf[128];
-  char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
-
-  /* The number of symbols on the RHS of the reduced rule.
-     Keep to zero when no symbol should be popped.  */
-  int yylen = 0;
-
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
-  yystacksize = YYINITDEPTH;
-
-  YYDPRINTF ((stderr, "Starting parse\n"));
-
-  yystate = 0;
-  yyerrstatus = 0;
-  yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
-
-  /* Initialize stack pointers.
-     Waste one element of value and location stack
-     so that they stay on the same level as the state stack.
-     The wasted elements are never initialized.  */
-  yyssp = yyss;
-  yyvsp = yyvs;
-
-  goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
-`------------------------------------------------------------*/
- yynewstate:
-  /* In all cases, when you get here, the value and location stacks
-     have just been pushed.  So pushing a state here evens the stacks.  */
-  yyssp++;
-
- yysetstate:
-  *yyssp = yystate;
-
-  if (yyss + yystacksize - 1 <= yyssp)
-    {
-      /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
-      {
-        /* Give user a chance to reallocate the stack.  Use copies of
-           these so that the &'s don't force the real ones into
-           memory.  */
-        YYSTYPE *yyvs1 = yyvs;
-        yytype_int16 *yyss1 = yyss;
-
-        /* Each stack pointer address is followed by the size of the
-           data in use in that stack, in bytes.  This used to be a
-           conditional around just the two extra args, but that might
-           be undefined if yyoverflow is a macro.  */
-        yyoverflow (YY_("memory exhausted"),
-                    &yyss1, yysize * sizeof (*yyssp),
-                    &yyvs1, yysize * sizeof (*yyvsp),
-                    &yystacksize);
-
-        yyss = yyss1;
-        yyvs = yyvs1;
-      }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
-      /* Extend the stack our own way.  */
-      if (YYMAXDEPTH <= yystacksize)
-        goto yyexhaustedlab;
-      yystacksize *= 2;
-      if (YYMAXDEPTH < yystacksize)
-        yystacksize = YYMAXDEPTH;
-
-      {
-        yytype_int16 *yyss1 = yyss;
-        union yyalloc *yyptr =
-          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-        if (! yyptr)
-          goto yyexhaustedlab;
-        YYSTACK_RELOCATE (yyss_alloc, yyss);
-        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
-        if (yyss1 != yyssa)
-          YYSTACK_FREE (yyss1);
-      }
-# endif
-#endif /* no yyoverflow */
-
-      yyssp = yyss + yysize - 1;
-      yyvsp = yyvs + yysize - 1;
-
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
-
-      if (yyss + yystacksize - 1 <= yyssp)
-        YYABORT;
-    }
-
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
-  goto yybackup;
-
-/*-----------.
-| yybackup.  |
-`-----------*/
-yybackup:
-
-  /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
-
-  /* First try to decide what to do without reference to lookahead token.  */
-  yyn = yypact[yystate];
-  if (yypact_value_is_default (yyn))
-    goto yydefault;
-
-  /* Not known => get a lookahead token if don't already have one.  */
-
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
-  if (yychar == YYEMPTY)
-    {
-      YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = YYLEX;
-    }
-
-  if (yychar <= YYEOF)
-    {
-      yychar = yytoken = YYEOF;
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
-    }
-  else
-    {
-      yytoken = YYTRANSLATE (yychar);
-      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
-    }
-
-  /* If the proper action on seeing token YYTOKEN is to reduce or to
-     detect an error, take that action.  */
-  yyn += yytoken;
-  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
-    goto yydefault;
-  yyn = yytable[yyn];
-  if (yyn <= 0)
-    {
-      if (yytable_value_is_error (yyn))
-        goto yyerrlab;
-      yyn = -yyn;
-      goto yyreduce;
-    }
-
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
-
-  /* Shift the lookahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
-
-  yystate = yyn;
-  *++yyvsp = yylval;
-
-  goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state.  |
-`-----------------------------------------------------------*/
-yydefault:
-  yyn = yydefact[yystate];
-  if (yyn == 0)
-    goto yyerrlab;
-  goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction.  |
-`-----------------------------*/
-yyreduce:
-  /* yyn is the number of a rule to reduce with.  */
-  yylen = yyr2[yyn];
-
-  /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
-
-     Otherwise, the following line sets YYVAL to garbage.
-     This behavior is undocumented and Bison
-     users should not rely upon it.  Assigning to YYVAL
-     unconditionally makes the parser a bit smaller, and it avoids a
-     GCC warning that YYVAL may be used uninitialized.  */
-  yyval = yyvsp[1-yylen];
-
-
-  YY_REDUCE_PRINT (yyn);
-  switch (yyn)
-    {
-        case 6:
-
-/* Line 1806 of yacc.c  */
-#line 116 "cmDependsFortranParser.y"
-    {
-    free((yyvsp[(1) - (4)].string));
-    }
-    break;
-
-  case 7:
-
-/* Line 1806 of yacc.c  */
-#line 122 "cmDependsFortranParser.y"
-    {
-    if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (2)].string), "interface"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_SetInInterface(parser, true);
-      }
-    free((yyvsp[(1) - (2)].string));
-    }
-    break;
-
-  case 8:
-
-/* Line 1806 of yacc.c  */
-#line 132 "cmDependsFortranParser.y"
-    {
-    if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "use"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleUse(parser, (yyvsp[(2) - (4)].string));
-      }
-    else if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "module"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleModule(parser, (yyvsp[(2) - (4)].string));
-      }
-    else if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "interface"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_SetInInterface(parser, true);
-      }
-    else if (cmDependsFortranParserIsKeyword((yyvsp[(2) - (4)].string), "interface") &&
-             cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "end"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_SetInInterface(parser, false);
-      }
-    free((yyvsp[(1) - (4)].string));
-    free((yyvsp[(2) - (4)].string));
-    }
-    break;
-
-  case 9:
-
-/* Line 1806 of yacc.c  */
-#line 162 "cmDependsFortranParser.y"
-    {
-    if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (5)].string), "use"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleUse(parser, (yyvsp[(3) - (5)].string));
-      }
-    free((yyvsp[(1) - (5)].string));
-    free((yyvsp[(3) - (5)].string));
-    }
-    break;
-
-  case 10:
-
-/* Line 1806 of yacc.c  */
-#line 173 "cmDependsFortranParser.y"
-    {
-    if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (7)].string), "use") &&
-        cmDependsFortranParserIsKeyword((yyvsp[(3) - (7)].string), "non_intrinsic") )
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleUse(parser, (yyvsp[(5) - (7)].string));
-      }
-    free((yyvsp[(1) - (7)].string));
-    free((yyvsp[(3) - (7)].string));
-    free((yyvsp[(5) - (7)].string));
-    }
-    break;
-
-  case 11:
-
-/* Line 1806 of yacc.c  */
-#line 186 "cmDependsFortranParser.y"
-    {
-    if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "include"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleInclude(parser, (yyvsp[(2) - (4)].string));
-      }
-    free((yyvsp[(1) - (4)].string));
-    free((yyvsp[(2) - (4)].string));
-    }
-    break;
-
-  case 12:
-
-/* Line 1806 of yacc.c  */
-#line 197 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser =
-      cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleInclude(parser, (yyvsp[(1) - (3)].string));
-    free((yyvsp[(1) - (3)].string));
-    }
-    break;
-
-  case 13:
-
-/* Line 1806 of yacc.c  */
-#line 204 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser =
-      cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleInclude(parser, (yyvsp[(2) - (4)].string));
-    free((yyvsp[(2) - (4)].string));
-    }
-    break;
-
-  case 14:
-
-/* Line 1806 of yacc.c  */
-#line 211 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleDefine(parser, (yyvsp[(2) - (4)].string));
-    free((yyvsp[(2) - (4)].string));
-    }
-    break;
-
-  case 15:
-
-/* Line 1806 of yacc.c  */
-#line 217 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleUndef(parser, (yyvsp[(2) - (4)].string));
-    free((yyvsp[(2) - (4)].string));
-    }
-    break;
-
-  case 16:
-
-/* Line 1806 of yacc.c  */
-#line 223 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleIfdef(parser, (yyvsp[(2) - (4)].string));
-    free((yyvsp[(2) - (4)].string));
-    }
-    break;
-
-  case 17:
-
-/* Line 1806 of yacc.c  */
-#line 229 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleIfndef(parser, (yyvsp[(2) - (4)].string));
-    free((yyvsp[(2) - (4)].string));
-    }
-    break;
-
-  case 18:
-
-/* Line 1806 of yacc.c  */
-#line 235 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleIf(parser);
-    }
-    break;
-
-  case 19:
-
-/* Line 1806 of yacc.c  */
-#line 240 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleElif(parser);
-    }
-    break;
-
-  case 20:
-
-/* Line 1806 of yacc.c  */
-#line 245 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleElse(parser);
-    }
-    break;
-
-  case 21:
-
-/* Line 1806 of yacc.c  */
-#line 250 "cmDependsFortranParser.y"
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleEndif(parser);
-    }
-    break;
-
-  case 22:
-
-/* Line 1806 of yacc.c  */
-#line 255 "cmDependsFortranParser.y"
-    {
-    free((yyvsp[(1) - (4)].string));
-    }
-    break;
-
-  case 47:
-
-/* Line 1806 of yacc.c  */
-#line 277 "cmDependsFortranParser.y"
-    { free ((yyvsp[(1) - (1)].string)); }
-    break;
-
-  case 48:
-
-/* Line 1806 of yacc.c  */
-#line 278 "cmDependsFortranParser.y"
-    { free ((yyvsp[(1) - (1)].string)); }
-    break;
-
-
-
-/* Line 1806 of yacc.c  */
-#line 1860 "cmDependsFortranParser.cxx"
-      default: break;
-    }
-  /* User semantic actions sometimes alter yychar, and that requires
-     that yytoken be updated with the new translation.  We take the
-     approach of translating immediately before every use of yytoken.
-     One alternative is translating here after every semantic action,
-     but that translation would be missed if the semantic action invokes
-     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
-     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
-     incorrect destructor might then be invoked immediately.  In the
-     case of YYERROR or YYBACKUP, subsequent parser actions might lead
-     to an incorrect destructor call or verbose syntax error message
-     before the lookahead is translated.  */
-  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-
-  *++yyvsp = yyval;
-
-  /* Now `shift' the result of the reduction.  Determine what state
-     that goes to, based on the state we popped back to and the rule
-     number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
-
-  goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
-  /* Make sure we have latest lookahead translation.  See comments at
-     user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
-  /* If not already recovering from an error, report this error.  */
-  if (!yyerrstatus)
-    {
-      ++yynerrs;
-#if ! YYERROR_VERBOSE
-      yyerror (YY_("syntax error"));
-#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
-                                        yyssp, yytoken)
-      {
-        char const *yymsgp = YY_("syntax error");
-        int yysyntax_error_status;
-        yysyntax_error_status = YYSYNTAX_ERROR;
-        if (yysyntax_error_status == 0)
-          yymsgp = yymsg;
-        else if (yysyntax_error_status == 1)
-          {
-            if (yymsg != yymsgbuf)
-              YYSTACK_FREE (yymsg);
-            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
-            if (!yymsg)
-              {
-                yymsg = yymsgbuf;
-                yymsg_alloc = sizeof yymsgbuf;
-                yysyntax_error_status = 2;
-              }
-            else
-              {
-                yysyntax_error_status = YYSYNTAX_ERROR;
-                yymsgp = yymsg;
-              }
-          }
-        yyerror (yymsgp);
-        if (yysyntax_error_status == 2)
-          goto yyexhaustedlab;
-      }
-# undef YYSYNTAX_ERROR
-#endif
-    }
-
-
-
-  if (yyerrstatus == 3)
-    {
-      /* If just tried and failed to reuse lookahead token after an
-         error, discard it.  */
-
-      if (yychar <= YYEOF)
-        {
-          /* Return failure if at end of input.  */
-          if (yychar == YYEOF)
-            YYABORT;
-        }
-      else
-        {
-          yydestruct ("Error: discarding",
-                      yytoken, &yylval);
-          yychar = YYEMPTY;
-        }
-    }
-
-#if 0
-  /* Else will try to reuse lookahead token after shifting the error
-     token.  */
-  goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR.  |
-`---------------------------------------------------*/
-yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
-
-  /* Do not reclaim the symbols of the rule which action triggered
-     this YYERROR.  */
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-  yystate = *yyssp;
-  goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR.  |
-`-------------------------------------------------------------*/
-yyerrlab1:
-#endif
-  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
-
-  for (;;)
-    {
-      yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
-        {
-          yyn += YYTERROR;
-          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-            {
-              yyn = yytable[yyn];
-              if (0 < yyn)
-                break;
-            }
-        }
-
-      /* Pop the current state because it cannot handle the error token.  */
-      if (yyssp == yyss)
-        YYABORT;
-
-
-      yydestruct ("Error: popping",
-                  yystos[yystate], yyvsp);
-      YYPOPSTACK (1);
-      yystate = *yyssp;
-      YY_STACK_PRINT (yyss, yyssp);
-    }
-
-  *++yyvsp = yylval;
-
-
-  /* Shift the error token.  */
-  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
-  yystate = yyn;
-  goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here.  |
-`-------------------------------------*/
-yyacceptlab:
-  yyresult = 0;
-  goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here.  |
-`-----------------------------------*/
-yyabortlab:
-  yyresult = 1;
-  goto yyreturn;
-
-#if !defined(yyoverflow) || YYERROR_VERBOSE
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here.  |
-`-------------------------------------------------*/
-yyexhaustedlab:
-  yyerror (YY_("memory exhausted"));
-  yyresult = 2;
-  /* Fall through.  */
-#endif
-
-yyreturn:
-  if (yychar != YYEMPTY)
-    {
-      /* Make sure we have latest lookahead translation.  See comments at
-         user semantic actions for why this is necessary.  */
-      yytoken = YYTRANSLATE (yychar);
-      yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval);
-    }
-  /* Do not reclaim the symbols of the rule which action triggered
-     this YYABORT or YYACCEPT.  */
-  YYPOPSTACK (yylen);
-  YY_STACK_PRINT (yyss, yyssp);
-  while (yyssp != yyss)
-    {
-      yydestruct ("Cleanup: popping",
-                  yystos[*yyssp], yyvsp);
-      YYPOPSTACK (1);
-    }
-#ifndef yyoverflow
-  if (yyss != yyssa)
-    YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
-  if (yymsg != yymsgbuf)
-    YYSTACK_FREE (yymsg);
-#endif
-  /* Make sure YYID is used.  */
-  return YYID (yyresult);
-}
-
-
-
-/* Line 2067 of yacc.c  */
-#line 286 "cmDependsFortranParser.y"
-
-/* End of grammar */
diff --git a/Source/cmDependsFortranParser.h b/Source/cmDependsFortranParser.h
deleted file mode 100644
index 399c3c8..0000000
--- a/Source/cmDependsFortranParser.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-#ifndef cmDependsFortranParser_h
-#define cmDependsFortranParser_h
-
-#include <stddef.h> /* size_t */
-
-/* Forward declare parser object type.  */
-typedef struct cmDependsFortranParser_s cmDependsFortranParser;
-
-/* Functions to enter/exit #include'd files in order.  */
-bool cmDependsFortranParser_FilePush(cmDependsFortranParser* parser,
-                                    const char* fname);
-bool cmDependsFortranParser_FilePop(cmDependsFortranParser* parser);
-
-/* Callbacks for lexer.  */
-int cmDependsFortranParser_Input(cmDependsFortranParser* parser,
-                                 char* buffer, size_t bufferSize);
-
-
-void cmDependsFortranParser_StringStart(cmDependsFortranParser* parser);
-const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser);
-void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser,
-                                         char c);
-
-void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser,
-                                           bool is_in);
-bool cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser);
-
-
-void cmDependsFortranParser_SetInPPFalseBranch(cmDependsFortranParser* parser,
-                                               bool is_in);
-bool cmDependsFortranParser_GetInPPFalseBranch(cmDependsFortranParser* parser);
-
-
-void cmDependsFortranParser_SetOldStartcond(cmDependsFortranParser* parser,
-                                            int arg);
-int cmDependsFortranParser_GetOldStartcond(cmDependsFortranParser* parser);
-
-/* Callbacks for parser.  */
-void cmDependsFortranParser_Error(cmDependsFortranParser* parser,
-                                  const char* message);
-void cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser,
-                                    const char* name);
-void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser,
-                                        const char* name);
-void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser,
-                                       const char* name);
-void cmDependsFortranParser_RuleDefine(cmDependsFortranParser* parser,
-                                       const char* name);
-void cmDependsFortranParser_RuleUndef(cmDependsFortranParser* parser,
-                                      const char* name);
-void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser* parser,
-                                      const char* name);
-void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser* parser,
-                                       const char* name);
-void cmDependsFortranParser_RuleIf(cmDependsFortranParser* parser);
-void cmDependsFortranParser_RuleElif(cmDependsFortranParser* parser);
-void cmDependsFortranParser_RuleElse(cmDependsFortranParser* parser);
-void cmDependsFortranParser_RuleEndif(cmDependsFortranParser* parser);
-
-/* Define the parser stack element type.  */
-typedef union cmDependsFortran_yystype_u cmDependsFortran_yystype;
-union cmDependsFortran_yystype_u
-{
-  char* string;
-};
-
-/* Setup the proper yylex interface.  */
-#define YY_EXTRA_TYPE cmDependsFortranParser*
-#define YY_DECL \
-int cmDependsFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
-#define YYSTYPE cmDependsFortran_yystype
-#define YYSTYPE_IS_DECLARED 1
-#if !defined(cmDependsFortranLexer_cxx)
-# include "cmDependsFortranLexer.h"
-#endif
-#if !defined(cmDependsFortranLexer_cxx)
-#if !defined(cmDependsFortranParser_cxx)
-# undef YY_EXTRA_TYPE
-# undef YY_DECL
-# undef YYSTYPE
-# undef YYSTYPE_IS_DECLARED
-#endif
-#endif
-
-#endif
diff --git a/Source/cmDependsFortranParser.y b/Source/cmDependsFortranParser.y
deleted file mode 100644
index a987c13..0000000
--- a/Source/cmDependsFortranParser.y
+++ /dev/null
@@ -1,282 +0,0 @@
-%{
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-/*-------------------------------------------------------------------------
-  Portions of this source have been derived from makedepf90 version 2.8.8,
-
-   Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann at iki.fi>
-
-  The code was originally distributed under the GPL but permission
-  from the copyright holder has been obtained to distribute this
-  derived work under the CMake license.
--------------------------------------------------------------------------*/
-
-/*
-
-This file must be translated to C and modified to build everywhere.
-
-Run bison like this:
-
-  bison --yacc --name-prefix=cmDependsFortran_yy
-        --defines=cmDependsFortranParserTokens.h
-         -ocmDependsFortranParser.cxx
-          cmDependsFortranParser.y
-
-Modify cmDependsFortranParser.cxx:
-  - remove TABs
-  - remove use of the 'register' storage class specifier
-  - Remove the yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
-*/
-
-/*-------------------------------------------------------------------------*/
-#define cmDependsFortranParser_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object.  */
-#include "cmDependsFortranParserTokens.h" /* Need YYSTYPE for YY_DECL.  */
-
-#include <cmsys/String.h>
-
-/* Configure the parser to use a lexer object.  */
-#define YYPARSE_PARAM yyscanner
-#define YYLEX_PARAM yyscanner
-#define YYERROR_VERBOSE 1
-#define cmDependsFortran_yyerror(x) \
-        cmDependsFortranError(yyscanner, x)
-
-/* Forward declare the lexer entry point.  */
-YY_DECL;
-
-/* Helper function to forward error callback.  */
-static void cmDependsFortranError(yyscan_t yyscanner, const char* message)
-{
-  cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-  cmDependsFortranParser_Error(parser, message);
-}
-
-static bool cmDependsFortranParserIsKeyword(const char* word,
-                                            const char* keyword)
-{
-  return cmsysString_strcasecmp(word, keyword) == 0;
-}
-
-/* Disable some warnings in the generated code.  */
-#ifdef _MSC_VER
-# pragma warning (disable: 4102) /* Unused goto label.  */
-# pragma warning (disable: 4065) /* Switch contains default but no case. */
-# pragma warning (disable: 4701) /* Local variable may not be initialized.  */
-# pragma warning (disable: 4702) /* Unreachable code.  */
-# pragma warning (disable: 4127) /* Conditional expression is constant.  */
-# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
-#endif
-%}
-
-/* Generate a reentrant parser object.  */
-%pure-parser
-
-%union {
-  char* string;
-}
-
-/*-------------------------------------------------------------------------*/
-/* Tokens */
-%token EOSTMT ASSIGNMENT_OP GARBAGE
-%token CPP_INCLUDE F90PPR_INCLUDE COCO_INCLUDE
-%token F90PPR_DEFINE CPP_DEFINE F90PPR_UNDEF CPP_UNDEF
-%token CPP_IFDEF CPP_IFNDEF CPP_IF CPP_ELSE CPP_ELIF CPP_ENDIF
-%token F90PPR_IFDEF F90PPR_IFNDEF F90PPR_IF
-%token F90PPR_ELSE F90PPR_ELIF F90PPR_ENDIF
-%token COMMA DCOLON
-%token <string> CPP_TOENDL
-%token <number> UNTERMINATED_STRING
-%token <string> STRING WORD
-%token <string> CPP_INCLUDE_ANGLE
-
-/*-------------------------------------------------------------------------*/
-/* grammar */
-%%
-
-code: /* empty */ | code stmt;
-
-stmt: keyword_stmt | assignment_stmt;
-
-assignment_stmt: WORD ASSIGNMENT_OP other EOSTMT    /* Ignore */
-    {
-    free($1);
-    }
-
-keyword_stmt:
-  WORD EOSTMT
-    {
-    if (cmDependsFortranParserIsKeyword($1, "interface"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_SetInInterface(parser, true);
-      }
-    free($1);
-    }
-| WORD WORD other EOSTMT
-    {
-    if (cmDependsFortranParserIsKeyword($1, "use"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleUse(parser, $2);
-      }
-    else if (cmDependsFortranParserIsKeyword($1, "module"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleModule(parser, $2);
-      }
-    else if (cmDependsFortranParserIsKeyword($1, "interface"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_SetInInterface(parser, true);
-      }
-    else if (cmDependsFortranParserIsKeyword($2, "interface") &&
-             cmDependsFortranParserIsKeyword($1, "end"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_SetInInterface(parser, false);
-      }
-    free($1);
-    free($2);
-    }
-| WORD DCOLON WORD other EOSTMT
-    {
-    if (cmDependsFortranParserIsKeyword($1, "use"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleUse(parser, $3);
-      }
-    free($1);
-    free($3);
-    }
-| WORD COMMA WORD DCOLON WORD other EOSTMT
-    {
-    if (cmDependsFortranParserIsKeyword($1, "use") &&
-        cmDependsFortranParserIsKeyword($3, "non_intrinsic") )
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleUse(parser, $5);
-      }
-    free($1);
-    free($3);
-    free($5);
-    }
-| WORD STRING other EOSTMT /* Ignore */
-    {
-    if (cmDependsFortranParserIsKeyword($1, "include"))
-      {
-      cmDependsFortranParser* parser =
-        cmDependsFortran_yyget_extra(yyscanner);
-      cmDependsFortranParser_RuleInclude(parser, $2);
-      }
-    free($1);
-    free($2);
-    }
-| CPP_INCLUDE_ANGLE other EOSTMT
-    {
-    cmDependsFortranParser* parser =
-      cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleInclude(parser, $1);
-    free($1);
-    }
-| include STRING other EOSTMT
-    {
-    cmDependsFortranParser* parser =
-      cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleInclude(parser, $2);
-    free($2);
-    }
-| define WORD other EOSTMT
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleDefine(parser, $2);
-    free($2);
-    }
-| undef WORD other EOSTMT
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleUndef(parser, $2);
-    free($2);
-    }
-| ifdef WORD other EOSTMT
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleIfdef(parser, $2);
-    free($2);
-    }
-| ifndef WORD other EOSTMT
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleIfndef(parser, $2);
-    free($2);
-    }
-| if other EOSTMT
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleIf(parser);
-    }
-| elif other EOSTMT
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleElif(parser);
-    }
-| else other EOSTMT
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleElse(parser);
-    }
-| endif other EOSTMT
-    {
-    cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
-    cmDependsFortranParser_RuleEndif(parser);
-    }
-| WORD GARBAGE other EOSTMT             /* Ignore */
-    {
-    free($1);
-    }
-| GARBAGE other EOSTMT
-| EOSTMT
-| error
-;
-
-
-
-include: CPP_INCLUDE | F90PPR_INCLUDE | COCO_INCLUDE ;
-define: CPP_DEFINE | F90PPR_DEFINE;
-undef: CPP_UNDEF | F90PPR_UNDEF ;
-ifdef: CPP_IFDEF | F90PPR_IFDEF ;
-ifndef: CPP_IFNDEF | F90PPR_IFNDEF ;
-if: CPP_IF | F90PPR_IF ;
-elif: CPP_ELIF | F90PPR_ELIF ;
-else: CPP_ELSE | F90PPR_ELSE ;
-endif: CPP_ENDIF | F90PPR_ENDIF ;
-other: /* empty */ | other misc_code ;
-
-misc_code:
-  WORD                { free ($1); }
-| STRING              { free ($1); }
-| GARBAGE
-| ASSIGNMENT_OP
-| DCOLON
-| COMMA
-| UNTERMINATED_STRING
-;
-
-%%
-/* End of grammar */
diff --git a/Source/cmDependsFortranParserTokens.h b/Source/cmDependsFortranParserTokens.h
deleted file mode 100644
index 941eda0..0000000
--- a/Source/cmDependsFortranParserTokens.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.5.  */
-
-/* Bison interface for Yacc-like parsers in C
-
-      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     EOSTMT = 258,
-     ASSIGNMENT_OP = 259,
-     GARBAGE = 260,
-     CPP_INCLUDE = 261,
-     F90PPR_INCLUDE = 262,
-     COCO_INCLUDE = 263,
-     F90PPR_DEFINE = 264,
-     CPP_DEFINE = 265,
-     F90PPR_UNDEF = 266,
-     CPP_UNDEF = 267,
-     CPP_IFDEF = 268,
-     CPP_IFNDEF = 269,
-     CPP_IF = 270,
-     CPP_ELSE = 271,
-     CPP_ELIF = 272,
-     CPP_ENDIF = 273,
-     F90PPR_IFDEF = 274,
-     F90PPR_IFNDEF = 275,
-     F90PPR_IF = 276,
-     F90PPR_ELSE = 277,
-     F90PPR_ELIF = 278,
-     F90PPR_ENDIF = 279,
-     COMMA = 280,
-     DCOLON = 281,
-     CPP_TOENDL = 282,
-     UNTERMINATED_STRING = 283,
-     STRING = 284,
-     WORD = 285,
-     CPP_INCLUDE_ANGLE = 286
-   };
-#endif
-/* Tokens.  */
-#define EOSTMT 258
-#define ASSIGNMENT_OP 259
-#define GARBAGE 260
-#define CPP_INCLUDE 261
-#define F90PPR_INCLUDE 262
-#define COCO_INCLUDE 263
-#define F90PPR_DEFINE 264
-#define CPP_DEFINE 265
-#define F90PPR_UNDEF 266
-#define CPP_UNDEF 267
-#define CPP_IFDEF 268
-#define CPP_IFNDEF 269
-#define CPP_IF 270
-#define CPP_ELSE 271
-#define CPP_ELIF 272
-#define CPP_ENDIF 273
-#define F90PPR_IFDEF 274
-#define F90PPR_IFNDEF 275
-#define F90PPR_IF 276
-#define F90PPR_ELSE 277
-#define F90PPR_ELIF 278
-#define F90PPR_ENDIF 279
-#define COMMA 280
-#define DCOLON 281
-#define CPP_TOENDL 282
-#define UNTERMINATED_STRING 283
-#define STRING 284
-#define WORD 285
-#define CPP_INCLUDE_ANGLE 286
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-{
-
-/* Line 2068 of yacc.c  */
-#line 89 "cmDependsFortranParser.y"
-
-  char* string;
-
-
-
-/* Line 2068 of yacc.c  */
-#line 118 "cmDependsFortranParserTokens.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
index 8854c36..b6c5fde 100644
--- a/Source/cmDocumentation.h
+++ b/Source/cmDocumentation.h
@@ -13,7 +13,6 @@
 #define _cmDocumentation_h
 
 #include "cmStandardIncludes.h"
-#include "cmProperty.h"
 #include "cmDocumentationFormatter.h"
 #include "cmDocumentationSection.h"
 #include "cmake.h"
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index e021d0b..41785c2 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -156,7 +156,7 @@ bool cmExecProgramCommand::RunCommand(const char* command,
     verbose = false;
     }
 
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
   // if the command does not start with a quote, then
   // try to find the program, and if the program can not be
   // found use system to run the command as it must be a built in
@@ -219,7 +219,7 @@ bool cmExecProgramCommand::RunCommand(const char* command,
     return false;
     }
 
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
   if(dir)
     {
     cmsysProcess_SetWorkingDirectory(cp, dir);
@@ -305,7 +305,7 @@ bool cmExecProgramCommand::RunCommand(const char* command,
     }
   if(!msg.empty())
     {
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
     // Old Windows process execution printed this info.
     msg += "\n\nfor command: ";
     msg += command;
diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h
index 23d10f9..adefdf9 100644
--- a/Source/cmExecProgramCommand.h
+++ b/Source/cmExecProgramCommand.h
@@ -50,12 +50,6 @@ public:
    */
   virtual bool IsScriptable() const { return true; }
 
-  /** This command is kept for compatibility with older CMake versions. */
-  virtual bool IsDiscouraged() const
-    {
-    return true;
-    }
-
   cmTypeMacro(cmExecProgramCommand, cmCommand);
 private:
   static bool RunCommand(const char* command, std::string& output,
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index bf18deb..fed0dbc 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -18,7 +18,7 @@
 
 //----------------------------------------------------------------------------
 cmExportBuildFileGenerator::cmExportBuildFileGenerator()
-  : Backtrace(NULL)
+  : Backtrace()
 {
   this->Makefile = 0;
   this->ExportSet = 0;
@@ -27,6 +27,7 @@ cmExportBuildFileGenerator::cmExportBuildFileGenerator()
 //----------------------------------------------------------------------------
 bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
 {
+  std::vector<cmGeneratorTarget*> allTargets;
   {
   std::string expectedTargets;
   std::string sep;
@@ -36,10 +37,11 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
         tei = targets.begin();
       tei != targets.end(); ++tei)
     {
-    cmTarget *te = this->Makefile->FindTargetToUse(*tei);
-    expectedTargets += sep + this->Namespace + te->GetExportName();
+    cmGeneratorTarget *te = this->Makefile
+                                ->FindGeneratorTargetToUse(*tei);
+    expectedTargets += sep + this->Namespace + te->Target->GetExportName();
     sep = " ";
-    if(this->ExportedTargets.insert(te).second)
+    if(this->ExportedTargets.insert(te->Target).second)
       {
       this->Exports.push_back(te);
       }
@@ -63,11 +65,12 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
   std::vector<std::string> missingTargets;
 
   // Create all the imported targets.
-  for(std::vector<cmTarget*>::const_iterator
+  for(std::vector<cmGeneratorTarget*>::const_iterator
         tei = this->Exports.begin();
       tei != this->Exports.end(); ++tei)
     {
-    cmTarget* te = *tei;
+    cmGeneratorTarget* gte = *tei;
+    cmTarget* te = gte->Target;
     this->GenerateImportTargetCode(os, te);
 
     te->AppendBuildInterfaceIncludes();
@@ -103,7 +106,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
                                     cmGeneratorExpression::BuildInterface,
                                     properties, missingTargets);
       }
-    this->PopulateCompatibleInterfaceProperties(te, properties);
+    this->PopulateCompatibleInterfaceProperties(gte, properties);
 
     this->GenerateInterfaceProperties(te, os, properties);
     }
@@ -129,12 +132,12 @@ cmExportBuildFileGenerator
                               std::string const& suffix,
                               std::vector<std::string> &missingTargets)
 {
-  for(std::vector<cmTarget*>::const_iterator
+  for(std::vector<cmGeneratorTarget*>::const_iterator
         tei = this->Exports.begin();
       tei != this->Exports.end(); ++tei)
     {
     // Collect import properties for this target.
-    cmTarget* target = *tei;
+    cmGeneratorTarget* target = *tei;
     ImportPropertyMap properties;
 
     if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
@@ -147,10 +150,12 @@ cmExportBuildFileGenerator
       if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
         {
         this->SetImportDetailProperties(config, suffix,
-                                        target, properties, missingTargets);
+                                        target,
+                                        properties, missingTargets);
         this->SetImportLinkInterface(config, suffix,
-                                    cmGeneratorExpression::BuildInterface,
-                                    target, properties, missingTargets);
+                                     cmGeneratorExpression::BuildInterface,
+                                     target,
+                                     properties, missingTargets);
         }
 
       // TOOD: PUBLIC_HEADER_LOCATION
@@ -160,7 +165,8 @@ cmExportBuildFileGenerator
       //                              properties);
 
       // Generate code in the export file.
-      this->GenerateImportPropertyCode(os, config, target, properties);
+      this->GenerateImportPropertyCode(os, config, target->Target,
+                                       properties);
       }
     }
 }
@@ -176,17 +182,18 @@ void
 cmExportBuildFileGenerator
 ::SetImportLocationProperty(const std::string& config,
                             std::string const& suffix,
-                            cmTarget* target, ImportPropertyMap& properties)
+                            cmGeneratorTarget* target,
+                            ImportPropertyMap& properties)
 {
   // Get the makefile in which to lookup target information.
-  cmMakefile* mf = target->GetMakefile();
+  cmMakefile* mf = target->Makefile;
 
   // Add the main target file.
   {
   std::string prop = "IMPORTED_LOCATION";
   prop += suffix;
   std::string value;
-  if(target->IsAppBundleOnApple())
+  if(target->Target->IsAppBundleOnApple())
     {
     value = target->GetFullPath(config, false);
     }
@@ -204,13 +211,13 @@ cmExportBuildFileGenerator
   // Add the import library for windows DLLs.
   if(dll_platform &&
      (target->GetType() == cmTarget::SHARED_LIBRARY ||
-      target->IsExecutableWithExports()) &&
+      target->Target->IsExecutableWithExports()) &&
      mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
     {
     std::string prop = "IMPORTED_IMPLIB";
     prop += suffix;
     std::string value = target->GetFullPath(config, true);
-    target->GetImplibGNUtoMS(value, value,
+    target->Target->GetImplibGNUtoMS(value, value,
                              "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
     properties[prop] = value;
     }
@@ -326,12 +333,12 @@ cmExportBuildFileGenerator
 }
 
 std::string
-cmExportBuildFileGenerator::InstallNameDir(cmTarget* target,
+cmExportBuildFileGenerator::InstallNameDir(cmGeneratorTarget* target,
                                            const std::string& config)
 {
   std::string install_name_dir;
 
-  cmMakefile* mf = target->GetMakefile();
+  cmMakefile* mf = target->Target->GetMakefile();
   if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
     {
     install_name_dir =
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 8b5694c..ff3d2e1 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -68,17 +68,18 @@ protected:
   /** Fill in properties indicating built file locations.  */
   void SetImportLocationProperty(const std::string& config,
                                  std::string const& suffix,
-                                 cmTarget* target,
+                                 cmGeneratorTarget* target,
                                  ImportPropertyMap& properties);
 
-  std::string InstallNameDir(cmTarget* target, const std::string& config);
+  std::string InstallNameDir(cmGeneratorTarget* target,
+                             const std::string& config);
 
   std::vector<std::string>
   FindNamespaces(cmMakefile* mf, const std::string& name);
 
   std::vector<std::string> Targets;
   cmExportSet *ExportSet;
-  std::vector<cmTarget*> Exports;
+  std::vector<cmGeneratorTarget*> Exports;
   cmMakefile* Makefile;
   cmListFileBacktrace Backtrace;
 };
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 43d26f9..96ea77b 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -177,6 +177,12 @@ bool cmExportCommand
           this->SetError(e.str());
           return false;
           }
+        if (target->GetType() == cmTarget::UTILITY)
+          {
+          this->SetError("given custom target \"" + *currentTarget
+                         + "\" which may not be exported.");
+          return false;
+          }
         }
       else
         {
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index a51fb2a..9a7d73f 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -23,12 +23,28 @@
 #include "cmVersion.h"
 #include "cmComputeLinkInformation.h"
 #include "cmAlgorithms.h"
+#include "cmOutputConverter.h"
 
 #include <cmsys/auto_ptr.hxx>
 #include <cmsys/FStream.hxx>
 #include <assert.h>
 
 //----------------------------------------------------------------------------
+static std::string cmExportFileGeneratorEscape(std::string const& str)
+{
+  // Escape a property value for writing into a .cmake file.
+  std::string result = cmOutputConverter::EscapeForCMake(str);
+  // Un-escape variable references generated by our own export code.
+  cmSystemTools::ReplaceString(result,
+                               "\\${_IMPORT_PREFIX}",
+                               "${_IMPORT_PREFIX}");
+  cmSystemTools::ReplaceString(result,
+                               "\\${CMAKE_IMPORT_LIBRARY_SUFFIX}",
+                               "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+  return result;
+}
+
+//----------------------------------------------------------------------------
 cmExportFileGenerator::cmExportFileGenerator()
 {
   this->AppendMode = false;
@@ -509,7 +525,7 @@ void getPropertyContents(cmTarget const* tgt, const std::string& prop,
 }
 
 //----------------------------------------------------------------------------
-void getCompatibleInterfaceProperties(cmTarget *target,
+void getCompatibleInterfaceProperties(cmGeneratorTarget *target,
                                       std::set<std::string> &ifaceProperties,
                                       const std::string& config)
 {
@@ -517,7 +533,7 @@ void getCompatibleInterfaceProperties(cmTarget *target,
 
   if (!info)
     {
-    cmMakefile* mf = target->GetMakefile();
+    cmMakefile* mf = target->Target->GetMakefile();
     std::ostringstream e;
     e << "Exporting the target \"" << target->GetName() << "\" is not "
         "allowed since its linker language cannot be determined";
@@ -552,9 +568,10 @@ void getCompatibleInterfaceProperties(cmTarget *target,
 
 //----------------------------------------------------------------------------
 void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
-                                cmTarget *target,
+                                cmGeneratorTarget *gtarget,
                                 ImportPropertyMap &properties)
 {
+  cmTarget *target = gtarget->Target;
   this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL",
                                 target, properties);
   this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
@@ -575,7 +592,7 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
 
   if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
     {
-    getCompatibleInterfaceProperties(target, ifaceProperties, "");
+    getCompatibleInterfaceProperties(gtarget, ifaceProperties, "");
 
     std::vector<std::string> configNames;
     target->GetMakefile()->GetConfigurations(configNames);
@@ -583,7 +600,7 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
     for (std::vector<std::string>::const_iterator ci = configNames.begin();
       ci != configNames.end(); ++ci)
       {
-      getCompatibleInterfaceProperties(target, ifaceProperties, *ci);
+      getCompatibleInterfaceProperties(gtarget, ifaceProperties, *ci);
       }
     }
 
@@ -608,7 +625,8 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget const* target,
     for(ImportPropertyMap::const_iterator pi = properties.begin();
         pi != properties.end(); ++pi)
       {
-      os << "  " << pi->first << " \"" << pi->second << "\"\n";
+      os << "  " << pi->first << " "
+         << cmExportFileGeneratorEscape(pi->second) << "\n";
       }
     os << ")\n\n";
     }
@@ -774,12 +792,12 @@ void
 cmExportFileGenerator
 ::SetImportLinkInterface(const std::string& config, std::string const& suffix,
                     cmGeneratorExpression::PreprocessContext preprocessRule,
-                    cmTarget* target, ImportPropertyMap& properties,
+                    cmGeneratorTarget* target, ImportPropertyMap& properties,
                     std::vector<std::string>& missingTargets)
 {
   // Add the transitive link dependencies for this configuration.
-  cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
-                                                                  target);
+  cmLinkInterface const* iface = target->GetLinkInterface(config,
+                                                          target->Target);
   if (!iface)
     {
     return;
@@ -812,12 +830,14 @@ cmExportFileGenerator
     }
 
   const bool newCMP0022Behavior =
-                        target->GetPolicyStatusCMP0022() != cmPolicies::WARN
-                     && target->GetPolicyStatusCMP0022() != cmPolicies::OLD;
+                        target->Target
+                              ->GetPolicyStatusCMP0022() != cmPolicies::WARN
+                     && target->Target
+                              ->GetPolicyStatusCMP0022() != cmPolicies::OLD;
 
   if(newCMP0022Behavior && !this->ExportOld)
     {
-    cmMakefile *mf = target->GetMakefile();
+    cmMakefile *mf = target->Target->GetMakefile();
     std::ostringstream e;
     e << "Target \"" << target->GetName() << "\" has policy CMP0022 enabled, "
          "but also has old-style LINK_INTERFACE_LIBRARIES properties "
@@ -837,7 +857,7 @@ cmExportFileGenerator
                                                          preprocessRule);
   if (!prepro.empty())
     {
-    this->ResolveTargetsInGeneratorExpressions(prepro, target,
+    this->ResolveTargetsInGeneratorExpressions(prepro, target->Target,
                                                missingTargets,
                                                ReplaceFreeTargets);
     properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
@@ -849,12 +869,13 @@ void
 cmExportFileGenerator
 ::SetImportDetailProperties(const std::string& config,
                             std::string const& suffix,
-                            cmTarget* target, ImportPropertyMap& properties,
+                            cmGeneratorTarget* target,
+                            ImportPropertyMap& properties,
                             std::vector<std::string>& missingTargets
                            )
 {
   // Get the makefile in which to lookup target information.
-  cmMakefile* mf = target->GetMakefile();
+  cmMakefile* mf = target->Makefile;
 
   // Add the soname for unix shared libraries.
   if(target->GetType() == cmTarget::SHARED_LIBRARY ||
@@ -887,8 +908,8 @@ cmExportFileGenerator
     }
 
   // Add the transitive link dependencies for this configuration.
-  if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
-                                                                     target))
+  if(cmLinkInterface const* iface =
+                            target->GetLinkInterface(config, target->Target))
     {
     this->SetImportLinkProperty(suffix, target,
                                 "IMPORTED_LINK_INTERFACE_LANGUAGES",
@@ -914,7 +935,7 @@ template <typename T>
 void
 cmExportFileGenerator
 ::SetImportLinkProperty(std::string const& suffix,
-                        cmTarget* target,
+                        cmGeneratorTarget* target,
                         const std::string& propName,
                         std::vector<T> const& entries,
                         ImportPropertyMap& properties,
@@ -938,7 +959,7 @@ cmExportFileGenerator
     sep = ";";
 
     std::string temp = *li;
-    this->AddTargetNamespace(temp, target, missingTargets);
+    this->AddTargetNamespace(temp, target->Target, missingTargets);
     link_entries += temp;
     }
 
@@ -1112,7 +1133,8 @@ cmExportFileGenerator
   for(ImportPropertyMap::const_iterator pi = properties.begin();
       pi != properties.end(); ++pi)
     {
-    os << "  " << pi->first << " \"" << pi->second << "\"\n";
+    os << "  " << pi->first << " "
+       << cmExportFileGeneratorEscape(pi->second) << "\n";
     }
   os << "  )\n"
      << "\n";
@@ -1223,7 +1245,7 @@ cmExportFileGenerator
     ImportPropertyMap::const_iterator pi = properties.find(*li);
     if (pi != properties.end())
       {
-      os << "\"" << pi->second << "\" ";
+      os << cmExportFileGeneratorEscape(pi->second) << " ";
       }
     }
 
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index b6f4166..44f779b 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -92,13 +92,15 @@ protected:
   // Collect properties with detailed information about targets beyond
   // their location on disk.
   void SetImportDetailProperties(const std::string& config,
-                                 std::string const& suffix, cmTarget* target,
+                                 std::string const& suffix,
+                                 cmGeneratorTarget* target,
                                  ImportPropertyMap& properties,
                                  std::vector<std::string>& missingTargets);
 
   template <typename T>
   void SetImportLinkProperty(std::string const& suffix,
-                             cmTarget* target, const std::string& propName,
+                             cmGeneratorTarget* target,
+                             const std::string& propName,
                              std::vector<T> const& entries,
                              ImportPropertyMap& properties,
                              std::vector<std::string>& missingTargets);
@@ -130,7 +132,7 @@ protected:
                                  std::vector<std::string> &missingTargets);
   void PopulateInterfaceProperty(const std::string& propName, cmTarget *target,
                                  ImportPropertyMap &properties);
-  void PopulateCompatibleInterfaceProperties(cmTarget *target,
+  void PopulateCompatibleInterfaceProperties(cmGeneratorTarget *target,
                                  ImportPropertyMap &properties);
   void GenerateInterfaceProperties(cmTarget const* target, std::ostream& os,
                                    const ImportPropertyMap &properties);
@@ -148,7 +150,7 @@ protected:
   void SetImportLinkInterface(const std::string& config,
                     std::string const& suffix,
                     cmGeneratorExpression::PreprocessContext preprocessRule,
-                    cmTarget* target, ImportPropertyMap& properties,
+                    cmGeneratorTarget* target, ImportPropertyMap& properties,
                     std::vector<std::string>& missingTargets);
 
   enum FreeTargetsReplace {
@@ -198,7 +200,7 @@ private:
 
   virtual void ReplaceInstallPrefix(std::string &input);
 
-  virtual std::string InstallNameDir(cmTarget* target,
+  virtual std::string InstallNameDir(cmGeneratorTarget* target,
                                      const std::string& config) = 0;
 };
 
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 89c6ca2..7ffab0c 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -72,8 +72,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
 
   // Set an _IMPORT_PREFIX variable for import location properties
   // to reference if they are relative to the install prefix.
-  std::string installPrefix =
-    this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+  std::string installPrefix = this->IEGen->GetLocalGenerator()
+      ->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
   std::string const& expDest = this->IEGen->GetDestination();
   if(cmSystemTools::FileIsFullPath(expDest))
     {
@@ -193,7 +193,11 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
 
     this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
                                   te, properties);
-    this->PopulateCompatibleInterfaceProperties(te, properties);
+    cmGeneratorTarget *gtgt = te->GetMakefile()
+                                ->GetGlobalGenerator()
+                                ->GetGeneratorTarget(te);
+
+    this->PopulateCompatibleInterfaceProperties(gtgt, properties);
 
     this->GenerateInterfaceProperties(te, os, properties);
     }
@@ -358,12 +362,14 @@ cmExportInstallFileGenerator
     if(!properties.empty())
       {
       // Get the rest of the target details.
+      cmGeneratorTarget *gtgt = te->Target->GetMakefile()
+                    ->GetGlobalGenerator()->GetGeneratorTarget(te->Target);
       this->SetImportDetailProperties(config, suffix,
-                                      te->Target, properties, missingTargets);
+                                      gtgt, properties, missingTargets);
 
       this->SetImportLinkInterface(config, suffix,
                                    cmGeneratorExpression::InstallInterface,
-                                   te->Target, properties, missingTargets);
+                                   gtgt, properties, missingTargets);
 
       // TOOD: PUBLIC_HEADER_LOCATION
       // This should wait until the build feature propagation stuff
@@ -396,7 +402,7 @@ cmExportInstallFileGenerator
     }
 
   // Get the target to be installed.
-  cmTarget* target = itgen->GetTarget();
+  cmTarget* target = itgen->GetTarget()->Target;
 
   // Construct the installed location of the target.
   std::string dest = itgen->GetDestination(config);
@@ -540,12 +546,12 @@ cmExportInstallFileGenerator
 }
 
 std::string
-cmExportInstallFileGenerator::InstallNameDir(cmTarget* target,
+cmExportInstallFileGenerator::InstallNameDir(cmGeneratorTarget* target,
                                              const std::string&)
 {
   std::string install_name_dir;
 
-  cmMakefile* mf = target->GetMakefile();
+  cmMakefile* mf = target->Target->GetMakefile();
   if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
     {
     install_name_dir =
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 6f86ac9..b06fee5 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -83,7 +83,8 @@ protected:
                                  std::set<std::string>& importedLocations
                                 );
 
-  std::string InstallNameDir(cmTarget* target, const std::string& config);
+  std::string InstallNameDir(cmGeneratorTarget* target,
+                             const std::string& config);
 
   cmInstallExportGenerator* IEGen;
 
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index cb150a7..fde8fb1 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -11,7 +11,6 @@
 ============================================================================*/
 #include "cmExportLibraryDependenciesCommand.h"
 #include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
 #include "cmGeneratedFileStream.h"
 #include "cmake.h"
 #include "cmVersion.h"
@@ -82,15 +81,14 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const
   // the project.
   cmake* cm = this->Makefile->GetCMakeInstance();
   cmGlobalGenerator* global = cm->GetGlobalGenerator();
-  const std::vector<cmLocalGenerator *>& locals = global->GetLocalGenerators();
+  const std::vector<cmMakefile*>& locals = global->GetMakefiles();
   std::map<std::string, std::string> libDepsOld;
   std::map<std::string, std::string> libDepsNew;
   std::map<std::string, std::string> libTypes;
-  for(std::vector<cmLocalGenerator *>::const_iterator i = locals.begin();
+  for(std::vector<cmMakefile*>::const_iterator i = locals.begin();
       i != locals.end(); ++i)
     {
-    const cmLocalGenerator* gen = *i;
-    const cmTargets &tgts = gen->GetMakefile()->GetTargets();
+    const cmTargets &tgts = (*i)->GetTargets();
     for(cmTargets::const_iterator l = tgts.begin();
         l != tgts.end(); ++l)
       {
diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h
index 2ea4e79..81aa21a 100644
--- a/Source/cmExportLibraryDependenciesCommand.h
+++ b/Source/cmExportLibraryDependenciesCommand.h
@@ -22,7 +22,6 @@ public:
   virtual bool InitialPass(std::vector<std::string> const& args,
                            cmExecutionStatus &status);
   virtual std::string GetName() const { return "export_library_dependencies";}
-  virtual bool IsDiscouraged() const { return true; }
 
   virtual void FinalPass();
   virtual bool HasFinalPass() const { return true; }
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index eb8d193..ba66531 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -13,9 +13,16 @@
 #include "cmExportTryCompileFileGenerator.h"
 
 #include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 
 //----------------------------------------------------------------------------
+cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator(
+    cmGlobalGenerator* gg)
+{
+  gg->CreateGenerationObjects(cmGlobalGenerator::ImportedOnly);
+}
+
 bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
 {
   std::set<cmTarget const*> emitted;
@@ -99,8 +106,6 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget const* target,
         || i->first.find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0
         || i->first.find("INTERFACE_LINK_LIBRARIES") == 0)
       {
-      const std::string libs = i->second.GetValue();
-
       std::string evalResult = this->FindTargets(i->first,
                                                  target, emitted);
 
@@ -118,13 +123,14 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget const* target,
       }
     }
 }
+
 std::string
-cmExportTryCompileFileGenerator::InstallNameDir(cmTarget* target,
+cmExportTryCompileFileGenerator::InstallNameDir(cmGeneratorTarget* target,
                                                 const std::string& config)
 {
   std::string install_name_dir;
 
-  cmMakefile* mf = target->GetMakefile();
+  cmMakefile* mf = target->Target->GetMakefile();
   if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
     {
     install_name_dir =
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index ec70d81..8838eca 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -9,8 +9,8 @@
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the License for more information.
 ============================================================================*/
-#ifndef cmExportInstallFileGenerator_h
-#define cmExportInstallFileGenerator_h
+#ifndef cmExportTryCompileFileGenerator_h
+#define cmExportTryCompileFileGenerator_h
 
 #include "cmExportFileGenerator.h"
 
@@ -20,6 +20,8 @@ class cmInstallTargetGenerator;
 class cmExportTryCompileFileGenerator: public cmExportFileGenerator
 {
 public:
+  cmExportTryCompileFileGenerator(cmGlobalGenerator* gg);
+
   /** Set the list of targets to export.  */
   void SetExports(const std::vector<cmTarget const*> &exports)
     { this->Exports = exports; }
@@ -43,7 +45,7 @@ protected:
                           ImportPropertyMap& properties,
                           std::set<cmTarget const*> &emitted);
 
-  std::string InstallNameDir(cmTarget* target,
+  std::string InstallNameDir(cmGeneratorTarget* target,
                              const std::string& config);
 private:
   std::string FindTargets(const std::string& prop, cmTarget const* tgt,
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index e374387..dfd51c7 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -313,7 +313,7 @@ void cmExtraCodeBlocksGenerator
         "      "<<virtualFolders<<"\n"
         "      <Build>\n";
 
-  this->AppendTarget(fout, "all", 0, make.c_str(), mf, compiler.c_str());
+  this->AppendTarget(fout, "all", 0, make.c_str(), lgs[0], compiler.c_str());
 
   // add all executable and library targets and some of the GLOBAL
   // and UTILITY targets
@@ -335,7 +335,7 @@ void cmExtraCodeBlocksGenerator
                      makefile->GetHomeOutputDirectory())==0)
             {
             this->AppendTarget(fout, ti->first, 0,
-                               make.c_str(), makefile, compiler.c_str());
+                               make.c_str(), *lg, compiler.c_str());
             }
           }
           break;
@@ -351,7 +351,7 @@ void cmExtraCodeBlocksGenerator
             }
 
           this->AppendTarget(fout, ti->first, 0,
-                                 make.c_str(), makefile, compiler.c_str());
+                                 make.c_str(), *lg, compiler.c_str());
           break;
         case cmTarget::EXECUTABLE:
         case cmTarget::STATIC_LIBRARY:
@@ -360,11 +360,11 @@ void cmExtraCodeBlocksGenerator
         case cmTarget::OBJECT_LIBRARY:
           {
           this->AppendTarget(fout, ti->first, &ti->second,
-                             make.c_str(), makefile, compiler.c_str());
+                             make.c_str(), *lg, compiler.c_str());
           std::string fastTarget = ti->first;
           fastTarget += "/fast";
           this->AppendTarget(fout, fastTarget, &ti->second,
-                             make.c_str(), makefile, compiler.c_str());
+                             make.c_str(), *lg, compiler.c_str());
           }
           break;
         default:
@@ -519,14 +519,16 @@ void cmExtraCodeBlocksGenerator
 
 // Write a dummy file for OBJECT libraries, so C::B can reference some file
 std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile(
-                                        cmMakefile* mf, cmTarget* target) const
+                                        cmLocalGenerator* lg,
+                                        cmTarget* target) const
 {
+  cmMakefile *mf = lg->GetMakefile();
   // this file doesn't seem to be used by C::B in custom makefile mode,
   // but we generate a unique file for each OBJECT library so in case
   // C::B uses it in some way, the targets don't interfere with each other.
   std::string filename = mf->GetCurrentBinaryDirectory();
   filename += "/";
-  filename += mf->GetLocalGenerator()->GetTargetDirectory(*target);
+  filename += lg->GetTargetDirectory(*target);
   filename += "/";
   filename += target->GetName();
   filename += ".objlib";
@@ -547,9 +549,10 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
                                               const std::string& targetName,
                                               cmTarget* target,
                                               const char* make,
-                                              const cmMakefile* makefile,
+                                              const cmLocalGenerator* lg,
                                               const char* compiler)
 {
+  cmMakefile const* makefile = lg->GetMakefile();
   std::string makefileName = makefile->GetCurrentBinaryDirectory();
   makefileName += "/Makefile";
 
@@ -583,12 +586,14 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
     std::string location;
     if ( target->GetType()==cmTarget::OBJECT_LIBRARY)
       {
-      location = this->CreateDummyTargetFile(const_cast<cmMakefile*>(makefile),
+      location = this->CreateDummyTargetFile(const_cast<cmLocalGenerator*>(lg),
                                              target);
       }
     else
       {
-      location = target->GetLocation(buildType);
+      cmGeneratorTarget* gt =
+          this->GlobalGenerator->GetGeneratorTarget(target);
+      location = gt->GetLocation(buildType);
       }
 
     fout<<"         <Option output=\"" << location
@@ -604,7 +609,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
 
     // the compilerdefines for this target
     std::vector<std::string> cdefs;
-    target->GetCompileDefinitions(cdefs, buildType, "C");
+    gtgt->GetCompileDefinitions(cdefs, buildType, "C");
 
     // Expand the list.
     for(std::vector<std::string>::const_iterator di = cdefs.begin();
@@ -618,8 +623,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
     std::set<std::string> uniqIncludeDirs;
 
     std::vector<std::string> includes;
-    target->GetMakefile()->GetLocalGenerator()->
-      GetIncludeDirectories(includes, gtgt, "C", buildType);
+    lg->GetIncludeDirectories(includes, gtgt, "C", buildType);
 
     uniqIncludeDirs.insert(includes.begin(), includes.end());
 
diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h
index 97da1b8..e5ede9a 100644
--- a/Source/cmExtraCodeBlocksGenerator.h
+++ b/Source/cmExtraCodeBlocksGenerator.h
@@ -48,7 +48,8 @@ private:
 
   void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
                                 const std::string& filename);
-  std::string CreateDummyTargetFile(cmMakefile* mf, cmTarget* target) const;
+  std::string CreateDummyTargetFile(cmLocalGenerator* lg,
+                                    cmTarget* target) const;
 
   std::string GetCBCompilerId(const cmMakefile* mf);
   int GetCBTargetType(cmTarget* target);
@@ -58,7 +59,7 @@ private:
                     const std::string& targetName,
                     cmTarget* target,
                     const char* make,
-                    const cmMakefile* makefile,
+                    const cmLocalGenerator* lg,
                     const char* compiler);
 
 };
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index 9705d2b..c2cff14 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -141,24 +141,6 @@ void cmExtraCodeLiteGenerator
     return;
     }
 
-  // figure out the compiler
-  //std::string compiler = this->GetCBCompilerId(mf);
-  std::string workspaceSourcePath = mf->GetHomeDirectory();
-  std::string workspaceOutputDir =  mf->GetHomeOutputDirectory();
-  std::vector<std::string> outputFiles = mf->GetOutputFiles();
-  std::string projectName = mf->GetProjectName();
-  std::string incDirs;
-  std::vector<cmValueWithOrigin> incDirsVec =
-    mf->GetIncludeDirectoriesEntries();
-  std::vector<cmValueWithOrigin>::const_iterator iterInc = incDirsVec.begin();
-
-  //std::cout << "GetIncludeDirectories:" << std::endl;
-  for(; iterInc != incDirsVec.end(); ++iterInc )
-    {
-    //std::cout << (*ItStrVec) << std::endl;
-    incDirs += iterInc->Value + " ";
-    }
-
   ////////////////////////////////////
   fout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
        "<CodeLite_Project Name=\"" << mf->GetProjectName()
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index a81e53c..44bf586 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -598,7 +598,8 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(
                 linkName4 += "/";
                 linkName4 += cmSystemTools::GetFilenameName(fullPath);
                 this->AppendLinkedResource(fout, linkName4,
-                                           fullPath, LinkToFile);
+                                           this->GetEclipsePath(fullPath),
+                                           LinkToFile);
                 }
               }
             }
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 4698468..87faf84 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -66,7 +66,7 @@ static mode_t mode_setuid = S_ISUID;
 static mode_t mode_setgid = S_ISGID;
 #endif
 
-#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
+#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8)
 // libcurl doesn't support file:// urls for unicode filenames on Windows.
 // Convert string from UTF-8 to ACP if this is a file:// URL.
 static std::string fix_file_url_windows(const std::string& url)
@@ -270,7 +270,7 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
     this->SetError(error);
     return false;
     }
-  std::string message = cmJoin(cmRange(i, args.end()), std::string());
+  std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
   file << message;
   file.close();
   if(mode)
@@ -906,13 +906,13 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
     {
     switch(status)
       {
+      case cmPolicies::REQUIRED_IF_USED:
+      case cmPolicies::REQUIRED_ALWAYS:
       case cmPolicies::NEW:
         g.RecurseThroughSymlinksOff();
         break;
       case cmPolicies::OLD:
       case cmPolicies::WARN:
-      case cmPolicies::REQUIRED_IF_USED:
-      case cmPolicies::REQUIRED_ALWAYS:
         g.RecurseThroughSymlinksOn();
         break;
       }
@@ -1044,6 +1044,8 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
     {
     switch (status)
       {
+      case cmPolicies::REQUIRED_IF_USED:
+      case cmPolicies::REQUIRED_ALWAYS:
       case cmPolicies::NEW:
         // Correct behavior, yay!
         break;
@@ -1059,12 +1061,6 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
             cmPolicies::GetPolicyWarning(cmPolicies::CMP0009));
           }
         break;
-      case cmPolicies::REQUIRED_IF_USED:
-      case cmPolicies::REQUIRED_ALWAYS:
-        this->SetError("policy CMP0009 error");
-        this->Makefile->IssueMessage(cmake::FATAL_ERROR,
-          cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0009));
-        return false;
       }
     }
 
@@ -3160,7 +3156,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
     return false;
     }
 
-#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
+#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8)
   url = fix_file_url_windows(url);
 #endif
 
@@ -3415,7 +3411,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
 
   unsigned long file_size = cmsys::SystemTools::FileLength(filename);
 
-#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
+#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8)
   url = fix_file_url_windows(url);
 #endif
 
@@ -3569,19 +3565,16 @@ void cmFileCommand::AddEvaluationFile(const std::string &inputName,
 {
   cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
 
-  cmGeneratorExpression outputGe(&lfbt);
+  cmGeneratorExpression outputGe(lfbt);
   cmsys::auto_ptr<cmCompiledGeneratorExpression> outputCge
                                                 = outputGe.Parse(outputExpr);
 
-  cmGeneratorExpression conditionGe(&lfbt);
+  cmGeneratorExpression conditionGe(lfbt);
   cmsys::auto_ptr<cmCompiledGeneratorExpression> conditionCge
                                               = conditionGe.Parse(condition);
 
-  this->Makefile->GetGlobalGenerator()->AddEvaluationFile(inputName,
-                                                          outputCge,
-                                                          this->Makefile,
-                                                          conditionCge,
-                                                          inputIsContent);
+  this->Makefile->AddEvaluationFile(inputName, outputCge,
+                                    conditionCge, inputIsContent);
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index e2f86ce..fa9b381 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -170,8 +170,8 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
     else
       {
       this->VariableDocumentation += "one of the ";
-      this->VariableDocumentation += cmJoin(cmRange(this->Names).retreat(1),
-                                            ", ");
+      this->VariableDocumentation +=
+        cmJoin(cmMakeRange(this->Names).retreat(1), ", ");
       this->VariableDocumentation += " or "
         + this->Names[this->Names.size() - 1] + " libraries be found";
       }
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 0a66732..e7696af 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -11,7 +11,6 @@
 ============================================================================*/
 #include "cmFindLibraryCommand.h"
 #include <cmsys/Directory.hxx>
-#include <cmsys/stl/algorithm>
 
 cmFindLibraryCommand::cmFindLibraryCommand()
 {
@@ -204,6 +203,7 @@ struct cmFindLibraryHelper
     }
   bool HasValidSuffix(std::string const& name);
   void AddName(std::string const& name);
+  void SetName(std::string const& name);
   bool CheckDirectory(std::string const& path);
   bool CheckDirectoryForName(std::string const& path, Name& name);
 };
@@ -323,6 +323,13 @@ void cmFindLibraryHelper::AddName(std::string const& name)
 }
 
 //----------------------------------------------------------------------------
+void cmFindLibraryHelper::SetName(std::string const& name)
+{
+  this->Names.clear();
+  this->AddName(name);
+}
+
+//----------------------------------------------------------------------------
 bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
 {
   for(std::vector<Name>::iterator i = this->Names.begin();
@@ -460,8 +467,7 @@ std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
       ni != this->Names.end() ; ++ni)
     {
     // Switch to searching for this name.
-    std::string const& name = *ni;
-    helper.AddName(name);
+    helper.SetName(*ni);
 
     // Search every directory.
     for(std::vector<std::string>::const_iterator
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index bf4033e..64176e7 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -1381,7 +1381,7 @@ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir,
       cmFindPackageCommandHoldFile holdFile(fname.c_str());
 
       // Load the file.
-      cmsys::ifstream fin(fname.c_str(), std::ios::in | cmsys_ios_binary);
+      cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
       std::string fentry;
       if(fin && cmSystemTools::GetLineFromStream(fin, fentry) &&
          this->CheckPackageRegistryEntry(fentry, outPaths))
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index fbd9fd3..219ad48 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -16,6 +16,80 @@
 #include <CoreFoundation/CoreFoundation.h>
 #endif
 
+//----------------------------------------------------------------------------
+struct cmFindProgramHelper
+{
+  cmFindProgramHelper()
+    {
+#if defined (_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
+    // Consider platform-specific extensions.
+    this->Extensions.push_back(".com");
+    this->Extensions.push_back(".exe");
+#endif
+    // Consider original name with no extensions.
+    this->Extensions.push_back("");
+    }
+
+  // List of valid extensions.
+  std::vector<std::string> Extensions;
+
+  // Keep track of the best program file found so far.
+  std::string BestPath;
+
+  // Current names under consideration.
+  std::vector<std::string> Names;
+
+  // Current full path under consideration.
+  std::string TestPath;
+
+  void AddName(std::string const& name)
+    {
+    this->Names.push_back(name);
+    }
+  void SetName(std::string const& name)
+    {
+    this->Names.clear();
+    this->AddName(name);
+    }
+  bool CheckDirectory(std::string const& path)
+    {
+    for (std::vector<std::string>::iterator i = this->Names.begin();
+         i != this->Names.end(); ++i)
+      {
+      if (this->CheckDirectoryForName(path, *i))
+        {
+        return true;
+        }
+      }
+    return false;
+    }
+  bool CheckDirectoryForName(std::string const& path, std::string const& name)
+    {
+    for (std::vector<std::string>::iterator ext = this->Extensions.begin();
+         ext != this->Extensions.end(); ++ext)
+      {
+      this->TestPath = path;
+      this->TestPath += name;
+      if (!ext->empty() && cmSystemTools::StringEndsWith(name, ext->c_str()))
+        {
+        continue;
+        }
+      this->TestPath += *ext;
+      if (cmSystemTools::FileExists(this->TestPath, true))
+        {
+        this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
+        return true;
+        }
+      }
+    return false;
+    }
+};
+
+cmFindProgramCommand::cmFindProgramCommand()
+{
+  this->NamesPerDirAllowed = true;
+}
+
 // cmFindProgramCommand
 bool cmFindProgramCommand
 ::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
@@ -41,7 +115,7 @@ bool cmFindProgramCommand
     return true;
     }
 
-  std::string result = FindProgram(this->Names);
+  std::string result = FindProgram();
   if(result != "")
     {
     // Save the value in the cache
@@ -59,31 +133,105 @@ bool cmFindProgramCommand
   return true;
 }
 
-std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names)
+std::string cmFindProgramCommand::FindProgram()
 {
   std::string program = "";
 
   if(this->SearchAppBundleFirst || this->SearchAppBundleOnly)
     {
-    program = FindAppBundle(names);
+    program = FindAppBundle();
     }
   if(program.empty() && !this->SearchAppBundleOnly)
     {
-    program = cmSystemTools::FindProgram(names, this->SearchPaths, true);
+    program = this->FindNormalProgram();
     }
 
   if(program.empty() && this->SearchAppBundleLast)
     {
-    program = this->FindAppBundle(names);
+    program = this->FindAppBundle();
     }
   return program;
 }
 
-std::string cmFindProgramCommand
-::FindAppBundle(std::vector<std::string> names)
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgram()
+{
+  if(this->NamesPerDir)
+    {
+    return this->FindNormalProgramNamesPerDir();
+    }
+  else
+    {
+    return this->FindNormalProgramDirsPerName();
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
+{
+  // Search for all names in each directory.
+  cmFindProgramHelper helper;
+  for (std::vector<std::string>::const_iterator ni = this->Names.begin();
+       ni != this->Names.end() ; ++ni)
+    {
+    helper.AddName(*ni);
+    }
+
+  // Check for the names themselves (e.g. absolute paths).
+  if (helper.CheckDirectory(std::string()))
+    {
+    return helper.BestPath;
+    }
+
+  // Search every directory.
+  for (std::vector<std::string>::const_iterator
+         p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p)
+    {
+    if(helper.CheckDirectory(*p))
+      {
+      return helper.BestPath;
+      }
+    }
+  // Couldn't find the program.
+  return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
+{
+  // Search the entire path for each name.
+  cmFindProgramHelper helper;
+  for (std::vector<std::string>::const_iterator ni = this->Names.begin();
+       ni != this->Names.end() ; ++ni)
+    {
+    // Switch to searching for this name.
+    helper.SetName(*ni);
+
+    // Check for the name by itself (e.g. an absolute path).
+    if (helper.CheckDirectory(std::string()))
+      {
+      return helper.BestPath;
+      }
+
+    // Search every directory.
+    for (std::vector<std::string>::const_iterator
+           p = this->SearchPaths.begin();
+         p != this->SearchPaths.end(); ++p)
+      {
+      if (helper.CheckDirectory(*p))
+        {
+        return helper.BestPath;
+        }
+      }
+    }
+  // Couldn't find the program.
+  return "";
+}
+
+std::string cmFindProgramCommand::FindAppBundle()
 {
-  for(std::vector<std::string>::const_iterator name = names.begin();
-      name != names.end() ; ++name)
+  for(std::vector<std::string>::const_iterator name = this->Names.begin();
+      name != this->Names.end() ; ++name)
     {
 
     std::string appName = *name + std::string(".app");
diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h
index 70f758f..f88186b 100644
--- a/Source/cmFindProgramCommand.h
+++ b/Source/cmFindProgramCommand.h
@@ -25,6 +25,7 @@
 class cmFindProgramCommand : public cmFindBase
 {
 public:
+  cmFindProgramCommand();
   /**
    * This is a virtual constructor for the command.
    */
@@ -52,11 +53,12 @@ public:
 
   cmTypeMacro(cmFindProgramCommand, cmFindBase);
 
-protected:
-  std::string FindProgram(std::vector<std::string> names);
-
 private:
-  std::string FindAppBundle(std::vector<std::string> names);
+  std::string FindProgram();
+  std::string FindNormalProgram();
+  std::string FindNormalProgramDirsPerName();
+  std::string FindNormalProgramNamesPerDir();
+  std::string FindAppBundle();
   std::string GetBundleExecutable(std::string bundlePath);
 
 };
diff --git a/Source/cmFortranLexer.cxx b/Source/cmFortranLexer.cxx
new file mode 100644
index 0000000..b727f0e
--- /dev/null
+++ b/Source/cmFortranLexer.cxx
@@ -0,0 +1,2413 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#line 2 "cmFortranLexer.cxx"
+
+#line 4 "cmFortranLexer.cxx"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else   /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif  /* defined (__STDC__) */
+#endif  /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+   are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE cmFortran_yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+        do \
+                { \
+                /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+                *yy_cp = yyg->yy_hold_char; \
+                YY_RESTORE_YY_MORE_OFFSET \
+                yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+                YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+                } \
+        while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+        {
+        FILE *yy_input_file;
+
+        char *yy_ch_buf;                /* input buffer */
+        char *yy_buf_pos;               /* current position in input buffer */
+
+        /* Size of input buffer in bytes, not including room for EOB
+         * characters.
+         */
+        yy_size_t yy_buf_size;
+
+        /* Number of characters read into yy_ch_buf, not including EOB
+         * characters.
+         */
+        int yy_n_chars;
+
+        /* Whether we "own" the buffer - i.e., we know we created it,
+         * and can realloc() it to grow it, and should free() it to
+         * delete it.
+         */
+        int yy_is_our_buffer;
+
+        /* Whether this is an "interactive" input source; if so, and
+         * if we're using stdio for input, then we want to use getc()
+         * instead of fread(), to make sure we stop fetching input after
+         * each newline.
+         */
+        int yy_is_interactive;
+
+        /* Whether we're considered to be at the beginning of a line.
+         * If so, '^' rules will be active on the next match, otherwise
+         * not.
+         */
+        int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+
+        /* Whether to try to fill the input buffer when we reach the
+         * end of it.
+         */
+        int yy_fill_buffer;
+
+        int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+        /* When an EOF's been seen but there's still some text to process
+         * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+         * shouldn't try reading from the input source any more.  We might
+         * still have a bunch of tokens to match, though, because of
+         * possible backing-up.
+         *
+         * When we actually see the EOF, we change the status to "new"
+         * (via cmFortran_yyrestart()), so that the user can continue scanning by
+         * just pointing yyin at a new input file.
+         */
+#define YY_BUFFER_EOF_PENDING 2
+
+        };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+                          ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void cmFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmFortran_yypop_buffer_state (yyscan_t yyscanner );
+
+static void cmFortran_yyensure_buffer_stack (yyscan_t yyscanner );
+static void cmFortran_yy_load_buffer_state (yyscan_t yyscanner );
+static void cmFortran_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER cmFortran_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE cmFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *cmFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmFortran_yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer cmFortran_yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+        { \
+        if ( ! YY_CURRENT_BUFFER ){ \
+        cmFortran_yyensure_buffer_stack (yyscanner); \
+                YY_CURRENT_BUFFER_LVALUE =    \
+            cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+        } \
+        YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+        }
+
+#define yy_set_bol(at_bol) \
+        { \
+        if ( ! YY_CURRENT_BUFFER ){\
+        cmFortran_yyensure_buffer_stack (yyscanner); \
+                YY_CURRENT_BUFFER_LVALUE =    \
+            cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+        } \
+        YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+        }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define cmFortran_yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+        yyg->yytext_ptr = yy_bp; \
+        yyleng = (size_t) (yy_cp - yy_bp); \
+        yyg->yy_hold_char = *yy_cp; \
+        *yy_cp = '\0'; \
+        yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 44
+#define YY_END_OF_BUFFER 45
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+        {
+        flex_int32_t yy_verify;
+        flex_int32_t yy_nxt;
+        };
+static yyconst flex_int16_t yy_accept[165] =
+    {   0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+       45,   39,   41,   40,   43,    1,   39,   32,    2,   34,
+       39,   40,   37,   39,   38,   39,   38,   41,   39,   40,
+       39,   38,    9,    8,    9,    4,    3,   39,    0,   10,
+        0,    0,    0,    0,    0,   32,   32,   33,   35,   37,
+       39,   38,    0,   42,   38,    0,    0,    0,    0,    0,
+        0,    0,    0,   39,    0,   11,   38,    0,    0,    5,
+        0,    0,    0,   28,    0,    0,   32,   32,   32,   32,
+        0,    0,    0,    0,    0,   22,    0,    0,    0,    0,
+        0,    6,    0,    0,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,   29,   30,    0,    0,    0,    0,    0,    0,
+        0,   23,   24,    0,    0,    0,    0,    0,    0,    0,
+        0,   31,   26,    0,    0,   19,    0,    0,   25,   20,
+        0,    0,   18,    0,    0,   17,   27,    0,    0,   16,
+       21,    0,    7,   36,    7,   14,    0,   13,   15,    0,
+        0,    0,   12,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    5,    6,    7,    8,    9,    1,   10,   11,    1,
+        1,   12,    1,   13,    1,    1,    1,   14,   14,   14,
+       14,   14,   14,   14,   14,   14,   14,   15,   16,   17,
+       18,   19,   20,    1,   21,   21,   22,   23,   24,   25,
+       21,   21,   26,   21,   21,   27,   21,   28,   21,   21,
+       21,   21,   29,   21,   30,   21,   21,   21,   21,   21,
+        1,   31,    1,    1,   32,    1,   21,   21,   33,   34,
+
+       35,   36,   21,   21,   37,   21,   21,   38,   21,   39,
+       21,   21,   21,   21,   40,   21,   41,   21,   21,   21,
+       21,   21,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[42] =
+    {   0,
+        1,    2,    2,    3,    4,    3,    3,    1,    1,    3,
+        3,    1,    3,    5,    1,    3,    1,    3,    6,    1,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        1,    5,    7,    7,    7,    7,    7,    7,    7,    7,
+        7
+    } ;
+
+static yyconst flex_int16_t yy_base[174] =
+    {   0,
+        0,   40,    0,   41,  188,   48,   44,   54,   56,   65,
+      186,    0,  505,  505,  171,  505,   81,   74,  505,  505,
+      158,  505,  151,  137,    0,   85,  122,   87,  153,  145,
+      194,  226,  505,  143,   91,  505,  505,    0,  142,  505,
+      266,   34,   70,   74,   34,  122,  141,  505,    0,  505,
+      112,    0,   98,  505,    0,  154,  306,    0,   43,  133,
+      139,   46,  130,  347,  130,  505,    0,  121,  163,  179,
+      104,  156,  129,  176,  147,  178,  214,  267,  273,  292,
+      279,  179,  249,  280,  257,  265,  288,  289,  116,  107,
+      317,  505,  287,  289,  291,  302,  307,  310,  307,  311,
+
+      316,  326,  329,  333,  332,  336,  347,  345,  349,  101,
+       86,  346,  505,  505,  350,  351,  353,  350,  357,  362,
+      362,  505,  505,  367,  369,  371,  366,  372,   56,   47,
+      374,  505,  505,  374,  379,  505,  374,  387,  505,  505,
+      387,  391,  505,  117,    0,  505,  505,  392,  394,  505,
+      505,  394,  505,  505,  505,  505,  395,  419,  505,  429,
+        0,   25,  505,  505,  446,  453,  459,  462,  469,  476,
+      483,  490,  497
+    } ;
+
+static yyconst flex_int16_t yy_def[174] =
+    {   0,
+      164,    1,    1,    1,    1,    1,  165,  165,  165,  165,
+      164,  166,  164,  164,  167,  164,  166,  164,  164,  164,
+      166,  164,  164,  166,  168,  166,  168,  164,  166,  164,
+      169,  164,  164,  164,  164,  164,  164,  166,  167,  164,
+      164,  164,  164,  164,  164,  164,  170,  164,  166,  164,
+      166,  168,  164,  164,   27,  164,  164,   57,  164,  164,
+      164,  164,  164,  169,  169,  164,   32,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  170,  170,  170,  170,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  171,  172,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      173,  173,  164,    0,  164,  164,  164,  164,  164,  164,
+      164,  164,  164
+    } ;
+
+static yyconst flex_int16_t yy_nxt[547] =
+    {   0,
+       12,   13,   14,   13,   13,   15,   16,   12,   17,   18,
+       19,   12,   20,   12,   21,   22,   12,   23,   12,   24,
+       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
+       26,   27,   25,   25,   25,   25,   25,   25,   25,   25,
+       25,   28,   28,  163,   28,   28,   34,   29,   29,   28,
+       30,  145,   28,   35,   36,   29,   34,   71,   34,   31,
+      144,   76,   37,   35,   36,   35,   83,   34,   71,   32,
+       32,   37,   76,   88,   35,   46,   46,   83,   46,   47,
+       32,   32,   41,   48,   88,   41,   53,   54,   56,   53,
+      130,   56,   69,   70,   57,   69,   72,   73,   74,   53,
+
+       54,   75,   53,   42,   43,  129,   44,   72,   73,   74,
+       45,  111,   75,   81,   42,   43,   81,   44,  154,  154,
+      110,   45,   38,   46,   46,   90,   46,   47,   93,   38,
+       38,   48,   66,   38,   89,   55,   38,   82,   38,   93,
+       38,   38,   78,   46,   40,   78,   79,   68,   82,   63,
+       80,   96,   38,   55,   58,   56,   51,   58,   56,   84,
+       85,   57,   96,   86,   69,   70,   87,   69,   99,   50,
+       84,   85,   49,   40,   86,   59,   60,   87,   61,   99,
+       91,   94,   62,   91,   95,  164,   59,   60,   92,   61,
+       30,  164,   94,   62,   64,   95,   66,  164,   97,  164,
+
+      100,   64,   64,   98,  164,   64,  101,   64,   64,   97,
+       64,  100,   64,   64,   98,   78,   46,  101,   78,   79,
+      164,  164,  164,   80,   64,   64,   65,   65,   66,   65,
+       65,   65,   65,   65,   65,   65,   65,   65,   65,   67,
+       65,   65,   65,   65,   65,   65,   67,   67,   67,   67,
+       67,   67,   67,   67,   67,   67,   65,   67,   67,   67,
+       67,   67,   67,   67,   67,   67,   67,   41,   78,   46,
+       41,   78,   79,  102,   78,   46,   80,   78,   79,  105,
+       81,  164,   80,   81,  102,  164,  164,  106,   42,   43,
+      105,   44,  107,   78,   46,   45,   78,   79,  106,   42,
+
+       43,   80,   44,  107,   82,  103,   45,   58,  104,  108,
+       58,  109,  112,  113,  114,   82,  103,  164,   91,  104,
+      108,   91,  109,  112,  113,  114,   92,  115,   59,   60,
+      116,   61,  117,  118,  119,   62,  164,  120,  115,   59,
+       60,  116,   61,  117,  118,  119,   62,   64,  120,   66,
+      164,  121,  164,  122,   64,   64,  123,  124,   64,  125,
+       64,   64,  121,   64,  122,   64,   64,  123,  124,  126,
+      125,  127,  128,  131,  132,  133,  134,   64,   64,  135,
+      126,  136,  127,  128,  131,  132,  133,  134,  137,  138,
+      135,  139,  136,  140,  141,  142,  143,  146,  147,  137,
+
+      138,  148,  139,  149,  140,  141,  142,  143,  146,  147,
+      150,  151,  148,  152,  149,  156,  157,  158,  159,  164,
+      160,  150,  151,  160,  152,  164,  156,  157,  158,  159,
+      160,  164,  164,  160,  164,  161,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  161,   33,   33,   33,   33,
+       33,   33,   33,   38,  164,  164,  164,   38,   38,   39,
+       39,   39,   39,   39,   39,   39,   52,  164,   52,   65,
+       65,   65,   65,   65,   65,   65,   77,   77,   77,   77,
+       77,   77,   77,  153,  153,  153,  164,  153,  153,  153,
+      155,  164,  155,  164,  155,  155,  155,  162,  162,  162,
+
+      162,  162,  164,  162,   11,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164
+    } ;
+
+static yyconst flex_int16_t yy_chk[547] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,  162,    2,    4,    7,    2,    4,    6,
+        6,  130,    6,    7,    7,    6,    8,   42,    9,    6,
+      129,   45,    9,    8,    8,    9,   59,   10,   42,    6,
+        6,   10,   45,   62,   10,   18,   18,   59,   18,   18,
+        6,    6,   17,   18,   62,   17,   26,   26,   28,   26,
+      111,   28,   35,   35,   28,   35,   43,   43,   44,   53,
+
+       53,   44,   53,   17,   17,  110,   17,   43,   43,   44,
+       17,   90,   44,   51,   17,   17,   51,   17,  144,  144,
+       89,   17,   27,   46,   46,   68,   46,   46,   71,   27,
+       27,   46,   65,   27,   63,   27,   27,   51,   27,   71,
+       27,   27,   47,   47,   39,   47,   47,   34,   51,   30,
+       47,   73,   27,   27,   29,   56,   24,   29,   56,   60,
+       60,   56,   73,   61,   69,   69,   61,   69,   75,   23,
+       60,   60,   21,   15,   61,   29,   29,   61,   29,   75,
+       70,   72,   29,   70,   72,   11,   29,   29,   70,   29,
+        5,    0,   72,   29,   31,   72,   31,    0,   74,    0,
+
+       76,   31,   31,   74,    0,   31,   82,   31,   31,   74,
+       31,   76,   31,   31,   74,   77,   77,   82,   77,   77,
+        0,    0,    0,   77,   31,   31,   32,   32,   32,   32,
+       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
+       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
+       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
+       32,   32,   32,   32,   32,   32,   32,   41,   78,   78,
+       41,   78,   78,   83,   79,   79,   78,   79,   79,   85,
+       81,    0,   79,   81,   83,    0,    0,   86,   41,   41,
+       85,   41,   86,   80,   80,   41,   80,   80,   86,   41,
+
+       41,   80,   41,   86,   81,   84,   41,   57,   84,   87,
+       57,   88,   93,   94,   95,   81,   84,    0,   91,   84,
+       87,   91,   88,   93,   94,   95,   91,   96,   57,   57,
+       97,   57,   98,   99,  100,   57,    0,  101,   96,   57,
+       57,   97,   57,   98,   99,  100,   57,   64,  101,   64,
+        0,  102,    0,  103,   64,   64,  104,  105,   64,  106,
+       64,   64,  102,   64,  103,   64,   64,  104,  105,  107,
+      106,  108,  109,  112,  115,  116,  117,   64,   64,  118,
+      107,  119,  108,  109,  112,  115,  116,  117,  120,  121,
+      118,  124,  119,  125,  126,  127,  128,  131,  134,  120,
+
+      121,  135,  124,  137,  125,  126,  127,  128,  131,  134,
+      138,  141,  135,  142,  137,  148,  149,  152,  157,    0,
+      158,  138,  141,  158,  142,    0,  148,  149,  152,  157,
+      160,    0,    0,  160,    0,  158,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  160,  165,  165,  165,  165,
+      165,  165,  165,  166,    0,    0,    0,  166,  166,  167,
+      167,  167,  167,  167,  167,  167,  168,    0,  168,  169,
+      169,  169,  169,  169,  169,  169,  170,  170,  170,  170,
+      170,  170,  170,  171,  171,  171,    0,  171,  171,  171,
+      172,    0,  172,    0,  172,  172,  172,  173,  173,  173,
+
+      173,  173,    0,  173,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164
+    } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "cmFortranLexer.in.l"
+#line 2 "cmFortranLexer.in.l"
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+  Portions of this source have been derived from makedepf90 version 2.8.8,
+
+   Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann at iki.fi>
+
+  The code was originally distributed under the GPL but permission
+  from the copyright holder has been obtained to distribute this
+  derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+  flex -i --prefix=cmFortran_yy --header-file=cmFortranLexer.h -ocmFortranLexer.cxx cmFortranLexer.in.l
+
+Modify cmFortranLexer.cxx:
+  - remove TABs
+  - remove "yyscanner" argument from these methods:
+      yy_fatal_error, cmFortran_yyalloc, cmFortran_yyrealloc, cmFortran_yyfree
+  - remove "yyscanner = NULL" from end of cmFortran_yylex_destroy
+  - remove all YY_BREAK lines occurring right after return statements
+  - change while ( 1 ) to for(;;)
+
+Modify cmFortranLexer.h:
+  - remove TABs
+  - remove the yy_init_globals function
+  - remove the block that includes unistd.h
+  - remove #line directives (avoids bogus warning on old Sun)
+
+*/
+
+#include "cmStandardLexer.h"
+
+#define cmFortranLexer_cxx
+#include "cmFortranParser.h" /* Interface to parser object.  */
+
+/* Replace the lexer input function.  */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+  { result = cmFortranParser_Input(yyextra, buf, max_size); }
+
+/* Include the set of tokens from the parser.  */
+#include "cmFortranParserTokens.h"
+
+/*--------------------------------------------------------------------------*/
+
+
+#line 678 "cmFortranLexer.cxx"
+
+#define INITIAL 0
+#define free_fmt 1
+#define fixed_fmt 2
+#define str_sq 3
+#define str_dq 4
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+    {
+
+    /* User-defined. Not touched by flex. */
+    YY_EXTRA_TYPE yyextra_r;
+
+    /* The rest are the same as the globals declared in the non-reentrant scanner. */
+    FILE *yyin_r, *yyout_r;
+    size_t yy_buffer_stack_top; /**< index of top of stack. */
+    size_t yy_buffer_stack_max; /**< capacity of stack. */
+    YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+    char yy_hold_char;
+    int yy_n_chars;
+    int yyleng_r;
+    char *yy_c_buf_p;
+    int yy_init;
+    int yy_start;
+    int yy_did_buffer_switch_on_eof;
+    int yy_start_stack_ptr;
+    int yy_start_stack_depth;
+    int *yy_start_stack;
+    yy_state_type yy_last_accepting_state;
+    char* yy_last_accepting_cpos;
+
+    int yylineno_r;
+    int yy_flex_debug_r;
+
+    char *yytext_r;
+    int yy_more_flag;
+    int yy_more_len;
+
+    }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+int cmFortran_yylex_init (yyscan_t* scanner);
+
+int cmFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int cmFortran_yylex_destroy (yyscan_t yyscanner );
+
+int cmFortran_yyget_debug (yyscan_t yyscanner );
+
+void cmFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmFortran_yyget_extra (yyscan_t yyscanner );
+
+void cmFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmFortran_yyget_in (yyscan_t yyscanner );
+
+void cmFortran_yyset_in  (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmFortran_yyget_out (yyscan_t yyscanner );
+
+void cmFortran_yyset_out  (FILE * out_str ,yyscan_t yyscanner );
+
+int cmFortran_yyget_leng (yyscan_t yyscanner );
+
+char *cmFortran_yyget_text (yyscan_t yyscanner );
+
+int cmFortran_yyget_lineno (yyscan_t yyscanner );
+
+void cmFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int cmFortran_yywrap (yyscan_t yyscanner );
+#else
+extern int cmFortran_yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  ,yyscan_t yyscanner);
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+        if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+                { \
+                int c = '*'; \
+                size_t n; \
+                for ( n = 0; n < max_size && \
+                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+                        buf[n] = (char) c; \
+                if ( c == '\n' ) \
+                        buf[n++] = (char) c; \
+                if ( c == EOF && ferror( yyin ) ) \
+                        YY_FATAL_ERROR( "input in flex scanner failed" ); \
+                result = n; \
+                } \
+        else \
+                { \
+                errno=0; \
+                while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+                        { \
+                        if( errno != EINTR) \
+                                { \
+                                YY_FATAL_ERROR( "input in flex scanner failed" ); \
+                                break; \
+                                } \
+                        errno=0; \
+                        clearerr(yyin); \
+                        } \
+                }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int cmFortran_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmFortran_yylex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+        if ( yyleng > 0 ) \
+                YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+                                (yytext[yyleng - 1] == '\n'); \
+        YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+        yy_state_type yy_current_state;
+        char *yy_cp, *yy_bp;
+        int yy_act;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 71 "cmFortranLexer.in.l"
+
+
+#line 914 "cmFortranLexer.cxx"
+
+        if ( !yyg->yy_init )
+                {
+                yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+                YY_USER_INIT;
+#endif
+
+                if ( ! yyg->yy_start )
+                        yyg->yy_start = 1;      /* first start state */
+
+                if ( ! yyin )
+                        yyin = stdin;
+
+                if ( ! yyout )
+                        yyout = stdout;
+
+                if ( ! YY_CURRENT_BUFFER ) {
+                        cmFortran_yyensure_buffer_stack (yyscanner);
+                        YY_CURRENT_BUFFER_LVALUE =
+                                cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+                }
+
+                cmFortran_yy_load_buffer_state(yyscanner );
+                }
+
+        for(;;)             /* loops until end-of-file is reached */
+                {
+                yy_cp = yyg->yy_c_buf_p;
+
+                /* Support of yytext. */
+                *yy_cp = yyg->yy_hold_char;
+
+                /* yy_bp points to the position in yy_ch_buf of the start of
+                 * the current run.
+                 */
+                yy_bp = yy_cp;
+
+                yy_current_state = yyg->yy_start;
+                yy_current_state += YY_AT_BOL();
+yy_match:
+                do
+                        {
+                        YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+                        if ( yy_accept[yy_current_state] )
+                                {
+                                yyg->yy_last_accepting_state = yy_current_state;
+                                yyg->yy_last_accepting_cpos = yy_cp;
+                                }
+                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                                {
+                                yy_current_state = (int) yy_def[yy_current_state];
+                                if ( yy_current_state >= 165 )
+                                        yy_c = yy_meta[(unsigned int) yy_c];
+                                }
+                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+                        ++yy_cp;
+                        }
+                while ( yy_base[yy_current_state] != 505 );
+
+yy_find_action:
+                yy_act = yy_accept[yy_current_state];
+                if ( yy_act == 0 )
+                        { /* have to back up */
+                        yy_cp = yyg->yy_last_accepting_cpos;
+                        yy_current_state = yyg->yy_last_accepting_state;
+                        yy_act = yy_accept[yy_current_state];
+                        }
+
+                YY_DO_BEFORE_ACTION;
+
+do_action:      /* This label is used only to access EOF actions. */
+
+                switch ( yy_act )
+        { /* beginning of action switch */
+                        case 0: /* must back up */
+                        /* undo the effects of YY_DO_BEFORE_ACTION */
+                        *yy_cp = yyg->yy_hold_char;
+                        yy_cp = yyg->yy_last_accepting_cpos;
+                        yy_current_state = yyg->yy_last_accepting_state;
+                        goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 73 "cmFortranLexer.in.l"
+{
+  cmFortranParser_StringStart(yyextra);
+  cmFortranParser_SetOldStartcond(yyextra, YY_START);
+  BEGIN(str_dq);
+}
+        YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 79 "cmFortranLexer.in.l"
+{
+  cmFortranParser_StringStart(yyextra);
+  cmFortranParser_SetOldStartcond(yyextra, YY_START);
+  BEGIN(str_sq);
+}
+        YY_BREAK
+case 3:
+#line 86 "cmFortranLexer.in.l"
+case 4:
+YY_RULE_SETUP
+#line 86 "cmFortranLexer.in.l"
+{
+  BEGIN(cmFortranParser_GetOldStartcond(yyextra) );
+  yylvalp->string = strdup(cmFortranParser_StringEnd(yyextra));
+  return STRING;
+}
+case 5:
+/* rule 5 can match eol */
+#line 93 "cmFortranLexer.in.l"
+case 6:
+/* rule 6 can match eol */
+YY_RULE_SETUP
+#line 93 "cmFortranLexer.in.l"
+/* Ignore (continued strings, free fmt) */
+        YY_BREAK
+case 7:
+/* rule 7 can match eol */
+YY_RULE_SETUP
+#line 95 "cmFortranLexer.in.l"
+{
+  if (cmFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
+    ; /* Ignore (cont. strings, fixed fmt) */
+  else
+    {
+    unput(yytext[strlen(yytext)-1]);
+    }
+}
+        YY_BREAK
+case 8:
+/* rule 8 can match eol */
+YY_RULE_SETUP
+#line 105 "cmFortranLexer.in.l"
+{
+  unput ('\n');
+  BEGIN(INITIAL);
+  return UNTERMINATED_STRING;
+}
+case 9:
+YY_RULE_SETUP
+#line 111 "cmFortranLexer.in.l"
+{
+  cmFortranParser_StringAppend(yyextra, yytext[0]);
+}
+        YY_BREAK
+case 10:
+/* rule 10 can match eol */
+YY_RULE_SETUP
+#line 115 "cmFortranLexer.in.l"
+{ return EOSTMT; } /* Treat comments like */
+case 11:
+/* rule 11 can match eol */
+YY_RULE_SETUP
+#line 116 "cmFortranLexer.in.l"
+{ return EOSTMT; } /* empty lines */
+case 12:
+/* rule 12 can match eol */
+YY_RULE_SETUP
+#line 118 "cmFortranLexer.in.l"
+{
+  yytext[yyleng-1] = 0;
+  yylvalp->string = strdup(strchr(yytext, '<')+1);
+  return CPP_INCLUDE_ANGLE;
+}
+case 13:
+YY_RULE_SETUP
+#line 123 "cmFortranLexer.in.l"
+{ return CPP_INCLUDE; }
+case 14:
+YY_RULE_SETUP
+#line 124 "cmFortranLexer.in.l"
+{ return F90PPR_INCLUDE; }
+case 15:
+YY_RULE_SETUP
+#line 125 "cmFortranLexer.in.l"
+{ return COCO_INCLUDE; }
+case 16:
+YY_RULE_SETUP
+#line 127 "cmFortranLexer.in.l"
+{ return CPP_DEFINE; }
+case 17:
+YY_RULE_SETUP
+#line 128 "cmFortranLexer.in.l"
+{ return F90PPR_DEFINE; }
+case 18:
+YY_RULE_SETUP
+#line 130 "cmFortranLexer.in.l"
+{ return CPP_UNDEF; }
+case 19:
+YY_RULE_SETUP
+#line 131 "cmFortranLexer.in.l"
+{ return F90PPR_UNDEF; }
+case 20:
+YY_RULE_SETUP
+#line 133 "cmFortranLexer.in.l"
+{ return CPP_IFDEF; }
+case 21:
+YY_RULE_SETUP
+#line 134 "cmFortranLexer.in.l"
+{ return CPP_IFNDEF; }
+case 22:
+YY_RULE_SETUP
+#line 135 "cmFortranLexer.in.l"
+{ return CPP_IF; }
+case 23:
+YY_RULE_SETUP
+#line 136 "cmFortranLexer.in.l"
+{ return CPP_ELIF; }
+case 24:
+YY_RULE_SETUP
+#line 137 "cmFortranLexer.in.l"
+{ return CPP_ELSE; }
+case 25:
+YY_RULE_SETUP
+#line 138 "cmFortranLexer.in.l"
+{ return CPP_ENDIF; }
+case 26:
+YY_RULE_SETUP
+#line 140 "cmFortranLexer.in.l"
+{ return F90PPR_IFDEF; }
+case 27:
+YY_RULE_SETUP
+#line 141 "cmFortranLexer.in.l"
+{ return F90PPR_IFNDEF; }
+case 28:
+YY_RULE_SETUP
+#line 142 "cmFortranLexer.in.l"
+{ return F90PPR_IF; }
+case 29:
+YY_RULE_SETUP
+#line 143 "cmFortranLexer.in.l"
+{ return F90PPR_ELIF; }
+case 30:
+YY_RULE_SETUP
+#line 144 "cmFortranLexer.in.l"
+{ return F90PPR_ELSE; }
+case 31:
+YY_RULE_SETUP
+#line 145 "cmFortranLexer.in.l"
+{ return F90PPR_ENDIF; }
+/* Line continuations, possible involving comments.  */
+case 32:
+/* rule 32 can match eol */
+YY_RULE_SETUP
+#line 148 "cmFortranLexer.in.l"
+
+        YY_BREAK
+case 33:
+/* rule 33 can match eol */
+YY_RULE_SETUP
+#line 149 "cmFortranLexer.in.l"
+
+        YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 151 "cmFortranLexer.in.l"
+{ return COMMA; }
+case 35:
+YY_RULE_SETUP
+#line 153 "cmFortranLexer.in.l"
+{ return DCOLON; }
+case 36:
+/* rule 36 can match eol */
+YY_RULE_SETUP
+#line 155 "cmFortranLexer.in.l"
+{ return GARBAGE; }
+case 37:
+YY_RULE_SETUP
+#line 157 "cmFortranLexer.in.l"
+{ return ASSIGNMENT_OP; }
+case 38:
+YY_RULE_SETUP
+#line 159 "cmFortranLexer.in.l"
+{
+  yylvalp->string = strdup(yytext);
+  return WORD;
+}
+case 39:
+YY_RULE_SETUP
+#line 164 "cmFortranLexer.in.l"
+{ return GARBAGE; }
+case 40:
+/* rule 40 can match eol */
+YY_RULE_SETUP
+#line 166 "cmFortranLexer.in.l"
+{ return EOSTMT; }
+case 41:
+YY_RULE_SETUP
+#line 169 "cmFortranLexer.in.l"
+/* Ignore */
+        YY_BREAK
+case 42:
+/* rule 42 can match eol */
+YY_RULE_SETUP
+#line 170 "cmFortranLexer.in.l"
+/* Ignore line-endings preceeded by \ */
+        YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 172 "cmFortranLexer.in.l"
+{ return *yytext; }
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(free_fmt):
+case YY_STATE_EOF(fixed_fmt):
+case YY_STATE_EOF(str_sq):
+case YY_STATE_EOF(str_dq):
+#line 174 "cmFortranLexer.in.l"
+{
+  if(!cmFortranParser_FilePop(yyextra) )
+    {
+    return YY_NULL;
+    }
+}
+        YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 181 "cmFortranLexer.in.l"
+ECHO;
+        YY_BREAK
+#line 1270 "cmFortranLexer.cxx"
+
+        case YY_END_OF_BUFFER:
+                {
+                /* Amount of text matched not including the EOB char. */
+                int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+                /* Undo the effects of YY_DO_BEFORE_ACTION. */
+                *yy_cp = yyg->yy_hold_char;
+                YY_RESTORE_YY_MORE_OFFSET
+
+                if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+                        {
+                        /* We're scanning a new file or input source.  It's
+                         * possible that this happened because the user
+                         * just pointed yyin at a new source and called
+                         * cmFortran_yylex().  If so, then we have to assure
+                         * consistency between YY_CURRENT_BUFFER and our
+                         * globals.  Here is the right place to do so, because
+                         * this is the first action (other than possibly a
+                         * back-up) that will match for the new input source.
+                         */
+                        yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+                        YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+                        YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+                        }
+
+                /* Note that here we test for yy_c_buf_p "<=" to the position
+                 * of the first EOB in the buffer, since yy_c_buf_p will
+                 * already have been incremented past the NUL character
+                 * (since all states make transitions on EOB to the
+                 * end-of-buffer state).  Contrast this with the test
+                 * in input().
+                 */
+                if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+                        { /* This was really a NUL. */
+                        yy_state_type yy_next_state;
+
+                        yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+                        yy_current_state = yy_get_previous_state( yyscanner );
+
+                        /* Okay, we're now positioned to make the NUL
+                         * transition.  We couldn't have
+                         * yy_get_previous_state() go ahead and do it
+                         * for us because it doesn't know how to deal
+                         * with the possibility of jamming (and we don't
+                         * want to build jamming into it because then it
+                         * will run more slowly).
+                         */
+
+                        yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+                        yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+                        if ( yy_next_state )
+                                {
+                                /* Consume the NUL. */
+                                yy_cp = ++yyg->yy_c_buf_p;
+                                yy_current_state = yy_next_state;
+                                goto yy_match;
+                                }
+
+                        else
+                                {
+                                yy_cp = yyg->yy_c_buf_p;
+                                goto yy_find_action;
+                                }
+                        }
+
+                else switch ( yy_get_next_buffer( yyscanner ) )
+                        {
+                        case EOB_ACT_END_OF_FILE:
+                                {
+                                yyg->yy_did_buffer_switch_on_eof = 0;
+
+                                if ( cmFortran_yywrap(yyscanner ) )
+                                        {
+                                        /* Note: because we've taken care in
+                                         * yy_get_next_buffer() to have set up
+                                         * yytext, we can now set up
+                                         * yy_c_buf_p so that if some total
+                                         * hoser (like flex itself) wants to
+                                         * call the scanner after we return the
+                                         * YY_NULL, it'll still work - another
+                                         * YY_NULL will get returned.
+                                         */
+                                        yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+                                        yy_act = YY_STATE_EOF(YY_START);
+                                        goto do_action;
+                                        }
+
+                                else
+                                        {
+                                        if ( ! yyg->yy_did_buffer_switch_on_eof )
+                                                YY_NEW_FILE;
+                                        }
+                                break;
+                                }
+
+                        case EOB_ACT_CONTINUE_SCAN:
+                                yyg->yy_c_buf_p =
+                                        yyg->yytext_ptr + yy_amount_of_matched_text;
+
+                                yy_current_state = yy_get_previous_state( yyscanner );
+
+                                yy_cp = yyg->yy_c_buf_p;
+                                yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+                                goto yy_match;
+
+                        case EOB_ACT_LAST_MATCH:
+                                yyg->yy_c_buf_p =
+                                &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+                                yy_current_state = yy_get_previous_state( yyscanner );
+
+                                yy_cp = yyg->yy_c_buf_p;
+                                yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+                                goto yy_find_action;
+                        }
+                break;
+                }
+
+        default:
+                YY_FATAL_ERROR(
+                        "fatal flex scanner internal error--no action found" );
+        } /* end of action switch */
+                } /* end of scanning one token */
+} /* end of cmFortran_yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *      EOB_ACT_LAST_MATCH -
+ *      EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *      EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+        char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+        char *source = yyg->yytext_ptr;
+        int number_to_move, i;
+        int ret_val;
+
+        if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+                YY_FATAL_ERROR(
+                "fatal flex scanner internal error--end of buffer missed" );
+
+        if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+                { /* Don't try to fill the buffer, so this is an EOF. */
+                if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+                        {
+                        /* We matched a single character, the EOB, so
+                         * treat this as a final EOF.
+                         */
+                        return EOB_ACT_END_OF_FILE;
+                        }
+
+                else
+                        {
+                        /* We matched some text prior to the EOB, first
+                         * process it.
+                         */
+                        return EOB_ACT_LAST_MATCH;
+                        }
+                }
+
+        /* Try to read more data. */
+
+        /* First move last chars to start of buffer. */
+        number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+        for ( i = 0; i < number_to_move; ++i )
+                *(dest++) = *(source++);
+
+        if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+                /* don't do the read, it's not guaranteed to return an EOF,
+                 * just force an EOF
+                 */
+                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+        else
+                {
+                        int num_to_read =
+                        YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+                while ( num_to_read <= 0 )
+                        { /* Not enough room in the buffer - grow it. */
+
+                        /* just a shorter name for the current buffer */
+                        YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+                        int yy_c_buf_p_offset =
+                                (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+                        if ( b->yy_is_our_buffer )
+                                {
+                                int new_size = b->yy_buf_size * 2;
+
+                                if ( new_size <= 0 )
+                                        b->yy_buf_size += b->yy_buf_size / 8;
+                                else
+                                        b->yy_buf_size *= 2;
+
+                                b->yy_ch_buf = (char *)
+                                        /* Include room in for 2 EOB chars. */
+                                        cmFortran_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+                                }
+                        else
+                                /* Can't grow it, we don't own it. */
+                                b->yy_ch_buf = 0;
+
+                        if ( ! b->yy_ch_buf )
+                                YY_FATAL_ERROR(
+                                "fatal error - scanner input buffer overflow" );
+
+                        yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+                        num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                                                number_to_move - 1;
+
+                        }
+
+                if ( num_to_read > YY_READ_BUF_SIZE )
+                        num_to_read = YY_READ_BUF_SIZE;
+
+                /* Read in more data. */
+                YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+                        yyg->yy_n_chars, (size_t) num_to_read );
+
+                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+                }
+
+        if ( yyg->yy_n_chars == 0 )
+                {
+                if ( number_to_move == YY_MORE_ADJ )
+                        {
+                        ret_val = EOB_ACT_END_OF_FILE;
+                        cmFortran_yyrestart(yyin  ,yyscanner);
+                        }
+
+                else
+                        {
+                        ret_val = EOB_ACT_LAST_MATCH;
+                        YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                                YY_BUFFER_EOF_PENDING;
+                        }
+                }
+
+        else
+                ret_val = EOB_ACT_CONTINUE_SCAN;
+
+        if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+                /* Extend the array by 50%, plus the number we really need. */
+                yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+                YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cmFortran_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+                if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                        YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+        }
+
+        yyg->yy_n_chars += number_to_move;
+        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+        YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+        yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+        return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+        yy_state_type yy_current_state;
+        char *yy_cp;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        yy_current_state = yyg->yy_start;
+        yy_current_state += YY_AT_BOL();
+
+        for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+                {
+                YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+                if ( yy_accept[yy_current_state] )
+                        {
+                        yyg->yy_last_accepting_state = yy_current_state;
+                        yyg->yy_last_accepting_cpos = yy_cp;
+                        }
+                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                        {
+                        yy_current_state = (int) yy_def[yy_current_state];
+                        if ( yy_current_state >= 165 )
+                                yy_c = yy_meta[(unsigned int) yy_c];
+                        }
+                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+                }
+
+        return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *      next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+        int yy_is_jam;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+        char *yy_cp = yyg->yy_c_buf_p;
+
+        YY_CHAR yy_c = 1;
+        if ( yy_accept[yy_current_state] )
+                {
+                yyg->yy_last_accepting_state = yy_current_state;
+                yyg->yy_last_accepting_cpos = yy_cp;
+                }
+        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                {
+                yy_current_state = (int) yy_def[yy_current_state];
+                if ( yy_current_state >= 165 )
+                        yy_c = yy_meta[(unsigned int) yy_c];
+                }
+        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+        yy_is_jam = (yy_current_state == 164);
+
+        return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, char * yy_bp , yyscan_t yyscanner)
+{
+        char *yy_cp;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    yy_cp = yyg->yy_c_buf_p;
+
+        /* undo effects of setting up yytext */
+        *yy_cp = yyg->yy_hold_char;
+
+        if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+                { /* need to shift things up to make room */
+                /* +2 for EOB chars. */
+                int number_to_move = yyg->yy_n_chars + 2;
+                char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+                                        YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+                char *source =
+                                &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+                while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                        *--dest = *--source;
+
+                yy_cp += (int) (dest - source);
+                yy_bp += (int) (dest - source);
+                YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+                        yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+                if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+                        YY_FATAL_ERROR( "flex scanner push-back overflow" );
+                }
+
+        *--yy_cp = (char) c;
+
+        yyg->yytext_ptr = yy_bp;
+        yyg->yy_hold_char = *yy_cp;
+        yyg->yy_c_buf_p = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (yyscan_t yyscanner)
+#else
+    static int input  (yyscan_t yyscanner)
+#endif
+
+{
+        int c;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+        if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+                {
+                /* yy_c_buf_p now points to the character we want to return.
+                 * If this occurs *before* the EOB characters, then it's a
+                 * valid NUL; if not, then we've hit the end of the buffer.
+                 */
+                if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+                        /* This was really a NUL. */
+                        *yyg->yy_c_buf_p = '\0';
+
+                else
+                        { /* need more input */
+                        int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+                        ++yyg->yy_c_buf_p;
+
+                        switch ( yy_get_next_buffer( yyscanner ) )
+                                {
+                                case EOB_ACT_LAST_MATCH:
+                                        /* This happens because yy_g_n_b()
+                                         * sees that we've accumulated a
+                                         * token and flags that we need to
+                                         * try matching the token before
+                                         * proceeding.  But for input(),
+                                         * there's no matching to consider.
+                                         * So convert the EOB_ACT_LAST_MATCH
+                                         * to EOB_ACT_END_OF_FILE.
+                                         */
+
+                                        /* Reset buffer status. */
+                                        cmFortran_yyrestart(yyin ,yyscanner);
+
+                                        /*FALLTHROUGH*/
+
+                                case EOB_ACT_END_OF_FILE:
+                                        {
+                                        if ( cmFortran_yywrap(yyscanner ) )
+                                                return EOF;
+
+                                        if ( ! yyg->yy_did_buffer_switch_on_eof )
+                                                YY_NEW_FILE;
+#ifdef __cplusplus
+                                        return yyinput(yyscanner);
+#else
+                                        return input(yyscanner);
+#endif
+                                        }
+
+                                case EOB_ACT_CONTINUE_SCAN:
+                                        yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+                                        break;
+                                }
+                        }
+                }
+
+        c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+        *yyg->yy_c_buf_p = '\0';        /* preserve yytext */
+        yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+        YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+        return c;
+}
+#endif  /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void cmFortran_yyrestart  (FILE * input_file , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        if ( ! YY_CURRENT_BUFFER ){
+        cmFortran_yyensure_buffer_stack (yyscanner);
+                YY_CURRENT_BUFFER_LVALUE =
+            cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+        }
+
+        cmFortran_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+        cmFortran_yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+    void cmFortran_yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* TODO. We should be able to replace this entire function body
+         * with
+         *              cmFortran_yypop_buffer_state();
+         *              cmFortran_yypush_buffer_state(new_buffer);
+     */
+        cmFortran_yyensure_buffer_stack (yyscanner);
+        if ( YY_CURRENT_BUFFER == new_buffer )
+                return;
+
+        if ( YY_CURRENT_BUFFER )
+                {
+                /* Flush out information for old buffer. */
+                *yyg->yy_c_buf_p = yyg->yy_hold_char;
+                YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+                }
+
+        YY_CURRENT_BUFFER_LVALUE = new_buffer;
+        cmFortran_yy_load_buffer_state(yyscanner );
+
+        /* We don't actually know whether we did this switch during
+         * EOF (cmFortran_yywrap()) processing, but the only time this flag
+         * is looked at is after cmFortran_yywrap() is called, so it's safe
+         * to go ahead and always set it.
+         */
+        yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void cmFortran_yy_load_buffer_state  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+        yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+        yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+        yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+        yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE cmFortran_yy_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
+{
+        YY_BUFFER_STATE b;
+
+        b = (YY_BUFFER_STATE) cmFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+        if ( ! b )
+                YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_create_buffer()" );
+
+        b->yy_buf_size = size;
+
+        /* yy_ch_buf has to be 2 characters longer than the size given because
+         * we need to put in 2 end-of-buffer characters.
+         */
+        b->yy_ch_buf = (char *) cmFortran_yyalloc(b->yy_buf_size + 2 ,yyscanner );
+        if ( ! b->yy_ch_buf )
+                YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_create_buffer()" );
+
+        b->yy_is_our_buffer = 1;
+
+        cmFortran_yy_init_buffer(b,file ,yyscanner);
+
+        return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with cmFortran_yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+    void cmFortran_yy_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        if ( ! b )
+                return;
+
+        if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+                YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+        if ( b->yy_is_our_buffer )
+                cmFortran_yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+        cmFortran_yyfree((void *) b ,yyscanner );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a cmFortran_yyrestart() or at EOF.
+ */
+    static void cmFortran_yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)
+
+{
+        int oerrno = errno;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        cmFortran_yy_flush_buffer(b ,yyscanner);
+
+        b->yy_input_file = file;
+        b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then cmFortran_yy_init_buffer was _probably_
+     * called from cmFortran_yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+        errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+    void cmFortran_yy_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+        if ( ! b )
+                return;
+
+        b->yy_n_chars = 0;
+
+        /* We always need two end-of-buffer characters.  The first causes
+         * a transition to the end-of-buffer state.  The second causes
+         * a jam in that state.
+         */
+        b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+        b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+        b->yy_buf_pos = &b->yy_ch_buf[0];
+
+        b->yy_at_bol = 1;
+        b->yy_buffer_status = YY_BUFFER_NEW;
+
+        if ( b == YY_CURRENT_BUFFER )
+                cmFortran_yy_load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  @param yyscanner The scanner object.
+ */
+void cmFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+        if (new_buffer == NULL)
+                return;
+
+        cmFortran_yyensure_buffer_stack(yyscanner);
+
+        /* This block is copied from cmFortran_yy_switch_to_buffer. */
+        if ( YY_CURRENT_BUFFER )
+                {
+                /* Flush out information for old buffer. */
+                *yyg->yy_c_buf_p = yyg->yy_hold_char;
+                YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+                }
+
+        /* Only push if top exists. Otherwise, replace top. */
+        if (YY_CURRENT_BUFFER)
+                yyg->yy_buffer_stack_top++;
+        YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+        /* copied from cmFortran_yy_switch_to_buffer. */
+        cmFortran_yy_load_buffer_state(yyscanner );
+        yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  @param yyscanner The scanner object.
+ */
+void cmFortran_yypop_buffer_state (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+        if (!YY_CURRENT_BUFFER)
+                return;
+
+        cmFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+        YY_CURRENT_BUFFER_LVALUE = NULL;
+        if (yyg->yy_buffer_stack_top > 0)
+                --yyg->yy_buffer_stack_top;
+
+        if (YY_CURRENT_BUFFER) {
+                cmFortran_yy_load_buffer_state(yyscanner );
+                yyg->yy_did_buffer_switch_on_eof = 1;
+        }
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void cmFortran_yyensure_buffer_stack (yyscan_t yyscanner)
+{
+        int num_to_alloc;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        if (!yyg->yy_buffer_stack) {
+
+                /* First allocation is just for 2 elements, since we don't know if this
+                 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+                 * immediate realloc on the next call.
+         */
+                num_to_alloc = 1;
+                yyg->yy_buffer_stack = (struct yy_buffer_state**)cmFortran_yyalloc
+                                                                (num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                                , yyscanner);
+                if ( ! yyg->yy_buffer_stack )
+                        YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yyensure_buffer_stack()" );
+
+                memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+                yyg->yy_buffer_stack_max = num_to_alloc;
+                yyg->yy_buffer_stack_top = 0;
+                return;
+        }
+
+        if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+                /* Increase the buffer to prepare for a possible push. */
+                int grow_size = 8 /* arbitrary grow size */;
+
+                num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+                yyg->yy_buffer_stack = (struct yy_buffer_state**)cmFortran_yyrealloc
+                                                                (yyg->yy_buffer_stack,
+                                                                num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                                , yyscanner);
+                if ( ! yyg->yy_buffer_stack )
+                        YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yyensure_buffer_stack()" );
+
+                /* zero only the new slots.*/
+                memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+                yyg->yy_buffer_stack_max = num_to_alloc;
+        }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE cmFortran_yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
+{
+        YY_BUFFER_STATE b;
+
+        if ( size < 2 ||
+             base[size-2] != YY_END_OF_BUFFER_CHAR ||
+             base[size-1] != YY_END_OF_BUFFER_CHAR )
+                /* They forgot to leave room for the EOB's. */
+                return 0;
+
+        b = (YY_BUFFER_STATE) cmFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+        if ( ! b )
+                YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_scan_buffer()" );
+
+        b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
+        b->yy_buf_pos = b->yy_ch_buf = base;
+        b->yy_is_our_buffer = 0;
+        b->yy_input_file = 0;
+        b->yy_n_chars = b->yy_buf_size;
+        b->yy_is_interactive = 0;
+        b->yy_at_bol = 1;
+        b->yy_fill_buffer = 0;
+        b->yy_buffer_status = YY_BUFFER_NEW;
+
+        cmFortran_yy_switch_to_buffer(b ,yyscanner );
+
+        return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to cmFortran_yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       cmFortran_yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE cmFortran_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+        return cmFortran_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to cmFortran_yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE cmFortran_yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
+{
+        YY_BUFFER_STATE b;
+        char *buf;
+        yy_size_t n;
+        int i;
+
+        /* Get memory for full buffer, including space for trailing EOB's. */
+        n = _yybytes_len + 2;
+        buf = (char *) cmFortran_yyalloc(n ,yyscanner );
+        if ( ! buf )
+                YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_scan_bytes()" );
+
+        for ( i = 0; i < _yybytes_len; ++i )
+                buf[i] = yybytes[i];
+
+        buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+        b = cmFortran_yy_scan_buffer(buf,n ,yyscanner);
+        if ( ! b )
+                YY_FATAL_ERROR( "bad buffer in cmFortran_yy_scan_bytes()" );
+
+        /* It's okay to grow etc. this buffer, and we should throw it
+         * away when we're done.
+         */
+        b->yy_is_our_buffer = 1;
+
+        return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t)
+{
+        (void) fprintf( stderr, "%s\n", msg );
+        exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+        do \
+                { \
+                /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+                yytext[yyleng] = yyg->yy_hold_char; \
+                yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+                yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+                *yyg->yy_c_buf_p = '\0'; \
+                yyleng = yyless_macro_arg; \
+                } \
+        while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE cmFortran_yyget_extra  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int cmFortran_yyget_lineno  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+
+    return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int cmFortran_yyget_column  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+
+    return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *cmFortran_yyget_in  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *cmFortran_yyget_out  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int cmFortran_yyget_leng  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *cmFortran_yyget_text  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void cmFortran_yyset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number The line number to set.
+ * @param yyscanner The scanner object.
+ */
+void cmFortran_yyset_lineno (int  line_number , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* lineno is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           yy_fatal_error( "cmFortran_yyset_lineno called with no buffer" , yyscanner);
+
+    yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param column_no The column number to set.
+ * @param yyscanner The scanner object.
+ */
+void cmFortran_yyset_column (int  column_no , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* column is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           yy_fatal_error( "cmFortran_yyset_column called with no buffer" , yyscanner);
+
+    yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see cmFortran_yy_switch_to_buffer
+ */
+void cmFortran_yyset_in (FILE *  in_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyin = in_str ;
+}
+
+void cmFortran_yyset_out (FILE *  out_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyout = out_str ;
+}
+
+int cmFortran_yyget_debug  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yy_flex_debug;
+}
+
+void cmFortran_yyset_debug (int  bdebug , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+/* User-visible API */
+
+/* cmFortran_yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int cmFortran_yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+
+    *ptr_yy_globals = (yyscan_t) cmFortran_yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+
+    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* cmFortran_yylex_init_extra has the same functionality as cmFortran_yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to cmFortran_yyalloc in
+ * the yyextra field.
+ */
+
+int cmFortran_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+    struct yyguts_t dummy_yyguts;
+
+    cmFortran_yyset_extra (yy_user_defined, &dummy_yyguts);
+
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+
+    *ptr_yy_globals = (yyscan_t) cmFortran_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+
+    /* By setting to 0xAA, we expose bugs in
+    yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+    cmFortran_yyset_extra (yy_user_defined, *ptr_yy_globals);
+
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from cmFortran_yylex_destroy(), so don't allocate here.
+     */
+
+    yyg->yy_buffer_stack = 0;
+    yyg->yy_buffer_stack_top = 0;
+    yyg->yy_buffer_stack_max = 0;
+    yyg->yy_c_buf_p = (char *) 0;
+    yyg->yy_init = 0;
+    yyg->yy_start = 0;
+
+    yyg->yy_start_stack_ptr = 0;
+    yyg->yy_start_stack_depth = 0;
+    yyg->yy_start_stack =  NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * cmFortran_yylex_init()
+     */
+    return 0;
+}
+
+/* cmFortran_yylex_destroy is for both reentrant and non-reentrant scanners. */
+int cmFortran_yylex_destroy  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    /* Pop the buffer stack, destroying each element. */
+        while(YY_CURRENT_BUFFER){
+                cmFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+                YY_CURRENT_BUFFER_LVALUE = NULL;
+                cmFortran_yypop_buffer_state(yyscanner);
+        }
+
+        /* Destroy the stack itself. */
+        cmFortran_yyfree(yyg->yy_buffer_stack ,yyscanner);
+        yyg->yy_buffer_stack = NULL;
+
+    /* Destroy the start condition stack. */
+        cmFortran_yyfree(yyg->yy_start_stack ,yyscanner );
+        yyg->yy_start_stack = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * cmFortran_yylex() is called, initialization will occur. */
+    yy_init_globals( yyscanner);
+
+    /* Destroy the main struct (reentrant only). */
+    cmFortran_yyfree ( yyscanner , yyscanner );
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+        int i;
+        for ( i = 0; i < n; ++i )
+                s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+        int n;
+        for ( n = 0; s[n]; ++n )
+                ;
+
+        return n;
+}
+#endif
+
+void *cmFortran_yyalloc (yy_size_t  size , yyscan_t)
+{
+        return (void *) malloc( size );
+}
+
+void *cmFortran_yyrealloc  (void * ptr, yy_size_t  size , yyscan_t)
+{
+        /* The cast to (char *) in the following accommodates both
+         * implementations that use char* generic pointers, and those
+         * that use void* generic pointers.  It works with the latter
+         * because both ANSI C and C++ allow castless assignment from
+         * any pointer type to void*, and deal with argument conversions
+         * as though doing an assignment.
+         */
+        return (void *) realloc( (char *) ptr, size );
+}
+
+void cmFortran_yyfree (void * ptr , yyscan_t)
+{
+        free( (char *) ptr );   /* see cmFortran_yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 181 "cmFortranLexer.in.l"
+
+
+
+/*--------------------------------------------------------------------------*/
+YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
+{
+  /* Hack into the internal flex-generated scanner to get the buffer.  */
+  struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+  return YY_CURRENT_BUFFER;
+}
diff --git a/Source/cmFortranLexer.h b/Source/cmFortranLexer.h
new file mode 100644
index 0000000..c67e332
--- /dev/null
+++ b/Source/cmFortranLexer.h
@@ -0,0 +1,348 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmFortran_yyHEADER_H
+#define cmFortran_yyHEADER_H 1
+#define cmFortran_yyIN_HEADER 1
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else   /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif  /* defined (__STDC__) */
+#endif  /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+   are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+        {
+        FILE *yy_input_file;
+
+        char *yy_ch_buf;                /* input buffer */
+        char *yy_buf_pos;               /* current position in input buffer */
+
+        /* Size of input buffer in bytes, not including room for EOB
+         * characters.
+         */
+        yy_size_t yy_buf_size;
+
+        /* Number of characters read into yy_ch_buf, not including EOB
+         * characters.
+         */
+        int yy_n_chars;
+
+        /* Whether we "own" the buffer - i.e., we know we created it,
+         * and can realloc() it to grow it, and should free() it to
+         * delete it.
+         */
+        int yy_is_our_buffer;
+
+        /* Whether this is an "interactive" input source; if so, and
+         * if we're using stdio for input, then we want to use getc()
+         * instead of fread(), to make sure we stop fetching input after
+         * each newline.
+         */
+        int yy_is_interactive;
+
+        /* Whether we're considered to be at the beginning of a line.
+         * If so, '^' rules will be active on the next match, otherwise
+         * not.
+         */
+        int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+
+        /* Whether to try to fill the input buffer when we reach the
+         * end of it.
+         */
+        int yy_fill_buffer;
+
+        int yy_buffer_status;
+
+        };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+void cmFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmFortran_yypop_buffer_state (yyscan_t yyscanner );
+
+YY_BUFFER_STATE cmFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *cmFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmFortran_yyfree (void * ,yyscan_t yyscanner );
+
+/* Begin user sect3 */
+
+#define cmFortran_yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+#define yytext_ptr yytext_r
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+#define free_fmt 1
+#define fixed_fmt 2
+#define str_sq 3
+#define str_dq 4
+
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+int cmFortran_yylex_init (yyscan_t* scanner);
+
+int cmFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int cmFortran_yylex_destroy (yyscan_t yyscanner );
+
+int cmFortran_yyget_debug (yyscan_t yyscanner );
+
+void cmFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmFortran_yyget_extra (yyscan_t yyscanner );
+
+void cmFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmFortran_yyget_in (yyscan_t yyscanner );
+
+void cmFortran_yyset_in  (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmFortran_yyget_out (yyscan_t yyscanner );
+
+void cmFortran_yyset_out  (FILE * out_str ,yyscan_t yyscanner );
+
+int cmFortran_yyget_leng (yyscan_t yyscanner );
+
+char *cmFortran_yyget_text (yyscan_t yyscanner );
+
+int cmFortran_yyget_lineno (yyscan_t yyscanner );
+
+void cmFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int cmFortran_yywrap (yyscan_t yyscanner );
+#else
+extern int cmFortran_yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int cmFortran_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmFortran_yylex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+#undef cmFortran_yyIN_HEADER
+#endif /* cmFortran_yyHEADER_H */
diff --git a/Source/cmFortranLexer.in.l b/Source/cmFortranLexer.in.l
new file mode 100644
index 0000000..03fa90c
--- /dev/null
+++ b/Source/cmFortranLexer.in.l
@@ -0,0 +1,190 @@
+%{
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+  Portions of this source have been derived from makedepf90 version 2.8.8,
+
+   Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann at iki.fi>
+
+  The code was originally distributed under the GPL but permission
+  from the copyright holder has been obtained to distribute this
+  derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+  flex -i --prefix=cmFortran_yy --header-file=cmFortranLexer.h -ocmFortranLexer.cxx cmFortranLexer.in.l
+
+Modify cmFortranLexer.cxx:
+  - remove TABs
+  - remove use of the 'register' storage class specifier
+  - remove "yyscanner" argument from these methods:
+      yy_fatal_error, cmFortran_yyalloc, cmFortran_yyrealloc, cmFortran_yyfree
+  - remove "yyscanner = NULL" from end of cmFortran_yylex_destroy
+  - remove all YY_BREAK lines occurring right after return statements
+  - change while ( 1 ) to for(;;)
+
+Modify cmFortranLexer.h:
+  - remove TABs
+  - remove the yy_init_globals function
+  - remove the block that includes unistd.h
+  - remove #line directives (avoids bogus warning on old Sun)
+
+*/
+
+#include "cmStandardLexer.h"
+
+#define cmFortranLexer_cxx
+#include "cmFortranParser.h" /* Interface to parser object.  */
+
+/* Replace the lexer input function.  */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+  { result = cmFortranParser_Input(yyextra, buf, max_size); }
+
+/* Include the set of tokens from the parser.  */
+#include "cmFortranParserTokens.h"
+
+/*--------------------------------------------------------------------------*/
+%}
+
+
+%option reentrant
+%option noyywrap
+%pointer
+
+%s free_fmt fixed_fmt
+%x str_sq str_dq
+
+%%
+
+\"              {
+  cmFortranParser_StringStart(yyextra);
+  cmFortranParser_SetOldStartcond(yyextra, YY_START);
+  BEGIN(str_dq);
+}
+
+'               {
+  cmFortranParser_StringStart(yyextra);
+  cmFortranParser_SetOldStartcond(yyextra, YY_START);
+  BEGIN(str_sq);
+}
+
+<str_dq>\" |
+<str_sq>'  {
+  BEGIN(cmFortranParser_GetOldStartcond(yyextra) );
+  yylvalp->string = strdup(cmFortranParser_StringEnd(yyextra));
+  return STRING;
+}
+
+<str_dq,str_sq>&[ \t]*\n |
+<str_dq,str_sq>&[ \t]*\n[ \t]*&  /* Ignore (continued strings, free fmt) */
+
+<fixed_fmt,str_dq,str_sq>\n[ ]{5}[^ \t\n] {
+  if (cmFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
+    ; /* Ignore (cont. strings, fixed fmt) */
+  else
+    {
+    unput(yytext[strlen(yytext)-1]);
+    }
+}
+
+
+<str_dq,str_sq>\n {
+  unput ('\n');
+  BEGIN(INITIAL);
+  return UNTERMINATED_STRING;
+}
+
+<str_sq,str_dq>. {
+  cmFortranParser_StringAppend(yyextra, yytext[0]);
+}
+
+!.*\n                   { return EOSTMT; } /* Treat comments like */
+<fixed_fmt>^[cC*dD].*\n { return EOSTMT; } /* empty lines */
+
+^[ \t]*#[ \t]*include[ \t]*<[^>]+> {
+  yytext[yyleng-1] = 0;
+  yylvalp->string = strdup(strchr(yytext, '<')+1);
+  return CPP_INCLUDE_ANGLE;
+}
+^[ \t]*#[ \t]*include  { return CPP_INCLUDE; }
+\$[ \t]*include { return F90PPR_INCLUDE; }
+\?\?[ \t]*include { return COCO_INCLUDE; }
+
+^[ \t]*#[ \t]*define   { return CPP_DEFINE; }
+\$[ \t]*DEFINE   { return F90PPR_DEFINE; }
+
+^[ \t]*#[ \t]*undef    { return CPP_UNDEF; }
+\$[ \t]*UNDEF   { return F90PPR_UNDEF; }
+
+^[ \t]*#[ \t]*ifdef    { return CPP_IFDEF; }
+^[ \t]*#[ \t]*ifndef   { return CPP_IFNDEF; }
+^[ \t]*#[ \t]*if       { return CPP_IF; }
+^[ \t]*#[ \t]*elif     { return CPP_ELIF; }
+^[ \t]*#[ \t]*else     { return CPP_ELSE; }
+^[ \t]*#[ \t]*endif    { return CPP_ENDIF; }
+
+$[ \t]*ifdef    { return F90PPR_IFDEF; }
+$[ \t]*ifndef   { return F90PPR_IFNDEF; }
+$[ \t]*if       { return F90PPR_IF; }
+$[ \t]*elif     { return F90PPR_ELIF; }
+$[ \t]*else     { return F90PPR_ELSE; }
+$[ \t]*endif    { return F90PPR_ENDIF; }
+
+ /* Line continuations, possible involving comments.  */
+&([ \t\n]*|!.*)*
+&([ \t\n]*|!.*)*&
+
+, { return COMMA; }
+
+:: { return DCOLON; }
+
+<fixed_fmt>\n[ ]{5}[^ ]  { return GARBAGE; }
+
+=|=>                     { return ASSIGNMENT_OP; }
+
+[a-zA-Z_][a-zA-Z_0-9]* {
+  yylvalp->string = strdup(yytext);
+  return WORD;
+}
+
+[^ \t\n\r;,!'"a-zA-Z=&]+ { return GARBAGE; }
+
+;|\n { return EOSTMT; }
+
+
+[ \t\r,]         /* Ignore */
+\\[ \t]*\n       /* Ignore line-endings preceeded by \ */
+
+. { return *yytext; }
+
+<<EOF>> {
+  if(!cmFortranParser_FilePop(yyextra) )
+    {
+    return YY_NULL;
+    }
+}
+
+%%
+
+/*--------------------------------------------------------------------------*/
+YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
+{
+  /* Hack into the internal flex-generated scanner to get the buffer.  */
+  struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+  return YY_CURRENT_BUFFER;
+}
diff --git a/Source/cmFortranParser.cxx b/Source/cmFortranParser.cxx
new file mode 100644
index 0000000..0230f02
--- /dev/null
+++ b/Source/cmFortranParser.cxx
@@ -0,0 +1,1895 @@
+/* A Bison parser, made by GNU Bison 3.0.2.  */
+
+/* Bison implementation for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "3.0.2"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
+
+/* Substitute the variable and function names.  */
+#define yyparse         cmFortran_yyparse
+#define yylex           cmFortran_yylex
+#define yyerror         cmFortran_yyerror
+#define yydebug         cmFortran_yydebug
+#define yynerrs         cmFortran_yynerrs
+
+
+/* Copy the first part of user declarations.  */
+#line 1 "cmFortranParser.y" /* yacc.c:339  */
+
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+  Portions of this source have been derived from makedepf90 version 2.8.8,
+
+   Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann at iki.fi>
+
+  The code was originally distributed under the GPL but permission
+  from the copyright holder has been obtained to distribute this
+  derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+  bison --yacc --name-prefix=cmFortran_yy
+        --defines=cmFortranParserTokens.h
+         -ocmFortranParser.cxx
+          cmFortranParser.y
+
+Modify cmFortranParser.cxx:
+  - "#if 0" out yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
+*/
+
+/*-------------------------------------------------------------------------*/
+#define cmFortranParser_cxx
+#include "cmFortranParser.h" /* Interface to parser object.  */
+#include "cmFortranParserTokens.h" /* Need YYSTYPE for YY_DECL.  */
+
+#include <cmsys/String.h>
+
+/* Forward declare the lexer entry point.  */
+YY_DECL;
+
+/* Helper function to forward error callback from parser.  */
+static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
+{
+  cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+  cmFortranParser_Error(parser, message);
+}
+
+static bool cmFortranParserIsKeyword(const char* word,
+                                            const char* keyword)
+{
+  return cmsysString_strcasecmp(word, keyword) == 0;
+}
+
+/* Disable some warnings in the generated code.  */
+#ifdef _MSC_VER
+# pragma warning (disable: 4102) /* Unused goto label.  */
+# pragma warning (disable: 4065) /* Switch contains default but no case. */
+# pragma warning (disable: 4701) /* Local variable may not be initialized.  */
+# pragma warning (disable: 4702) /* Unreachable code.  */
+# pragma warning (disable: 4127) /* Conditional expression is constant.  */
+# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
+#endif
+
+#line 143 "cmFortranParser.cxx" /* yacc.c:339  */
+
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* In a future release of Bison, this section will be replaced
+   by #include "cmFortranParserTokens.h".  */
+#ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+# define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int cmFortran_yydebug;
+#endif
+
+/* Token type.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+  enum yytokentype
+  {
+    EOSTMT = 258,
+    ASSIGNMENT_OP = 259,
+    GARBAGE = 260,
+    CPP_INCLUDE = 261,
+    F90PPR_INCLUDE = 262,
+    COCO_INCLUDE = 263,
+    F90PPR_DEFINE = 264,
+    CPP_DEFINE = 265,
+    F90PPR_UNDEF = 266,
+    CPP_UNDEF = 267,
+    CPP_IFDEF = 268,
+    CPP_IFNDEF = 269,
+    CPP_IF = 270,
+    CPP_ELSE = 271,
+    CPP_ELIF = 272,
+    CPP_ENDIF = 273,
+    F90PPR_IFDEF = 274,
+    F90PPR_IFNDEF = 275,
+    F90PPR_IF = 276,
+    F90PPR_ELSE = 277,
+    F90PPR_ELIF = 278,
+    F90PPR_ENDIF = 279,
+    COMMA = 280,
+    DCOLON = 281,
+    CPP_TOENDL = 282,
+    UNTERMINATED_STRING = 283,
+    STRING = 284,
+    WORD = 285,
+    CPP_INCLUDE_ANGLE = 286
+  };
+#endif
+/* Tokens.  */
+#define EOSTMT 258
+#define ASSIGNMENT_OP 259
+#define GARBAGE 260
+#define CPP_INCLUDE 261
+#define F90PPR_INCLUDE 262
+#define COCO_INCLUDE 263
+#define F90PPR_DEFINE 264
+#define CPP_DEFINE 265
+#define F90PPR_UNDEF 266
+#define CPP_UNDEF 267
+#define CPP_IFDEF 268
+#define CPP_IFNDEF 269
+#define CPP_IF 270
+#define CPP_ELSE 271
+#define CPP_ELIF 272
+#define CPP_ENDIF 273
+#define F90PPR_IFDEF 274
+#define F90PPR_IFNDEF 275
+#define F90PPR_IF 276
+#define F90PPR_ELSE 277
+#define F90PPR_ELIF 278
+#define F90PPR_ENDIF 279
+#define COMMA 280
+#define DCOLON 281
+#define CPP_TOENDL 282
+#define UNTERMINATED_STRING 283
+#define STRING 284
+#define WORD 285
+#define CPP_INCLUDE_ANGLE 286
+
+/* Value type.  */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
+{
+#line 81 "cmFortranParser.y" /* yacc.c:355  */
+
+  char* string;
+
+#line 249 "cmFortranParser.cxx" /* yacc.c:355  */
+};
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+int cmFortran_yyparse (yyscan_t yyscanner);
+
+#endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED  */
+
+/* Copy the second part of user declarations.  */
+
+#line 263 "cmFortranParser.cxx" /* yacc.c:358  */
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's 'empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
+       && ! ((defined YYMALLOC || defined malloc) \
+             && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+      + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
+    do                                                                  \
+      {                                                                 \
+        YYSIZE_T yynewbytes;                                            \
+        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+        Stack = &yyptr->Stack_alloc;                                    \
+        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                 \
+    while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (0)
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  2
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   276
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  32
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  16
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  53
+/* YYNSTATES -- Number of states.  */
+#define YYNSTATES  97
+
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+   by yylex, with out-of-bounds checking.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   286
+
+#define YYTRANSLATE(YYX)                                                \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, without out-of-bounds checking.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31
+};
+
+#if YYDEBUG
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   103,   103,   103,   105,   105,   107,   113,   123,   153,
+     164,   177,   188,   195,   202,   208,   214,   220,   226,   231,
+     236,   241,   246,   250,   251,   252,   257,   257,   257,   258,
+     258,   259,   259,   260,   260,   261,   261,   262,   262,   263,
+     263,   264,   264,   265,   265,   266,   266,   269,   270,   271,
+     272,   273,   274,   275
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 1
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "EOSTMT", "ASSIGNMENT_OP", "GARBAGE",
+  "CPP_INCLUDE", "F90PPR_INCLUDE", "COCO_INCLUDE", "F90PPR_DEFINE",
+  "CPP_DEFINE", "F90PPR_UNDEF", "CPP_UNDEF", "CPP_IFDEF", "CPP_IFNDEF",
+  "CPP_IF", "CPP_ELSE", "CPP_ELIF", "CPP_ENDIF", "F90PPR_IFDEF",
+  "F90PPR_IFNDEF", "F90PPR_IF", "F90PPR_ELSE", "F90PPR_ELIF",
+  "F90PPR_ENDIF", "COMMA", "DCOLON", "CPP_TOENDL", "UNTERMINATED_STRING",
+  "STRING", "WORD", "CPP_INCLUDE_ANGLE", "$accept", "code", "stmt",
+  "assignment_stmt", "keyword_stmt", "include", "define", "undef", "ifdef",
+  "ifndef", "if", "elif", "else", "endif", "other", "misc_code", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+   (internal) symbol number NUM (which must be that of a token).  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286
+};
+# endif
+
+#define YYPACT_NINF -29
+
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-29)))
+
+#define YYTABLE_NINF -1
+
+#define yytable_value_is_error(Yytable_value) \
+  0
+
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
+static const yytype_int16 yypact[] =
+{
+     -29,    39,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,
+     -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,
+     -29,   -29,   -29,   -29,   -29,   246,   -29,   -29,   -29,   -29,
+     -28,   -27,   -22,   -17,   -16,   -29,   -29,   -29,   -29,     2,
+     -29,   -29,   -29,   -13,   -12,   -29,   -29,    61,   -29,   -29,
+     -29,   -29,   -29,    68,    74,    80,   108,   -29,   -29,   -29,
+     -29,   -29,   -29,   -29,   -29,   -29,   114,   120,   -24,   -29,
+     126,   154,   -29,   160,   166,   172,   200,   206,   -29,   -29,
+     -29,   -29,   -29,   -29,    -9,   212,   -29,   -29,   -29,   -29,
+     -29,   -29,   -29,   -29,   -29,   218,   -29
+};
+
+  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+     Performed when YYTABLE does not specify something else to do.  Zero
+     means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       2,     0,     1,    25,    24,    45,    26,    27,    28,    30,
+      29,    32,    31,    33,    35,    37,    41,    39,    43,    34,
+      36,    38,    42,    40,    44,     0,    45,     3,     5,     4,
+       0,     0,     0,     0,     0,    45,    45,    45,    45,     0,
+       7,    45,    45,     0,     0,    45,    45,     0,    45,    45,
+      45,    45,    45,     0,     0,     0,     0,    23,    50,    49,
+      52,    51,    53,    48,    47,    46,     0,     0,     0,    45,
+       0,     0,    12,     0,     0,     0,     0,     0,    18,    19,
+      20,    21,     6,    22,     0,     0,    11,     8,    13,    14,
+      15,    16,    17,    45,     9,     0,    10
+};
+
+  /* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+     -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,   -29,
+     -29,   -29,   -29,   -29,   -26,   -29
+};
+
+  /* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     1,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    65
+};
+
+  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule whose
+     number is the opposite.  If YYTABLE_NINF, syntax error.  */
+static const yytype_uint8 yytable[] =
+{
+      47,    48,    84,    49,     0,    57,    58,    59,    50,    53,
+      54,    55,    56,    51,    52,    66,    67,    68,    69,    70,
+      71,    93,    73,    74,    75,    76,    77,    60,    61,     0,
+      62,    63,    64,     0,     0,     0,     0,     0,     0,     2,
+       3,     0,     4,    85,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    72,    58,    59,    95,     0,    25,
+      26,    78,    58,    59,     0,     0,     0,    79,    58,    59,
+       0,     0,     0,    80,    58,    59,    60,    61,     0,    62,
+      63,    64,     0,    60,    61,     0,    62,    63,    64,    60,
+      61,     0,    62,    63,    64,    60,    61,     0,    62,    63,
+      64,    81,    58,    59,     0,     0,     0,    82,    58,    59,
+       0,     0,     0,    83,    58,    59,     0,     0,     0,    86,
+      58,    59,     0,    60,    61,     0,    62,    63,    64,    60,
+      61,     0,    62,    63,    64,    60,    61,     0,    62,    63,
+      64,    60,    61,     0,    62,    63,    64,    87,    58,    59,
+       0,     0,     0,    88,    58,    59,     0,     0,     0,    89,
+      58,    59,     0,     0,     0,    90,    58,    59,     0,    60,
+      61,     0,    62,    63,    64,    60,    61,     0,    62,    63,
+      64,    60,    61,     0,    62,    63,    64,    60,    61,     0,
+      62,    63,    64,    91,    58,    59,     0,     0,     0,    92,
+      58,    59,     0,     0,     0,    94,    58,    59,     0,     0,
+       0,    96,    58,    59,     0,    60,    61,     0,    62,    63,
+      64,    60,    61,     0,    62,    63,    64,    60,    61,     0,
+      62,    63,    64,    60,    61,     0,    62,    63,    64,    40,
+      41,    42,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    43,    44,     0,     0,    45,    46
+};
+
+static const yytype_int8 yycheck[] =
+{
+      26,    29,    26,    30,    -1,     3,     4,     5,    30,    35,
+      36,    37,    38,    30,    30,    41,    42,    30,    30,    45,
+      46,    30,    48,    49,    50,    51,    52,    25,    26,    -1,
+      28,    29,    30,    -1,    -1,    -1,    -1,    -1,    -1,     0,
+       1,    -1,     3,    69,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,     3,     4,     5,    93,    -1,    30,
+      31,     3,     4,     5,    -1,    -1,    -1,     3,     4,     5,
+      -1,    -1,    -1,     3,     4,     5,    25,    26,    -1,    28,
+      29,    30,    -1,    25,    26,    -1,    28,    29,    30,    25,
+      26,    -1,    28,    29,    30,    25,    26,    -1,    28,    29,
+      30,     3,     4,     5,    -1,    -1,    -1,     3,     4,     5,
+      -1,    -1,    -1,     3,     4,     5,    -1,    -1,    -1,     3,
+       4,     5,    -1,    25,    26,    -1,    28,    29,    30,    25,
+      26,    -1,    28,    29,    30,    25,    26,    -1,    28,    29,
+      30,    25,    26,    -1,    28,    29,    30,     3,     4,     5,
+      -1,    -1,    -1,     3,     4,     5,    -1,    -1,    -1,     3,
+       4,     5,    -1,    -1,    -1,     3,     4,     5,    -1,    25,
+      26,    -1,    28,    29,    30,    25,    26,    -1,    28,    29,
+      30,    25,    26,    -1,    28,    29,    30,    25,    26,    -1,
+      28,    29,    30,     3,     4,     5,    -1,    -1,    -1,     3,
+       4,     5,    -1,    -1,    -1,     3,     4,     5,    -1,    -1,
+      -1,     3,     4,     5,    -1,    25,    26,    -1,    28,    29,
+      30,    25,    26,    -1,    28,    29,    30,    25,    26,    -1,
+      28,    29,    30,    25,    26,    -1,    28,    29,    30,     3,
+       4,     5,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    25,    26,    -1,    -1,    29,    30
+};
+
+  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+     symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,    33,     0,     1,     3,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,    23,    24,    30,    31,    34,    35,    36,
+      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
+       3,     4,     5,    25,    26,    29,    30,    46,    29,    30,
+      30,    30,    30,    46,    46,    46,    46,     3,     4,     5,
+      25,    26,    28,    29,    30,    47,    46,    46,    30,    30,
+      46,    46,     3,    46,    46,    46,    46,    46,     3,     3,
+       3,     3,     3,     3,    26,    46,     3,     3,     3,     3,
+       3,     3,     3,    30,     3,    46,     3
+};
+
+  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    32,    33,    33,    34,    34,    35,    36,    36,    36,
+      36,    36,    36,    36,    36,    36,    36,    36,    36,    36,
+      36,    36,    36,    36,    36,    36,    37,    37,    37,    38,
+      38,    39,    39,    40,    40,    41,    41,    42,    42,    43,
+      43,    44,    44,    45,    45,    46,    46,    47,    47,    47,
+      47,    47,    47,    47
+};
+
+  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     1,     1,     4,     2,     4,     5,
+       7,     4,     3,     4,     4,     4,     4,     4,     3,     3,
+       3,     3,     4,     3,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     0,     2,     1,     1,     1,
+       1,     1,     1,     1
+};
+
+
+#define yyerrok         (yyerrstatus = 0)
+#define yyclearin       (yychar = YYEMPTY)
+#define YYEMPTY         (-2)
+#define YYEOF           0
+
+#define YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
+
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
+      yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+      YYERROR;                                                  \
+    }                                                           \
+while (0)
+
+/* Error token number */
+#define YYTERROR        1
+#define YYERRCODE       256
+
+
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                        \
+do {                                            \
+  if (yydebug)                                  \
+    YYFPRINTF Args;                             \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
+do {                                                                      \
+  if (yydebug)                                                            \
+    {                                                                     \
+      YYFPRINTF (stderr, "%s ", Title);                                   \
+      yy_symbol_print (stderr,                                            \
+                  Type, Value, yyscanner); \
+      YYFPRINTF (stderr, "\n");                                           \
+    }                                                                     \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT.  |
+`----------------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+{
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
+  YYUSE (yyscanner);
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+  YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+{
+  YYFPRINTF (yyoutput, "%s %s (",
+             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                            \
+do {                                                            \
+  if (yydebug)                                                  \
+    yy_stack_print ((Bottom), (Top));                           \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
+{
+  unsigned long int yylno = yyrline[yyrule];
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+             yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr,
+                       yystos[yyssp[yyi + 1 - yynrhs]],
+                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                                              , yyscanner);
+      YYFPRINTF (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)          \
+do {                                    \
+  if (yydebug)                          \
+    yy_reduce_print (yyssp, yyvsp, Rule, yyscanner); \
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+        switch (*++yyp)
+          {
+          case '\'':
+          case ',':
+            goto do_not_strip_quotes;
+
+          case '\\':
+            if (*++yyp != '\\')
+              goto do_not_strip_quotes;
+            /* Fall through.  */
+          default:
+            if (yyres)
+              yyres[yyn] = *yyp;
+            yyn++;
+            break;
+
+          case '"':
+            if (yyres)
+              yyres[yyn] = '\0';
+            return yyn;
+          }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
+
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
+{
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULLPTR;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
+    {
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          int yyxbegin = yyn < 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST - yyn + 1;
+          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+          int yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (! (yysize <= yysize1
+                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
+              }
+        }
+    }
+
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
+
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
+
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
+    }
+
+  /* Avoid sprintf, as that infringes on the user's name space.
+     Don't have undefined behavior even if the translation
+     produced a string with the wrong number of "%s"s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, yyscan_t yyscanner)
+{
+  YYUSE (yyvaluep);
+  YYUSE (yyscanner);
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+int
+yyparse (yyscan_t yyscanner)
+{
+/* The lookahead symbol.  */
+int yychar;
+
+
+/* The semantic value of the lookahead symbol.  */
+/* Default value used for initialization, for pacifying older GCCs
+   or non-GCC compilers.  */
+YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
+YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
+
+    /* Number of syntax errors so far.  */
+    int yynerrs;
+
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       'yyss': related to states.
+       'yyvs': related to semantic values.
+
+       Refer to the stacks through separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    YYSIZE_T yystacksize;
+
+  int yyn;
+  int yyresult;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
+  yystacksize = YYINITDEPTH;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY; /* Cause a token to be read.  */
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+        /* Give user a chance to reallocate the stack.  Use copies of
+           these so that the &'s don't force the real ones into
+           memory.  */
+        YYSTYPE *yyvs1 = yyvs;
+        yytype_int16 *yyss1 = yyss;
+
+        /* Each stack pointer address is followed by the size of the
+           data in use in that stack, in bytes.  This used to be a
+           conditional around just the two extra args, but that might
+           be undefined if yyoverflow is a macro.  */
+        yyoverflow (YY_("memory exhausted"),
+                    &yyss1, yysize * sizeof (*yyssp),
+                    &yyvs1, yysize * sizeof (*yyvsp),
+                    &yystacksize);
+
+        yyss = yyss1;
+        yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+        goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+        yystacksize = YYMAXDEPTH;
+
+      {
+        yytype_int16 *yyss1 = yyss;
+        union yyalloc *yyptr =
+          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+        if (! yyptr)
+          goto yyexhaustedlab;
+        YYSTACK_RELOCATE (yyss_alloc, yyss);
+        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+#  undef YYSTACK_RELOCATE
+        if (yyss1 != yyssa)
+          YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+        YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     lookahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+  yyn = yypact[yystate];
+  if (yypact_value_is_default (yyn))
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = yylex (&yylval, yyscanner);
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the lookahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+
+  yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     '$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 6:
+#line 108 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    free((yyvsp[-3].string));
+    }
+#line 1447 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 7:
+#line 114 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    if (cmFortranParserIsKeyword((yyvsp[-1].string), "interface"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_SetInInterface(parser, true);
+      }
+    free((yyvsp[-1].string));
+    }
+#line 1461 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 8:
+#line 124 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    if (cmFortranParserIsKeyword((yyvsp[-3].string), "use"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
+      }
+    else if (cmFortranParserIsKeyword((yyvsp[-3].string), "module"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleModule(parser, (yyvsp[-2].string));
+      }
+    else if (cmFortranParserIsKeyword((yyvsp[-3].string), "interface"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_SetInInterface(parser, true);
+      }
+    else if (cmFortranParserIsKeyword((yyvsp[-2].string), "interface") &&
+             cmFortranParserIsKeyword((yyvsp[-3].string), "end"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_SetInInterface(parser, false);
+      }
+    free((yyvsp[-3].string));
+    free((yyvsp[-2].string));
+    }
+#line 1495 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 9:
+#line 154 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    if (cmFortranParserIsKeyword((yyvsp[-4].string), "use"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
+      }
+    free((yyvsp[-4].string));
+    free((yyvsp[-2].string));
+    }
+#line 1510 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 10:
+#line 165 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    if (cmFortranParserIsKeyword((yyvsp[-6].string), "use") &&
+        cmFortranParserIsKeyword((yyvsp[-4].string), "non_intrinsic") )
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
+      }
+    free((yyvsp[-6].string));
+    free((yyvsp[-4].string));
+    free((yyvsp[-2].string));
+    }
+#line 1527 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 11:
+#line 178 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    if (cmFortranParserIsKeyword((yyvsp[-3].string), "include"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
+      }
+    free((yyvsp[-3].string));
+    free((yyvsp[-2].string));
+    }
+#line 1542 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 12:
+#line 189 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser =
+      cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
+    free((yyvsp[-2].string));
+    }
+#line 1553 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 13:
+#line 196 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser =
+      cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
+    free((yyvsp[-2].string));
+    }
+#line 1564 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 14:
+#line 203 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
+    free((yyvsp[-2].string));
+    }
+#line 1574 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 15:
+#line 209 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
+    free((yyvsp[-2].string));
+    }
+#line 1584 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 16:
+#line 215 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
+    free((yyvsp[-2].string));
+    }
+#line 1594 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 17:
+#line 221 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
+    free((yyvsp[-2].string));
+    }
+#line 1604 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 18:
+#line 227 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleIf(parser);
+    }
+#line 1613 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 19:
+#line 232 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleElif(parser);
+    }
+#line 1622 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 20:
+#line 237 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleElse(parser);
+    }
+#line 1631 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 21:
+#line 242 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleEndif(parser);
+    }
+#line 1640 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 22:
+#line 247 "cmFortranParser.y" /* yacc.c:1646  */
+    {
+    free((yyvsp[-3].string));
+    }
+#line 1648 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 47:
+#line 269 "cmFortranParser.y" /* yacc.c:1646  */
+    { free ((yyvsp[0].string)); }
+#line 1654 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+  case 48:
+#line 270 "cmFortranParser.y" /* yacc.c:1646  */
+    { free ((yyvsp[0].string)); }
+#line 1660 "cmFortranParser.cxx" /* yacc.c:1646  */
+    break;
+
+
+#line 1664 "cmFortranParser.cxx" /* yacc.c:1646  */
+      default: break;
+    }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+  /* Now 'shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error.  |
+`--------------------------------------*/
+yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (yyscanner, YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
+      {
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (yyscanner, yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
+      }
+# undef YYSYNTAX_ERROR
+#endif
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+         error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+          /* Return failure if at end of input.  */
+          if (yychar == YYEOF)
+            YYABORT;
+        }
+      else
+        {
+          yydestruct ("Error: discarding",
+                      yytoken, &yylval, yyscanner);
+          yychar = YYEMPTY;
+        }
+    }
+
+#if 0
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  /* Do not reclaim the symbols of the rule whose action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+#endif
+  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (!yypact_value_is_default (yyn))
+        {
+          yyn += YYTERROR;
+          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+            {
+              yyn = yytable[yyn];
+              if (0 < yyn)
+                break;
+            }
+        }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+        YYABORT;
+
+
+      yydestruct ("Error: popping",
+                  yystos[yystate], yyvsp, yyscanner);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (yyscanner, YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEMPTY)
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval, yyscanner);
+    }
+  /* Do not reclaim the symbols of the rule whose action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                  yystos[*yyssp], yyvsp, yyscanner);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  return yyresult;
+}
+#line 278 "cmFortranParser.y" /* yacc.c:1906  */
+
+/* End of grammar */
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
new file mode 100644
index 0000000..156c38a
--- /dev/null
+++ b/Source/cmFortranParser.h
@@ -0,0 +1,175 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmFortranParser_h
+#define cmFortranParser_h
+
+#if !defined(cmFortranLexer_cxx) && !defined(cmFortranParser_cxx)
+# include "cmStandardIncludes.h"
+#endif
+
+#include <stddef.h> /* size_t */
+
+/* Forward declare parser object type.  */
+typedef struct cmFortranParser_s cmFortranParser;
+
+/* Functions to enter/exit #include'd files in order.  */
+bool cmFortranParser_FilePush(cmFortranParser* parser,
+                                    const char* fname);
+bool cmFortranParser_FilePop(cmFortranParser* parser);
+
+/* Callbacks for lexer.  */
+int cmFortranParser_Input(cmFortranParser* parser,
+                                 char* buffer, size_t bufferSize);
+
+
+void cmFortranParser_StringStart(cmFortranParser* parser);
+const char* cmFortranParser_StringEnd(cmFortranParser* parser);
+void cmFortranParser_StringAppend(cmFortranParser* parser,
+                                         char c);
+
+void cmFortranParser_SetInInterface(cmFortranParser* parser,
+                                           bool is_in);
+bool cmFortranParser_GetInInterface(cmFortranParser* parser);
+
+
+void cmFortranParser_SetInPPFalseBranch(cmFortranParser* parser,
+                                               bool is_in);
+bool cmFortranParser_GetInPPFalseBranch(cmFortranParser* parser);
+
+
+void cmFortranParser_SetOldStartcond(cmFortranParser* parser,
+                                            int arg);
+int cmFortranParser_GetOldStartcond(cmFortranParser* parser);
+
+/* Callbacks for parser.  */
+void cmFortranParser_Error(cmFortranParser* parser,
+                                  const char* message);
+void cmFortranParser_RuleUse(cmFortranParser* parser,
+                                    const char* name);
+void cmFortranParser_RuleInclude(cmFortranParser* parser,
+                                        const char* name);
+void cmFortranParser_RuleModule(cmFortranParser* parser,
+                                       const char* name);
+void cmFortranParser_RuleDefine(cmFortranParser* parser,
+                                       const char* name);
+void cmFortranParser_RuleUndef(cmFortranParser* parser,
+                                      const char* name);
+void cmFortranParser_RuleIfdef(cmFortranParser* parser,
+                                      const char* name);
+void cmFortranParser_RuleIfndef(cmFortranParser* parser,
+                                       const char* name);
+void cmFortranParser_RuleIf(cmFortranParser* parser);
+void cmFortranParser_RuleElif(cmFortranParser* parser);
+void cmFortranParser_RuleElse(cmFortranParser* parser);
+void cmFortranParser_RuleEndif(cmFortranParser* parser);
+
+/* Define the parser stack element type.  */
+typedef union cmFortran_yystype_u cmFortran_yystype;
+union cmFortran_yystype_u
+{
+  char* string;
+};
+
+/* Setup the proper yylex interface.  */
+#define YY_EXTRA_TYPE cmFortranParser*
+#define YY_DECL \
+int cmFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
+#define YYSTYPE cmFortran_yystype
+#define YYSTYPE_IS_DECLARED 1
+#if !defined(cmFortranLexer_cxx)
+# include "cmFortranLexer.h"
+#endif
+#if !defined(cmFortranLexer_cxx)
+#if !defined(cmFortranParser_cxx)
+# undef YY_EXTRA_TYPE
+# undef YY_DECL
+# undef YYSTYPE
+# undef YYSTYPE_IS_DECLARED
+#endif
+#endif
+
+#if !defined(cmFortranLexer_cxx) && !defined(cmFortranParser_cxx)
+#include <stack>
+
+//----------------------------------------------------------------------------
+// Information about a single source file.
+class cmFortranSourceInfo
+{
+public:
+  // The name of the source file.
+  std::string Source;
+
+  // Set of provided and required modules.
+  std::set<std::string> Provides;
+  std::set<std::string> Requires;
+
+  // Set of files included in the translation unit.
+  std::set<std::string> Includes;
+};
+
+//----------------------------------------------------------------------------
+// Parser methods not included in generated interface.
+
+// Get the current buffer processed by the lexer.
+YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner);
+
+// The parser entry point.
+int cmFortran_yyparse(yyscan_t);
+
+//----------------------------------------------------------------------------
+// Define parser object internal structure.
+struct cmFortranFile
+{
+  cmFortranFile(FILE* file, YY_BUFFER_STATE buffer,
+                       const std::string& dir):
+    File(file), Buffer(buffer), Directory(dir) {}
+  FILE* File;
+  YY_BUFFER_STATE Buffer;
+  std::string Directory;
+};
+
+struct cmFortranParser_s
+{
+  cmFortranParser_s(std::vector<std::string> const& includes,
+                    std::set<std::string> const& defines,
+                    cmFortranSourceInfo& info);
+  ~cmFortranParser_s();
+
+  bool FindIncludeFile(const char* dir, const char* includeName,
+                       std::string& fileName);
+
+  // The include file search path.
+  std::vector<std::string> IncludePath;
+
+  // Lexical scanner instance.
+  yyscan_t Scanner;
+
+  // Stack of open files in the translation unit.
+  std::stack<cmFortranFile> FileStack;
+
+  // Buffer for string literals.
+  std::string TokenString;
+
+  // Flag for whether lexer is reading from inside an interface.
+  bool InInterface;
+
+  int OldStartcond;
+  std::set<std::string> PPDefinitions;
+  size_t InPPFalseBranch;
+  std::stack<bool> SkipToEnd;
+
+  // Information about the parsed source.
+  cmFortranSourceInfo& Info;
+};
+#endif
+
+#endif
diff --git a/Source/cmFortranParser.y b/Source/cmFortranParser.y
new file mode 100644
index 0000000..996bef6
--- /dev/null
+++ b/Source/cmFortranParser.y
@@ -0,0 +1,279 @@
+%{
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+  Portions of this source have been derived from makedepf90 version 2.8.8,
+
+   Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann at iki.fi>
+
+  The code was originally distributed under the GPL but permission
+  from the copyright holder has been obtained to distribute this
+  derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+  bison --yacc --name-prefix=cmFortran_yy
+        --defines=cmFortranParserTokens.h
+         -ocmFortranParser.cxx
+          cmFortranParser.y
+
+Modify cmFortranParser.cxx:
+  - "#if 0" out yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
+*/
+
+/*-------------------------------------------------------------------------*/
+#define cmFortranParser_cxx
+#include "cmFortranParser.h" /* Interface to parser object.  */
+#include "cmFortranParserTokens.h" /* Need YYSTYPE for YY_DECL.  */
+
+#include <cmsys/String.h>
+
+/* Forward declare the lexer entry point.  */
+YY_DECL;
+
+/* Helper function to forward error callback from parser.  */
+static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
+{
+  cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+  cmFortranParser_Error(parser, message);
+}
+
+static bool cmFortranParserIsKeyword(const char* word,
+                                            const char* keyword)
+{
+  return cmsysString_strcasecmp(word, keyword) == 0;
+}
+
+/* Disable some warnings in the generated code.  */
+#ifdef _MSC_VER
+# pragma warning (disable: 4102) /* Unused goto label.  */
+# pragma warning (disable: 4065) /* Switch contains default but no case. */
+# pragma warning (disable: 4701) /* Local variable may not be initialized.  */
+# pragma warning (disable: 4702) /* Unreachable code.  */
+# pragma warning (disable: 4127) /* Conditional expression is constant.  */
+# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
+#endif
+%}
+
+/* Generate a reentrant parser object.  */
+%define api.pure
+
+/* Configure the parser to use a lexer object.  */
+%lex-param   {yyscan_t yyscanner}
+%parse-param {yyscan_t yyscanner}
+
+%define parse.error verbose
+
+%union {
+  char* string;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Tokens */
+%token EOSTMT ASSIGNMENT_OP GARBAGE
+%token CPP_INCLUDE F90PPR_INCLUDE COCO_INCLUDE
+%token F90PPR_DEFINE CPP_DEFINE F90PPR_UNDEF CPP_UNDEF
+%token CPP_IFDEF CPP_IFNDEF CPP_IF CPP_ELSE CPP_ELIF CPP_ENDIF
+%token F90PPR_IFDEF F90PPR_IFNDEF F90PPR_IF
+%token F90PPR_ELSE F90PPR_ELIF F90PPR_ENDIF
+%token COMMA DCOLON
+%token <string> CPP_TOENDL
+%token <number> UNTERMINATED_STRING
+%token <string> STRING WORD
+%token <string> CPP_INCLUDE_ANGLE
+
+/*-------------------------------------------------------------------------*/
+/* grammar */
+%%
+
+code: /* empty */ | code stmt;
+
+stmt: keyword_stmt | assignment_stmt;
+
+assignment_stmt: WORD ASSIGNMENT_OP other EOSTMT    /* Ignore */
+    {
+    free($1);
+    }
+
+keyword_stmt:
+  WORD EOSTMT
+    {
+    if (cmFortranParserIsKeyword($1, "interface"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_SetInInterface(parser, true);
+      }
+    free($1);
+    }
+| WORD WORD other EOSTMT
+    {
+    if (cmFortranParserIsKeyword($1, "use"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleUse(parser, $2);
+      }
+    else if (cmFortranParserIsKeyword($1, "module"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleModule(parser, $2);
+      }
+    else if (cmFortranParserIsKeyword($1, "interface"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_SetInInterface(parser, true);
+      }
+    else if (cmFortranParserIsKeyword($2, "interface") &&
+             cmFortranParserIsKeyword($1, "end"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_SetInInterface(parser, false);
+      }
+    free($1);
+    free($2);
+    }
+| WORD DCOLON WORD other EOSTMT
+    {
+    if (cmFortranParserIsKeyword($1, "use"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleUse(parser, $3);
+      }
+    free($1);
+    free($3);
+    }
+| WORD COMMA WORD DCOLON WORD other EOSTMT
+    {
+    if (cmFortranParserIsKeyword($1, "use") &&
+        cmFortranParserIsKeyword($3, "non_intrinsic") )
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleUse(parser, $5);
+      }
+    free($1);
+    free($3);
+    free($5);
+    }
+| WORD STRING other EOSTMT /* Ignore */
+    {
+    if (cmFortranParserIsKeyword($1, "include"))
+      {
+      cmFortranParser* parser =
+        cmFortran_yyget_extra(yyscanner);
+      cmFortranParser_RuleInclude(parser, $2);
+      }
+    free($1);
+    free($2);
+    }
+| CPP_INCLUDE_ANGLE other EOSTMT
+    {
+    cmFortranParser* parser =
+      cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleInclude(parser, $1);
+    free($1);
+    }
+| include STRING other EOSTMT
+    {
+    cmFortranParser* parser =
+      cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleInclude(parser, $2);
+    free($2);
+    }
+| define WORD other EOSTMT
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleDefine(parser, $2);
+    free($2);
+    }
+| undef WORD other EOSTMT
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleUndef(parser, $2);
+    free($2);
+    }
+| ifdef WORD other EOSTMT
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleIfdef(parser, $2);
+    free($2);
+    }
+| ifndef WORD other EOSTMT
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleIfndef(parser, $2);
+    free($2);
+    }
+| if other EOSTMT
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleIf(parser);
+    }
+| elif other EOSTMT
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleElif(parser);
+    }
+| else other EOSTMT
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleElse(parser);
+    }
+| endif other EOSTMT
+    {
+    cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+    cmFortranParser_RuleEndif(parser);
+    }
+| WORD GARBAGE other EOSTMT             /* Ignore */
+    {
+    free($1);
+    }
+| GARBAGE other EOSTMT
+| EOSTMT
+| error
+;
+
+
+
+include: CPP_INCLUDE | F90PPR_INCLUDE | COCO_INCLUDE ;
+define: CPP_DEFINE | F90PPR_DEFINE;
+undef: CPP_UNDEF | F90PPR_UNDEF ;
+ifdef: CPP_IFDEF | F90PPR_IFDEF ;
+ifndef: CPP_IFNDEF | F90PPR_IFNDEF ;
+if: CPP_IF | F90PPR_IF ;
+elif: CPP_ELIF | F90PPR_ELIF ;
+else: CPP_ELSE | F90PPR_ELSE ;
+endif: CPP_ENDIF | F90PPR_ENDIF ;
+other: /* empty */ | other misc_code ;
+
+misc_code:
+  WORD                { free ($1); }
+| STRING              { free ($1); }
+| GARBAGE
+| ASSIGNMENT_OP
+| DCOLON
+| COMMA
+| UNTERMINATED_STRING
+;
+
+%%
+/* End of grammar */
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
new file mode 100644
index 0000000..a09c545
--- /dev/null
+++ b/Source/cmFortranParserImpl.cxx
@@ -0,0 +1,408 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmFortranParser.h"
+
+#include "cmSystemTools.h"
+#include <assert.h>
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_s::FindIncludeFile(const char* dir,
+                                        const char* includeName,
+                                        std::string& fileName)
+{
+  // If the file is a full path, include it directly.
+  if(cmSystemTools::FileIsFullPath(includeName))
+    {
+    fileName = includeName;
+    return cmSystemTools::FileExists(fileName.c_str(), true);
+    }
+  else
+    {
+    // Check for the file in the directory containing the including
+    // file.
+    std::string fullName = dir;
+    fullName += "/";
+    fullName += includeName;
+    if(cmSystemTools::FileExists(fullName.c_str(), true))
+      {
+      fileName = fullName;
+      return true;
+      }
+
+    // Search the include path for the file.
+    for(std::vector<std::string>::const_iterator i =
+          this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
+      {
+      fullName = *i;
+      fullName += "/";
+      fullName += includeName;
+      if(cmSystemTools::FileExists(fullName.c_str(), true))
+        {
+        fileName = fullName;
+        return true;
+        }
+      }
+    }
+  return false;
+}
+
+//----------------------------------------------------------------------------
+cmFortranParser_s
+::cmFortranParser_s(std::vector<std::string> const& includes,
+                    std::set<std::string> const& defines,
+                    cmFortranSourceInfo& info):
+  IncludePath(includes), PPDefinitions(defines), Info(info)
+{
+  this->InInterface = 0;
+  this->InPPFalseBranch = 0;
+
+  // Initialize the lexical scanner.
+  cmFortran_yylex_init(&this->Scanner);
+  cmFortran_yyset_extra(this, this->Scanner);
+
+  // Create a dummy buffer that is never read but is the fallback
+  // buffer when the last file is popped off the stack.
+  YY_BUFFER_STATE buffer =
+    cmFortran_yy_create_buffer(0, 4, this->Scanner);
+  cmFortran_yy_switch_to_buffer(buffer, this->Scanner);
+}
+
+//----------------------------------------------------------------------------
+cmFortranParser_s::~cmFortranParser_s()
+{
+  cmFortran_yylex_destroy(this->Scanner);
+}
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_FilePush(cmFortranParser* parser,
+                                    const char* fname)
+{
+  // Open the new file and push it onto the stack.  Save the old
+  // buffer with it on the stack.
+  if(FILE* file = cmsys::SystemTools::Fopen(fname, "rb"))
+    {
+    YY_BUFFER_STATE current =
+      cmFortranLexer_GetCurrentBuffer(parser->Scanner);
+    std::string dir = cmSystemTools::GetParentDirectory(fname);
+    cmFortranFile f(file, current, dir);
+    YY_BUFFER_STATE buffer =
+      cmFortran_yy_create_buffer(0, 16384, parser->Scanner);
+    cmFortran_yy_switch_to_buffer(buffer, parser->Scanner);
+    parser->FileStack.push(f);
+    return 1;
+    }
+  else
+    {
+    return 0;
+    }
+}
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_FilePop(cmFortranParser* parser)
+{
+  // Pop one file off the stack and close it.  Switch the lexer back
+  // to the next one on the stack.
+  if(parser->FileStack.empty())
+    {
+    return 0;
+    }
+  else
+    {
+    cmFortranFile f = parser->FileStack.top(); parser->FileStack.pop();
+    fclose(f.File);
+    YY_BUFFER_STATE current =
+      cmFortranLexer_GetCurrentBuffer(parser->Scanner);
+    cmFortran_yy_delete_buffer(current, parser->Scanner);
+    cmFortran_yy_switch_to_buffer(f.Buffer, parser->Scanner);
+    return 1;
+    }
+}
+
+//----------------------------------------------------------------------------
+int cmFortranParser_Input(cmFortranParser* parser,
+                                 char* buffer, size_t bufferSize)
+{
+  // Read from the file on top of the stack.  If the stack is empty,
+  // the end of the translation unit has been reached.
+  if(!parser->FileStack.empty())
+    {
+    FILE* file = parser->FileStack.top().File;
+    return (int)fread(buffer, 1, bufferSize, file);
+    }
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_StringStart(cmFortranParser* parser)
+{
+  parser->TokenString = "";
+}
+
+//----------------------------------------------------------------------------
+const char* cmFortranParser_StringEnd(cmFortranParser* parser)
+{
+  return parser->TokenString.c_str();
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_StringAppend(cmFortranParser* parser,
+                                         char c)
+{
+  parser->TokenString += c;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_SetInInterface(cmFortranParser* parser,
+                                           bool in)
+{
+  if(parser->InPPFalseBranch)
+    {
+    return;
+    }
+
+  parser->InInterface = in;
+}
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_GetInInterface(cmFortranParser* parser)
+{
+  return parser->InInterface;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_SetOldStartcond(cmFortranParser* parser,
+                                            int arg)
+{
+  parser->OldStartcond = arg;
+}
+
+//----------------------------------------------------------------------------
+int cmFortranParser_GetOldStartcond(cmFortranParser* parser)
+{
+  return parser->OldStartcond;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_Error(cmFortranParser*, const char*)
+{
+  // If there is a parser error just ignore it.  The source will not
+  // compile and the user will edit it.  Then dependencies will have
+  // to be regenerated anyway.
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleUse(cmFortranParser* parser,
+                                    const char* name)
+{
+  if(!parser->InPPFalseBranch)
+    {
+    parser->Info.Requires.insert(cmSystemTools::LowerCase(name) );
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleInclude(cmFortranParser* parser,
+                                        const char* name)
+{
+  if(parser->InPPFalseBranch)
+    {
+    return;
+    }
+
+  // If processing an include statement there must be an open file.
+  assert(!parser->FileStack.empty());
+
+  // Get the directory containing the source in which the include
+  // statement appears.  This is always the first search location for
+  // Fortran include files.
+  std::string dir = parser->FileStack.top().Directory;
+
+  // Find the included file.  If it cannot be found just ignore the
+  // problem because either the source will not compile or the user
+  // does not care about depending on this included source.
+  std::string fullName;
+  if(parser->FindIncludeFile(dir.c_str(), name, fullName))
+    {
+    // Found the included file.  Save it in the set of included files.
+    parser->Info.Includes.insert(fullName);
+
+    // Parse it immediately to translate the source inline.
+    cmFortranParser_FilePush(parser, fullName.c_str());
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleModule(cmFortranParser* parser,
+                                       const char* name)
+{
+  if(!parser->InPPFalseBranch && !parser->InInterface)
+    {
+    parser->Info.Provides.insert(cmSystemTools::LowerCase(name));
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleDefine(cmFortranParser* parser,
+                                       const char* macro)
+{
+  if(!parser->InPPFalseBranch)
+    {
+    parser->PPDefinitions.insert(macro);
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleUndef(cmFortranParser* parser,
+                                      const char* macro)
+{
+  if(!parser->InPPFalseBranch)
+    {
+    std::set<std::string>::iterator match;
+    match = parser->PPDefinitions.find(macro);
+    if(match != parser->PPDefinitions.end())
+      {
+      parser->PPDefinitions.erase(match);
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleIfdef(cmFortranParser* parser,
+                                      const char* macro)
+{
+  // A new PP branch has been opened
+  parser->SkipToEnd.push(false);
+
+  if (parser->InPPFalseBranch)
+    {
+    parser->InPPFalseBranch++;
+    }
+  else if(parser->PPDefinitions.find(macro) == parser->PPDefinitions.end())
+    {
+    parser->InPPFalseBranch=1;
+    }
+  else
+    {
+    parser->SkipToEnd.top() = true;
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleIfndef(cmFortranParser* parser,
+  const char* macro)
+{
+  // A new PP branch has been opened
+  parser->SkipToEnd.push(false);
+
+  if (parser->InPPFalseBranch)
+    {
+    parser->InPPFalseBranch++;
+    }
+  else if(parser->PPDefinitions.find(macro) != parser->PPDefinitions.end())
+    {
+    parser->InPPFalseBranch = 1;
+    }
+  else
+    {
+    // ignore other branches
+    parser->SkipToEnd.top() = true;
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleIf(cmFortranParser* parser)
+{
+  /* Note: The current parser is _not_ able to get statements like
+   *   #if 0
+   *   #if 1
+   *   #if MYSMBOL
+   *   #if defined(MYSYMBOL)
+   *   #if defined(MYSYMBOL) && ...
+   * right.  The same for #elif.  Thus in
+   *   #if SYMBOL_1
+   *     ..
+   *   #elif SYMBOL_2
+   *     ...
+   *     ...
+   *   #elif SYMBOL_N
+   *     ..
+   *   #else
+   *     ..
+   *   #endif
+   * _all_ N+1 branches are considered.  If you got something like this
+   *   #if defined(MYSYMBOL)
+   *   #if !defined(MYSYMBOL)
+   * use
+   *   #ifdef MYSYMBOL
+   *   #ifndef MYSYMBOL
+   * instead.
+   */
+
+  // A new PP branch has been opened
+  // Never skip!  See note above.
+  parser->SkipToEnd.push(false);
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleElif(cmFortranParser* parser)
+{
+  /* Note: There are parser limitations.  See the note at
+   * cmFortranParser_RuleIf(..)
+   */
+
+  // Always taken unless an #ifdef or #ifndef-branch has been taken
+  // already.  If the second condition isn't meet already
+  // (parser->InPPFalseBranch == 0) correct it.
+  if(!parser->SkipToEnd.empty() &&
+     parser->SkipToEnd.top() && !parser->InPPFalseBranch)
+    {
+    parser->InPPFalseBranch = 1;
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleElse(cmFortranParser* parser)
+{
+  // if the parent branch is false do nothing!
+  if(parser->InPPFalseBranch > 1)
+    {
+    return;
+    }
+
+  // parser->InPPFalseBranch is either 0 or 1.  We change it depending on
+  // parser->SkipToEnd.top()
+  if(!parser->SkipToEnd.empty() &&
+     parser->SkipToEnd.top())
+    {
+    parser->InPPFalseBranch = 1;
+    }
+  else
+    {
+    parser->InPPFalseBranch = 0;
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleEndif(cmFortranParser* parser)
+{
+  if(!parser->SkipToEnd.empty())
+    {
+    parser->SkipToEnd.pop();
+    }
+
+  // #endif doesn't know if there was a "#else" in before, so it
+  // always decreases InPPFalseBranch
+  if(parser->InPPFalseBranch)
+    {
+    parser->InPPFalseBranch--;
+    }
+}
diff --git a/Source/cmFortranParserTokens.h b/Source/cmFortranParserTokens.h
new file mode 100644
index 0000000..df1aec3
--- /dev/null
+++ b/Source/cmFortranParserTokens.h
@@ -0,0 +1,129 @@
+/* A Bison parser, made by GNU Bison 3.0.2.  */
+
+/* Bison interface for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+#ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+# define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int cmFortran_yydebug;
+#endif
+
+/* Token type.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+  enum yytokentype
+  {
+    EOSTMT = 258,
+    ASSIGNMENT_OP = 259,
+    GARBAGE = 260,
+    CPP_INCLUDE = 261,
+    F90PPR_INCLUDE = 262,
+    COCO_INCLUDE = 263,
+    F90PPR_DEFINE = 264,
+    CPP_DEFINE = 265,
+    F90PPR_UNDEF = 266,
+    CPP_UNDEF = 267,
+    CPP_IFDEF = 268,
+    CPP_IFNDEF = 269,
+    CPP_IF = 270,
+    CPP_ELSE = 271,
+    CPP_ELIF = 272,
+    CPP_ENDIF = 273,
+    F90PPR_IFDEF = 274,
+    F90PPR_IFNDEF = 275,
+    F90PPR_IF = 276,
+    F90PPR_ELSE = 277,
+    F90PPR_ELIF = 278,
+    F90PPR_ENDIF = 279,
+    COMMA = 280,
+    DCOLON = 281,
+    CPP_TOENDL = 282,
+    UNTERMINATED_STRING = 283,
+    STRING = 284,
+    WORD = 285,
+    CPP_INCLUDE_ANGLE = 286
+  };
+#endif
+/* Tokens.  */
+#define EOSTMT 258
+#define ASSIGNMENT_OP 259
+#define GARBAGE 260
+#define CPP_INCLUDE 261
+#define F90PPR_INCLUDE 262
+#define COCO_INCLUDE 263
+#define F90PPR_DEFINE 264
+#define CPP_DEFINE 265
+#define F90PPR_UNDEF 266
+#define CPP_UNDEF 267
+#define CPP_IFDEF 268
+#define CPP_IFNDEF 269
+#define CPP_IF 270
+#define CPP_ELSE 271
+#define CPP_ELIF 272
+#define CPP_ENDIF 273
+#define F90PPR_IFDEF 274
+#define F90PPR_IFNDEF 275
+#define F90PPR_IF 276
+#define F90PPR_ELSE 277
+#define F90PPR_ELIF 278
+#define F90PPR_ENDIF 279
+#define COMMA 280
+#define DCOLON 281
+#define CPP_TOENDL 282
+#define UNTERMINATED_STRING 283
+#define STRING 284
+#define WORD 285
+#define CPP_INCLUDE_ANGLE 286
+
+/* Value type.  */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
+{
+#line 81 "cmFortranParser.y" /* yacc.c:1909  */
+
+  char* string;
+
+#line 120 "cmFortranParserTokens.h" /* yacc.c:1909  */
+};
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+int cmFortran_yyparse (yyscan_t yyscanner);
+
+#endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED  */
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 001adb1..c883ad7 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -43,6 +43,7 @@ public:
     newC->Args = this->Args;
     newC->Functions = this->Functions;
     newC->Policies = this->Policies;
+    newC->FilePath = this->FilePath;
     return newC;
   }
 
@@ -71,9 +72,9 @@ public:
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
   cmPolicies::PolicyMap Policies;
+  std::string FilePath;
 };
 
-
 bool cmFunctionHelperCommand::InvokeInitialPass
 (const std::vector<cmListFileArgument>& args,
  cmExecutionStatus & inStatus)
@@ -93,14 +94,9 @@ bool cmFunctionHelperCommand::InvokeInitialPass
     return false;
     }
 
-  // we push a scope on the makefile
-  cmMakefile::ScopePushPop varScope(this->Makefile);
-  cmMakefile::LexicalPushPop lexScope(this->Makefile);
-  static_cast<void>(varScope);
-
-  // Push a weak policy scope which restores the policies recorded at
-  // function creation.
-  cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
+  cmMakefile::FunctionPushPop functionScope(this->Makefile,
+                                            this->FilePath,
+                                            this->Policies);
 
   // set the value of argc
   std::ostringstream strStream;
@@ -129,7 +125,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass
   std::string argvDef = cmJoin(expandedArgs, ";");
   std::vector<std::string>::const_iterator eit
       = expandedArgs.begin() + (this->Args.size()-1);
-  std::string argnDef = cmJoin(cmRange(eit, expandedArgs.end()), ";");
+  std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
   this->Makefile->AddDefinition("ARGV", argvDef.c_str());
   this->Makefile->MarkVariableAsUsed("ARGV");
   this->Makefile->AddDefinition("ARGN", argnDef.c_str());
@@ -145,8 +141,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass
       {
       // The error message should have already included the call stack
       // so we do not need to report an error here.
-      lexScope.Quiet();
-      polScope.Quiet();
+      functionScope.Quiet();
       inStatus.SetNestedError(true);
       return false;
       }
@@ -179,19 +174,9 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
       cmFunctionHelperCommand *f = new cmFunctionHelperCommand();
       f->Args = this->Args;
       f->Functions = this->Functions;
+      f->FilePath = this->GetStartingContext().FilePath;
       mf.RecordPolicies(f->Policies);
 
-      // Set the FilePath on the arguments to match the function since it is
-      // not stored and the original values may be freed
-      for (unsigned int i = 0; i < f->Functions.size(); ++i)
-        {
-        for (unsigned int j = 0; j < f->Functions[i].Arguments.size(); ++j)
-          {
-          f->Functions[i].Arguments[j].FilePath =
-            f->Functions[i].FilePath.c_str();
-          }
-        }
-
       std::string newName = "_" + this->Args[0];
       mf.GetState()->RenameCommand(this->Args[0], newName);
       mf.GetState()->AddCommand(f);
@@ -220,7 +205,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
   if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction"))
     {
     std::vector<std::string> expandedArguments;
-    mf.ExpandArguments(lff.Arguments, expandedArguments);
+    mf.ExpandArguments(lff.Arguments, expandedArguments,
+                       this->GetStartingContext().FilePath.c_str());
     // if the endfunction has arguments then make sure
     // they match the ones in the opening function command
     if ((expandedArguments.empty() ||
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index 2aa6beb..8df3e1a 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -56,10 +56,10 @@ protected:
   // Whether the real file stream was valid when it was closed.
   bool Okay;
 
-  // Whether the destionation file is compressed
+  // Whether the destination file is compressed
   bool Compress;
 
-  // Whether the destionation file is compressed
+  // Whether the destination file is compressed
   bool CompressExtraExtension;
 };
 
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index a1c405b..80a4f81 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -23,7 +23,7 @@
 
 //----------------------------------------------------------------------------
 cmGeneratorExpression::cmGeneratorExpression(
-  cmListFileBacktrace const* backtrace):
+    const cmListFileBacktrace& backtrace):
   Backtrace(backtrace)
 {
 }
@@ -33,9 +33,7 @@ cmsys::auto_ptr<cmCompiledGeneratorExpression>
 cmGeneratorExpression::Parse(std::string const& input)
 {
   return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
-    new cmCompiledGeneratorExpression(
-      this->Backtrace ? *this->Backtrace : cmListFileBacktrace(NULL),
-      input));
+    new cmCompiledGeneratorExpression(this->Backtrace, input));
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 11c27fd..cd19bc0 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -42,7 +42,8 @@ class cmGeneratorExpression
 {
 public:
   /** Construct. */
-  cmGeneratorExpression(cmListFileBacktrace const* backtrace = NULL);
+  cmGeneratorExpression(
+      cmListFileBacktrace const& backtrace = cmListFileBacktrace());
   ~cmGeneratorExpression();
 
   cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(
@@ -71,7 +72,7 @@ private:
   cmGeneratorExpression(const cmGeneratorExpression &);
   void operator=(const cmGeneratorExpression &);
 
-  cmListFileBacktrace const* Backtrace;
+  cmListFileBacktrace Backtrace;
 };
 
 class cmCompiledGeneratorExpression
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index ff8790c..851aacd 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -35,7 +35,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
                 const GeneratorExpressionContent *content,
                 cmGeneratorExpressionDAGChecker *parent)
   : Parent(parent), Target(target), Property(property),
-    Content(content), Backtrace(NULL), TransitivePropertiesOnly(false)
+    Content(content), Backtrace(), TransitivePropertiesOnly(false)
 {
   Initialize();
 }
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index c726995..e4d9f10 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -25,19 +25,18 @@
 cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
         const std::string &input,
         cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
-        cmMakefile *makefile,
         cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
         bool inputIsContent)
   : Input(input),
     OutputFileExpr(outputFileExpr),
-    Makefile(makefile),
     Condition(condition),
     InputIsContent(inputIsContent)
 {
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
+void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg,
+              const std::string& config,
               const std::string& lang,
               cmCompiledGeneratorExpression* inputExpression,
               std::map<std::string, std::string> &outputFiles, mode_t perm)
@@ -45,7 +44,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
   std::string rawCondition = this->Condition->GetInput();
   if (!rawCondition.empty())
     {
-    std::string condResult = this->Condition->Evaluate(this->Makefile, config,
+    std::string condResult = this->Condition->Evaluate(lg->GetMakefile(),
+                                                       config,
                                                        false, 0, 0, 0, lang);
     if (condResult == "0")
       {
@@ -56,16 +56,17 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
       std::ostringstream e;
       e << "Evaluation file condition \"" << rawCondition << "\" did "
           "not evaluate to valid content. Got \"" << condResult << "\".";
-      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+      lg->IssueMessage(cmake::FATAL_ERROR, e.str());
       return;
       }
     }
 
   const std::string outputFileName
-                    = this->OutputFileExpr->Evaluate(this->Makefile, config,
+                    = this->OutputFileExpr->Evaluate(lg->GetMakefile(), config,
                                                      false, 0, 0, 0, lang);
   const std::string outputContent
-                          = inputExpression->Evaluate(this->Makefile, config,
+                          = inputExpression->Evaluate(lg->GetMakefile(),
+                                                      config,
                                                       false, 0, 0, 0, lang);
 
   std::map<std::string, std::string>::iterator it
@@ -81,11 +82,11 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
     e << "Evaluation file to be written multiple times for different "
          "configurations or languages with different content:\n  "
       << outputFileName;
-    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+    lg->IssueMessage(cmake::FATAL_ERROR, e.str());
     return;
     }
 
-  this->Makefile->AddCMakeOutputFile(outputFileName.c_str());
+  lg->GetMakefile()->AddCMakeOutputFile(outputFileName.c_str());
   this->Files.push_back(outputFileName);
   outputFiles[outputFileName] = outputContent;
 
@@ -100,18 +101,19 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
 
 //----------------------------------------------------------------------------
 void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
-                                              std::string const& config)
+    cmLocalGenerator *lg, std::string const& config)
 {
   std::vector<std::string> enabledLanguages;
-  cmGlobalGenerator *gg = this->Makefile->GetGlobalGenerator();
+  cmGlobalGenerator *gg = lg->GetGlobalGenerator();
   gg->GetEnabledLanguages(enabledLanguages);
 
   for(std::vector<std::string>::const_iterator le = enabledLanguages.begin();
       le != enabledLanguages.end(); ++le)
     {
-    std::string name = this->OutputFileExpr->Evaluate(this->Makefile, config,
+    std::string name = this->OutputFileExpr->Evaluate(lg->GetMakefile(),
+                                                      config,
                                                       false, 0, 0, 0, *le);
-    cmSourceFile* sf = this->Makefile->GetOrCreateSource(name);
+    cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource(name);
     sf->SetProperty("GENERATED", "1");
 
     gg->SetFilenameTargetDepends(sf,
@@ -120,7 +122,7 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorExpressionEvaluationFile::Generate()
+void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator *lg)
 {
   mode_t perm = 0;
   std::string inputContent;
@@ -130,14 +132,14 @@ void cmGeneratorExpressionEvaluationFile::Generate()
     }
   else
     {
-    this->Makefile->AddCMakeDependFile(this->Input.c_str());
+    lg->GetMakefile()->AddCMakeDependFile(this->Input.c_str());
     cmSystemTools::GetPermissions(this->Input.c_str(), perm);
     cmsys::ifstream fin(this->Input.c_str());
     if(!fin)
       {
       std::ostringstream e;
       e << "Evaluation file \"" << this->Input << "\" cannot be read.";
-      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+      lg->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
       return;
       }
 
@@ -152,14 +154,14 @@ void cmGeneratorExpressionEvaluationFile::Generate()
     }
 
   cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace();
-  cmGeneratorExpression contentGE(&lfbt);
+  cmGeneratorExpression contentGE(lfbt);
   cmsys::auto_ptr<cmCompiledGeneratorExpression> inputExpression
                                               = contentGE.Parse(inputContent);
 
   std::map<std::string, std::string> outputFiles;
 
   std::vector<std::string> allConfigs;
-  this->Makefile->GetConfigurations(allConfigs);
+  lg->GetMakefile()->GetConfigurations(allConfigs);
 
   if (allConfigs.empty())
     {
@@ -167,7 +169,7 @@ void cmGeneratorExpressionEvaluationFile::Generate()
     }
 
   std::vector<std::string> enabledLanguages;
-  cmGlobalGenerator *gg = this->Makefile->GetGlobalGenerator();
+  cmGlobalGenerator *gg = lg->GetGlobalGenerator();
   gg->GetEnabledLanguages(enabledLanguages);
 
   for(std::vector<std::string>::const_iterator le = enabledLanguages.begin();
@@ -176,7 +178,7 @@ void cmGeneratorExpressionEvaluationFile::Generate()
     for(std::vector<std::string>::const_iterator li = allConfigs.begin();
         li != allConfigs.end(); ++li)
       {
-      this->Generate(*li, *le, inputExpression.get(), outputFiles, perm);
+      this->Generate(lg, *li, *le, inputExpression.get(), outputFiles, perm);
       if(cmSystemTools::GetFatalErrorOccured())
         {
         return;
diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h
index 5d8b54c..ad41274 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.h
+++ b/Source/cmGeneratorExpressionEvaluationFile.h
@@ -18,31 +18,32 @@
 
 #include "cmGeneratorExpression.h"
 
+class cmLocalGenerator;
+
 //----------------------------------------------------------------------------
 class cmGeneratorExpressionEvaluationFile
 {
 public:
   cmGeneratorExpressionEvaluationFile(const std::string &input,
         cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
-        cmMakefile *makefile,
         cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
         bool inputIsContent);
 
-  void Generate();
+  void Generate(cmLocalGenerator* lg);
 
   std::vector<std::string> GetFiles() const { return this->Files; }
 
-  void CreateOutputFile(std::string const& config);
+  void CreateOutputFile(cmLocalGenerator* lg, std::string const& config);
 
 private:
-  void Generate(const std::string& config, const std::string& lang,
-              cmCompiledGeneratorExpression* inputExpression,
-              std::map<std::string, std::string> &outputFiles, mode_t perm);
+  void Generate(cmLocalGenerator* lg, const std::string& config,
+                const std::string& lang,
+                cmCompiledGeneratorExpression* inputExpression,
+                std::map<std::string, std::string> &outputFiles, mode_t perm);
 
 private:
   const std::string Input;
   const cmsys::auto_ptr<cmCompiledGeneratorExpression> OutputFileExpr;
-  cmMakefile *Makefile;
   const cmsys::auto_ptr<cmCompiledGeneratorExpression> Condition;
   std::vector<std::string> Files;
   const bool InputIsContent;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 293eb41..1c350ab 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -13,6 +13,7 @@
 #include "cmGeneratorExpressionNode.h"
 #include "cmGlobalGenerator.h"
 #include "cmAlgorithms.h"
+#include "cmOutputConverter.h"
 
 //----------------------------------------------------------------------------
 std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
@@ -21,7 +22,7 @@ std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
     cmTarget const* headTarget, cmTarget const* currentTarget,
     cmGeneratorExpressionDAGChecker *dagChecker)
 {
-  cmGeneratorExpression ge(&context->Backtrace);
+  cmGeneratorExpression ge(context->Backtrace);
   cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
   cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
   std::string result = cge->Evaluate(makefile,
@@ -990,6 +991,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
 
     assert(target);
 
+    cmGeneratorTarget* gtgt =
+        context->Makefile->GetGlobalGenerator()->GetGeneratorTarget(target);
+
     if (propertyName == "LINKER_LANGUAGE")
       {
       if (target->LinkLanguagePropagatesToDependents() &&
@@ -1001,7 +1005,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
             "link libraries for a static library");
         return std::string();
         }
-      return target->GetLinkerLanguage(context->Config);
+      return gtgt->GetLinkerLanguage(context->Config);
       }
 
     cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
@@ -1105,8 +1109,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
 
     if(isInterfaceProperty)
       {
-      if(cmTarget::LinkInterfaceLibraries const* iface =
-         target->GetLinkInterfaceLibraries(context->Config, headTarget, true))
+      if(cmLinkInterfaceLibraries const* iface =
+         gtgt->GetLinkInterfaceLibraries(context->Config, headTarget, true))
         {
         linkedTargetsContent =
           getLinkedTargetsContent(iface->Libraries, target,
@@ -1117,7 +1121,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
       }
     else if(!interfacePropertyName.empty())
       {
-      if(cmTarget::LinkImplementationLibraries const* impl =
+      if(cmLinkImplementationLibraries const* impl =
          target->GetLinkImplementationLibraries(context->Config))
         {
         linkedTargetsContent =
@@ -1135,40 +1139,40 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
         {
         return linkedTargetsContent;
         }
-      if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
-                                                       context->Config))
+      if (gtgt->IsLinkInterfaceDependentBoolProperty(propertyName,
+                                                     context->Config))
         {
         context->HadContextSensitiveCondition = true;
-        return target->GetLinkInterfaceDependentBoolProperty(
+        return gtgt->GetLinkInterfaceDependentBoolProperty(
                                                 propertyName,
                                                 context->Config) ? "1" : "0";
         }
-      if (target->IsLinkInterfaceDependentStringProperty(propertyName,
-                                                         context->Config))
+      if (gtgt->IsLinkInterfaceDependentStringProperty(propertyName,
+                                                       context->Config))
         {
         context->HadContextSensitiveCondition = true;
         const char *propContent =
-                              target->GetLinkInterfaceDependentStringProperty(
+                              gtgt->GetLinkInterfaceDependentStringProperty(
                                                 propertyName,
                                                 context->Config);
         return propContent ? propContent : "";
         }
-      if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
-                                                         context->Config))
+      if (gtgt->IsLinkInterfaceDependentNumberMinProperty(propertyName,
+                                                          context->Config))
         {
         context->HadContextSensitiveCondition = true;
         const char *propContent =
-                          target->GetLinkInterfaceDependentNumberMinProperty(
+                          gtgt->GetLinkInterfaceDependentNumberMinProperty(
                                                 propertyName,
                                                 context->Config);
         return propContent ? propContent : "";
         }
-      if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
-                                                         context->Config))
+      if (gtgt->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
+                                                          context->Config))
         {
         context->HadContextSensitiveCondition = true;
         const char *propContent =
-                          target->GetLinkInterfaceDependentNumberMaxProperty(
+                          gtgt->GetLinkInterfaceDependentNumberMaxProperty(
                                                 propertyName,
                                                 context->Config);
         return propContent ? propContent : "";
@@ -1180,22 +1184,22 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
     if (!target->IsImported()
         && dagCheckerParent && !dagCheckerParent->EvaluatingLinkLibraries())
       {
-      if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
-                                                        context->Config))
+      if (gtgt->IsLinkInterfaceDependentNumberMinProperty(propertyName,
+                                                          context->Config))
         {
         context->HadContextSensitiveCondition = true;
         const char *propContent =
-                            target->GetLinkInterfaceDependentNumberMinProperty(
+                            gtgt->GetLinkInterfaceDependentNumberMinProperty(
                                                 propertyName,
                                                 context->Config);
         return propContent ? propContent : "";
         }
-      if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
-                                                        context->Config))
+      if (gtgt->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
+                                                          context->Config))
         {
         context->HadContextSensitiveCondition = true;
         const char *propContent =
-                            target->GetLinkInterfaceDependentNumberMaxProperty(
+                            gtgt->GetLinkInterfaceDependentNumberMaxProperty(
                                                 propertyName,
                                                 context->Config);
         return propContent ? propContent : "";
@@ -1369,8 +1373,6 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
 
     bool evalLL = dagChecker && dagChecker->EvaluatingLinkLibraries();
 
-    std::string result;
-
     for (LangMap::const_iterator lit = testedFeatures.begin();
           lit != testedFeatures.end(); ++lit)
       {
@@ -1556,7 +1558,7 @@ class ArtifactDirTag;
 template<typename ArtifactT>
 struct TargetFilesystemArtifactResultCreator
 {
-  static std::string Create(cmTarget* target,
+  static std::string Create(cmGeneratorTarget* target,
                             cmGeneratorExpressionContext *context,
                             const GeneratorExpressionContent *content);
 };
@@ -1565,12 +1567,12 @@ struct TargetFilesystemArtifactResultCreator
 template<>
 struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
 {
-  static std::string Create(cmTarget* target,
+  static std::string Create(cmGeneratorTarget* target,
                             cmGeneratorExpressionContext *context,
                             const GeneratorExpressionContent *content)
   {
     // The target soname file (.so.1).
-    if(target->IsDLLPlatform())
+    if(target->Target->IsDLLPlatform())
       {
       ::reportError(context, content->GetOriginalExpression(),
                     "TARGET_SONAME_FILE is not allowed "
@@ -1584,7 +1586,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
                     "SHARED libraries.");
       return std::string();
       }
-    std::string result = target->GetDirectory(context->Config);
+    std::string result = target->Target->GetDirectory(context->Config);
     result += "/";
     result += target->GetSOName(context->Config);
     return result;
@@ -1595,10 +1597,17 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
 template<>
 struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
 {
-  static std::string Create(cmTarget* target,
+  static std::string Create(cmGeneratorTarget* target,
                             cmGeneratorExpressionContext *context,
                             const GeneratorExpressionContent *content)
   {
+    if (target->IsImported())
+      {
+      ::reportError(context, content->GetOriginalExpression(),
+                    "TARGET_PDB_FILE not allowed for IMPORTED targets.");
+      return std::string();
+      }
+
     std::string language = target->GetLinkerLanguage(context->Config);
 
     std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";
@@ -1610,7 +1619,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
       return std::string();
       }
 
-    cmTarget::TargetType targetType = target->GetType();
+    cmTarget::TargetType targetType = target->Target->GetType();
 
     if(targetType != cmTarget::SHARED_LIBRARY &&
        targetType != cmTarget::MODULE_LIBRARY &&
@@ -1622,7 +1631,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
       return std::string();
       }
 
-    std::string result = target->GetPDBDirectory(context->Config);
+    std::string result = target->Target->GetPDBDirectory(context->Config);
     result += "/";
     result += target->GetPDBName(context->Config);
     return result;
@@ -1633,12 +1642,12 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
 template<>
 struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
 {
-  static std::string Create(cmTarget* target,
+  static std::string Create(cmGeneratorTarget* target,
                             cmGeneratorExpressionContext *context,
                             const GeneratorExpressionContent *content)
   {
     // The file used to link to the target (.so, .lib, .a).
-    if(!target->IsLinkable())
+    if(!target->Target->IsLinkable())
       {
       ::reportError(context, content->GetOriginalExpression(),
                     "TARGET_LINKER_FILE is allowed only for libraries and "
@@ -1646,7 +1655,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
       return std::string();
       }
     return target->GetFullPath(context->Config,
-                               target->HasImportLibrary());
+                               target->Target->HasImportLibrary());
   }
 };
 
@@ -1654,7 +1663,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
 template<>
 struct TargetFilesystemArtifactResultCreator<ArtifactNameTag>
 {
-  static std::string Create(cmTarget* target,
+  static std::string Create(cmGeneratorTarget* target,
                             cmGeneratorExpressionContext *context,
                             const GeneratorExpressionContent *)
   {
@@ -1716,7 +1725,8 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
                     "Expression syntax not recognized.");
       return std::string();
       }
-    cmTarget* target = context->Makefile->FindTargetToUse(name);
+    cmGeneratorTarget* target =
+        context->Makefile->FindGeneratorTargetToUse(name);
     if(!target)
       {
       ::reportError(context, content->GetOriginalExpression(),
@@ -1739,8 +1749,8 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
                     "be used while evaluating link libraries");
       return std::string();
       }
-    context->DependTargets.insert(target);
-    context->AllTargets.insert(target);
+    context->DependTargets.insert(target->Target);
+    context->AllTargets.insert(target->Target);
 
     std::string result =
                 TargetFilesystemArtifactResultCreator<ArtifactT>::Create(
@@ -1783,6 +1793,27 @@ static const
 TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup;
 
 //----------------------------------------------------------------------------
+static const struct ShellPathNode : public cmGeneratorExpressionNode
+{
+  ShellPathNode() {}
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *context,
+                       const GeneratorExpressionContent *content,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    if (!cmSystemTools::FileIsFullPath(parameters.front()))
+      {
+      reportError(context, content->GetOriginalExpression(),
+                  "\"" + parameters.front() + "\" is not an absolute path.");
+      return std::string();
+      }
+    cmOutputConverter converter(context->Makefile->GetStateSnapshot());
+    return converter.ConvertDirectorySeparatorsForShell(parameters.front());
+  }
+} shellPathNode;
+
+//----------------------------------------------------------------------------
 const cmGeneratorExpressionNode*
 cmGeneratorExpressionNode::GetNode(const std::string &identifier)
 {
@@ -1837,6 +1868,7 @@ cmGeneratorExpressionNode::GetNode(const std::string &identifier)
     nodeMap["JOIN"] = &joinNode;
     nodeMap["LINK_ONLY"] = &linkOnlyNode;
     nodeMap["COMPILE_LANGUAGE"] = &languageNode;
+    nodeMap["SHELL_PATH"] = &shellPathNode;
     }
   NodeMap::const_iterator i = nodeMap.find(identifier);
   if (i == nodeMap.end())
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index e2b8c45..62598f4 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -24,11 +24,31 @@
 
 #include <queue>
 
+#include <errno.h>
 #include "assert.h"
 
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include <cmsys/hash_set.hxx>
+#define UNORDERED_SET cmsys::hash_set
+#else
+#define UNORDERED_SET std::set
+#endif
+
+class cmGeneratorTarget::TargetPropertyEntry {
+  static cmLinkImplItem NoLinkImplItem;
+public:
+  TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
+                      cmLinkImplItem const& item = NoLinkImplItem)
+    : ge(cge), LinkImplItem(item)
+  {}
+  const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
+  cmLinkImplItem const& LinkImplItem;
+};
+cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem;
+
 //----------------------------------------------------------------------------
 void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
-                     cmTarget *target, cmake *cm)
+                     cmGeneratorTarget const* target, cmake *cm)
 {
   if(!badObjLib.empty())
     {
@@ -42,7 +62,7 @@ void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
     e << "but may contain only sources that compile, header files, and "
          "other files that would not affect linking of a normal library.";
     cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
-                     target->GetBacktrace());
+                     target->Target->GetBacktrace());
     }
 }
 
@@ -55,6 +75,7 @@ struct IDLSourcesTag {};
 struct ResxTag {};
 struct ModuleDefinitionFileTag {};
 struct AppManifestTag{};
+struct ManifestsTag{};
 struct CertificatesTag{};
 struct XamlTag{};
 
@@ -125,14 +146,14 @@ struct TagVisitor
 {
   DataType& Data;
   std::vector<cmSourceFile*> BadObjLibFiles;
-  cmTarget *Target;
+  cmGeneratorTarget const* Target;
   cmGlobalGenerator *GlobalGenerator;
   cmsys::RegularExpression Header;
   bool IsObjLib;
 
-  TagVisitor(cmTarget *target, DataType& data)
+  TagVisitor(cmGeneratorTarget const* target, DataType& data)
     : Data(data), Target(target),
-    GlobalGenerator(target->GetMakefile()->GetGlobalGenerator()),
+    GlobalGenerator(target->GetLocalGenerator()->GetGlobalGenerator()),
     Header(CM_HEADER_REGEX),
     IsObjLib(target->GetType() == cmTarget::OBJECT_LIBRARY)
   {
@@ -196,6 +217,10 @@ struct TagVisitor
       {
       DoAccept<IsSameTag<Tag, AppManifestTag>::Result>::Do(this->Data, sf);
       }
+    else if (ext == "manifest")
+      {
+      DoAccept<IsSameTag<Tag, ManifestsTag>::Result>::Do(this->Data, sf);
+      }
     else if (ext == "pfx")
       {
       DoAccept<IsSameTag<Tag, CertificatesTag>::Result>::Do(this->Data, sf);
@@ -219,13 +244,73 @@ struct TagVisitor
   }
 };
 
+void CreatePropertyGeneratorExpressions(
+    cmStringRange const& entries,
+    cmBacktraceRange const& backtraces,
+    std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items,
+    bool evaluateForBuildsystem = false)
+{
+  std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin();
+  for (std::vector<std::string>::const_iterator it = entries.begin();
+       it != entries.end(); ++it, ++btIt)
+    {
+    cmGeneratorExpression ge(*btIt);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*it);
+    cge->SetEvaluateForBuildsystem(evaluateForBuildsystem);
+    items.push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+    }
+}
+
 //----------------------------------------------------------------------------
-cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t),
-  SourceFileFlagsConstructed(false)
+cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
+  : Target(t),
+  SourceFileFlagsConstructed(false),
+  PolicyWarnedCMP0022(false),
+  DebugIncludesDone(false),
+  DebugCompileOptionsDone(false),
+  DebugCompileFeaturesDone(false),
+  DebugCompileDefinitionsDone(false)
 {
   this->Makefile = this->Target->GetMakefile();
-  this->LocalGenerator = this->Makefile->GetLocalGenerator();
-  this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
+  this->LocalGenerator = lg;
+  this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
+
+  this->GlobalGenerator->ComputeTargetObjectDirectory(this);
+
+  CreatePropertyGeneratorExpressions(
+        t->GetIncludeDirectoriesEntries(),
+        t->GetIncludeDirectoriesBacktraces(),
+        this->IncludeDirectoriesEntries);
+
+  CreatePropertyGeneratorExpressions(
+        t->GetCompileOptionsEntries(),
+        t->GetCompileOptionsBacktraces(),
+        this->CompileOptionsEntries);
+
+  CreatePropertyGeneratorExpressions(
+        t->GetCompileFeaturesEntries(),
+        t->GetCompileFeaturesBacktraces(),
+        this->CompileFeaturesEntries);
+
+  CreatePropertyGeneratorExpressions(
+        t->GetCompileDefinitionsEntries(),
+        t->GetCompileDefinitionsBacktraces(),
+        this->CompileDefinitionsEntries);
+}
+
+cmGeneratorTarget::~cmGeneratorTarget()
+{
+  cmDeleteAll(this->IncludeDirectoriesEntries);
+  cmDeleteAll(this->CompileOptionsEntries);
+  cmDeleteAll(this->CompileFeaturesEntries);
+  cmDeleteAll(this->CompileDefinitionsEntries);
+  cmDeleteAll(this->LinkInformation);
+  this->LinkInformation.clear();
+}
+
+cmLocalGenerator* cmGeneratorTarget::GetLocalGenerator() const
+{
+  return this->LocalGenerator;
 }
 
 //----------------------------------------------------------------------------
@@ -247,6 +332,77 @@ const char *cmGeneratorTarget::GetProperty(const std::string& prop) const
 }
 
 //----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetOutputName(const std::string& config,
+                                             bool implib) const
+{
+  // Lookup/compute/cache the output name for this configuration.
+  OutputNameKey key(config, implib);
+  cmGeneratorTarget::OutputNameMapType::iterator i =
+    this->OutputNameMap.find(key);
+  if(i == this->OutputNameMap.end())
+    {
+    // Add empty name in map to detect potential recursion.
+    OutputNameMapType::value_type entry(key, "");
+    i = this->OutputNameMap.insert(entry).first;
+
+    // Compute output name.
+    std::vector<std::string> props;
+    std::string type = this->Target->GetOutputTargetType(implib);
+    std::string configUpper = cmSystemTools::UpperCase(config);
+    if(!type.empty() && !configUpper.empty())
+      {
+      // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG>
+      props.push_back(type + "_OUTPUT_NAME_" + configUpper);
+      }
+    if(!type.empty())
+      {
+      // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME
+      props.push_back(type + "_OUTPUT_NAME");
+      }
+    if(!configUpper.empty())
+      {
+      // OUTPUT_NAME_<CONFIG>
+      props.push_back("OUTPUT_NAME_" + configUpper);
+      // <CONFIG>_OUTPUT_NAME
+      props.push_back(configUpper + "_OUTPUT_NAME");
+      }
+    // OUTPUT_NAME
+    props.push_back("OUTPUT_NAME");
+
+    std::string outName;
+    for(std::vector<std::string>::const_iterator it = props.begin();
+        it != props.end(); ++it)
+      {
+      if (const char* outNameProp = this->Target->GetProperty(*it))
+        {
+        outName = outNameProp;
+        break;
+        }
+      }
+
+    if(outName.empty())
+      {
+      outName = this->GetName();
+      }
+
+    // Now evaluate genex and update the previously-prepared map entry.
+    cmGeneratorExpression ge;
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName);
+    i->second = cge->Evaluate(this->Makefile, config);
+    }
+  else if(i->second.empty())
+    {
+    // An empty map entry indicates we have been called recursively
+    // from the above block.
+    this->Makefile->GetCMakeInstance()->IssueMessage(
+      cmake::FATAL_ERROR,
+      "Target '" + this->GetName() + "' OUTPUT_NAME depends on itself.",
+      this->Target->GetBacktrace());
+    }
+  return i->second;
+}
+
+//----------------------------------------------------------------------------
 std::vector<cmSourceFile*> const*
 cmGeneratorTarget::GetSourceDepends(cmSourceFile const* sf) const
 {
@@ -294,7 +450,7 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
   { \
   std::vector<cmSourceFile*> sourceFiles; \
   this->Target->GetSourceFiles(sourceFiles, config); \
-  TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \
+  TagVisitor<DATA ## Tag DATATYPE> visitor(this, data); \
   for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
       si != sourceFiles.end(); ++si) \
     { \
@@ -353,6 +509,34 @@ void cmGeneratorTarget::ComputeObjectMapping()
 }
 
 //----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetFeature(const std::string& feature,
+                                          const std::string& config) const
+{
+  if(!config.empty())
+    {
+    std::string featureConfig = feature;
+    featureConfig += "_";
+    featureConfig += cmSystemTools::UpperCase(config);
+    if(const char* value = this->Target->GetProperty(featureConfig))
+      {
+      return value;
+      }
+    }
+  if(const char* value = this->Target->GetProperty(feature))
+    {
+    return value;
+    }
+  return this->LocalGenerator->GetFeature(feature, config);
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetFeatureAsBool(const std::string& feature,
+                                         const std::string& config) const
+{
+  return cmSystemTools::IsOn(this->GetFeature(feature, config));
+}
+
+//----------------------------------------------------------------------------
 const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
 {
   this->ComputeObjectMapping();
@@ -449,6 +633,15 @@ cmGeneratorTarget
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget
+::GetManifests(std::vector<cmSourceFile const*>& data,
+               const std::string& config) const
+{
+  IMPLEMENT_VISIT(Manifests);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
 ::GetCertificates(std::vector<cmSourceFile const*>& data,
                   const std::string& config) const
 {
@@ -486,6 +679,61 @@ void cmGeneratorTarget
 }
 
 //----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetLocation(const std::string& config) const
+{
+  static std::string location;
+  if (this->Target->IsImported())
+    {
+    location = this->Target->ImportedGetFullPath(config, false);
+    }
+  else
+    {
+    location = this->GetFullPath(config, false);
+    }
+  return location.c_str();
+}
+
+bool cmGeneratorTarget::IsImported() const
+{
+  return this->Target->IsImported();
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetLocationForBuild() const
+{
+  static std::string location;
+  if(this->IsImported())
+    {
+    location = this->Target->ImportedGetFullPath("", false);
+    return location.c_str();
+    }
+
+  // Now handle the deprecated build-time configuration location.
+  location = this->Target->GetDirectory();
+  const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
+  if(cfgid && strcmp(cfgid, ".") != 0)
+    {
+    location += "/";
+    location += cfgid;
+    }
+
+  if(this->Target->IsAppBundleOnApple())
+    {
+    std::string macdir = this->BuildMacContentDirectory("", "",
+                                                                false);
+    if(!macdir.empty())
+      {
+      location += "/";
+      location += macdir;
+      }
+    }
+  location += "/";
+  location += this->GetFullName("", false);
+  return location.c_str();
+}
+
+
+//----------------------------------------------------------------------------
 bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
                                               const std::string& config) const
 {
@@ -522,7 +770,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
       }
 
     std::vector<cmTarget const*> const& deps =
-      this->Target->GetLinkImplementationClosure(config);
+      this->GetLinkImplementationClosure(config);
     for(std::vector<cmTarget const*>::const_iterator
           li = deps.begin(), le = deps.end(); li != le; ++li)
       {
@@ -562,636 +810,3760 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
 
 //----------------------------------------------------------------------------
 std::string
-cmGeneratorTarget::GetModuleDefinitionFile(const std::string& config) const
+cmGeneratorTarget::GetCompilePDBName(const std::string& config) const
 {
-  std::string data;
-  IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
-  return data;
+  std::string prefix;
+  std::string base;
+  std::string suffix;
+  this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+  // Check for a per-configuration output directory target property.
+  std::string configUpper = cmSystemTools::UpperCase(config);
+  std::string configProp = "COMPILE_PDB_NAME_";
+  configProp += configUpper;
+  const char* config_name = this->Target->GetProperty(configProp);
+  if(config_name && *config_name)
+    {
+    return prefix + config_name + ".pdb";
+    }
+
+  const char* name = this->Target->GetProperty("COMPILE_PDB_NAME");
+  if(name && *name)
+    {
+    return prefix + name + ".pdb";
+    }
+
+  return "";
 }
 
 //----------------------------------------------------------------------------
-void
-cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs,
-                                      const std::string &config) const
+std::string
+cmGeneratorTarget::GetCompilePDBPath(const std::string& config) const
 {
-  std::vector<cmSourceFile const*> objectFiles;
-  this->GetExternalObjects(objectFiles, config);
-  std::vector<cmTarget*> objectLibraries;
-  for(std::vector<cmSourceFile const*>::const_iterator
-      it = objectFiles.begin(); it != objectFiles.end(); ++it)
+  std::string dir = this->GetCompilePDBDirectory(config);
+  std::string name = this->GetCompilePDBName(config);
+  if(dir.empty() && !name.empty())
     {
-    std::string objLib = (*it)->GetObjectLibrary();
-    if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
-      {
-      objectLibraries.push_back(tgt);
-      }
+    dir = this->Target->GetPDBDirectory(config);
+    }
+  if(!dir.empty())
+    {
+    dir += "/";
     }
+  return dir + name;
+}
 
-  std::vector<cmTarget*>::const_iterator end
-      = cmRemoveDuplicates(objectLibraries);
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasSOName(const std::string& config) const
+{
+  // soname is supported only for shared libraries and modules,
+  // and then only when the platform supports an soname flag.
+  return ((this->GetType() == cmTarget::SHARED_LIBRARY) &&
+          !this->GetPropertyAsBool("NO_SONAME") &&
+          this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
+}
 
-  for(std::vector<cmTarget*>::const_iterator
-        ti = objectLibraries.begin();
-      ti != end; ++ti)
+//----------------------------------------------------------------------------
+bool
+cmGeneratorTarget::NeedRelinkBeforeInstall(const std::string& config) const
+{
+  // Only executables and shared libraries can have an rpath and may
+  // need relinking.
+  if(this->GetType() != cmTarget::EXECUTABLE &&
+     this->GetType() != cmTarget::SHARED_LIBRARY &&
+     this->GetType() != cmTarget::MODULE_LIBRARY)
     {
-    cmTarget* objLib = *ti;
-    cmGeneratorTarget* ogt =
-      this->GlobalGenerator->GetGeneratorTarget(objLib);
-    std::vector<cmSourceFile const*> objectSources;
-    ogt->GetObjectSources(objectSources, config);
-    for(std::vector<cmSourceFile const*>::const_iterator
-          si = objectSources.begin();
-        si != objectSources.end(); ++si)
+    return false;
+    }
+
+  // If there is no install location this target will not be installed
+  // and therefore does not need relinking.
+  if(!this->Target->GetHaveInstallRule())
+    {
+    return false;
+    }
+
+  // If skipping all rpaths completely then no relinking is needed.
+  if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
+    {
+    return false;
+    }
+
+  // If building with the install-tree rpath no relinking is needed.
+  if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
+    {
+    return false;
+    }
+
+  // If chrpath is going to be used no relinking is needed.
+  if(this->IsChrpathUsed(config))
+    {
+    return false;
+    }
+
+  // Check for rpath support on this platform.
+  std::string ll = this->GetLinkerLanguage(config);
+  if(!ll.empty())
+    {
+    std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+    flagVar += ll;
+    flagVar += "_FLAG";
+    if(!this->Makefile->IsSet(flagVar))
       {
-      std::string obj = ogt->ObjectDirectory;
-      obj += ogt->Objects[*si];
-      objs.push_back(obj);
+      // There is no rpath support on this platform so nothing needs
+      // relinking.
+      return false;
       }
     }
+  else
+    {
+    // No linker language is known.  This error will be reported by
+    // other code.
+    return false;
+    }
+
+  // If either a build or install tree rpath is set then the rpath
+  // will likely change between the build tree and install tree and
+  // this target must be relinked.
+  return this->HaveBuildTreeRPATH(config)
+      || this->Target->HaveInstallTreeRPATH();
 }
 
 //----------------------------------------------------------------------------
-class cmTargetTraceDependencies
+bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
 {
-public:
-  cmTargetTraceDependencies(cmGeneratorTarget* target);
-  void Trace();
-private:
-  cmTarget* Target;
-  cmGeneratorTarget* GeneratorTarget;
-  cmMakefile* Makefile;
-  cmGlobalGenerator const* GlobalGenerator;
-  typedef cmGeneratorTarget::SourceEntry SourceEntry;
-  SourceEntry* CurrentEntry;
-  std::queue<cmSourceFile*> SourceQueue;
-  std::set<cmSourceFile*> SourcesQueued;
-  typedef std::map<std::string, cmSourceFile*> NameMapType;
-  NameMapType NameMap;
-  std::vector<std::string> NewSources;
+  // Only certain target types have an rpath.
+  if(!(this->GetType() == cmTarget::SHARED_LIBRARY ||
+       this->GetType() == cmTarget::MODULE_LIBRARY ||
+       this->GetType() == cmTarget::EXECUTABLE))
+    {
+    return false;
+    }
 
-  void QueueSource(cmSourceFile* sf);
-  void FollowName(std::string const& name);
-  void FollowNames(std::vector<std::string> const& names);
-  bool IsUtility(std::string const& dep);
-  void CheckCustomCommand(cmCustomCommand const& cc);
-  void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
-  void FollowCommandDepends(cmCustomCommand const& cc,
-                            const std::string& config,
-                            std::set<std::string>& emitted);
-};
+  // If the target will not be installed we do not need to change its
+  // rpath.
+  if(!this->Target->GetHaveInstallRule())
+    {
+    return false;
+    }
 
-//----------------------------------------------------------------------------
-cmTargetTraceDependencies
-::cmTargetTraceDependencies(cmGeneratorTarget* target):
-  Target(target->Target), GeneratorTarget(target)
-{
-  // Convenience.
-  this->Makefile = this->Target->GetMakefile();
-  this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
-  this->CurrentEntry = 0;
+  // Skip chrpath if skipping rpath altogether.
+  if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
+    {
+    return false;
+    }
 
-  // Queue all the source files already specified for the target.
-  if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
+  // Skip chrpath if it does not need to be changed at install time.
+  if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
     {
-    std::vector<std::string> configs;
-    this->Makefile->GetConfigurations(configs);
-    if (configs.empty())
-      {
-      configs.push_back("");
-      }
-    std::set<cmSourceFile*> emitted;
-    for(std::vector<std::string>::const_iterator ci = configs.begin();
-        ci != configs.end(); ++ci)
+    return false;
+    }
+
+  // Allow the user to disable builtin chrpath explicitly.
+  if(this->Makefile->IsOn("CMAKE_NO_BUILTIN_CHRPATH"))
+    {
+    return false;
+    }
+
+  if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+    {
+    return true;
+    }
+
+#if defined(CMAKE_USE_ELF_PARSER)
+  // Enable if the rpath flag uses a separator and the target uses ELF
+  // binaries.
+  std::string ll = this->GetLinkerLanguage(config);
+  if(!ll.empty())
+    {
+    std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+    sepVar += ll;
+    sepVar += "_FLAG_SEP";
+    const char* sep = this->Makefile->GetDefinition(sepVar);
+    if(sep && *sep)
       {
-      std::vector<cmSourceFile*> sources;
-      this->Target->GetSourceFiles(sources, *ci);
-      for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
-          si != sources.end(); ++si)
+      // TODO: Add ELF check to ABI detection and get rid of
+      // CMAKE_EXECUTABLE_FORMAT.
+      if(const char* fmt =
+         this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT"))
         {
-        cmSourceFile* sf = *si;
-        const std::set<cmTarget const*> tgts =
-                          this->GlobalGenerator->GetFilenameTargetDepends(sf);
-        if (tgts.find(this->Target) != tgts.end())
-          {
-          std::ostringstream e;
-          e << "Evaluation output file\n  \"" << sf->GetFullPath()
-            << "\"\ndepends on the sources of a target it is used in.  This "
-              "is a dependency loop and is not allowed.";
-          this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-          return;
-          }
-        if(emitted.insert(sf).second && this->SourcesQueued.insert(sf).second)
-          {
-          this->SourceQueue.push(sf);
-          }
+        return strcmp(fmt, "ELF") == 0;
         }
       }
     }
-
-  // Queue pre-build, pre-link, and post-build rule dependencies.
-  this->CheckCustomCommands(this->Target->GetPreBuildCommands());
-  this->CheckCustomCommands(this->Target->GetPreLinkCommands());
-  this->CheckCustomCommands(this->Target->GetPostBuildCommands());
+#endif
+  static_cast<void>(config);
+  return false;
 }
 
+
 //----------------------------------------------------------------------------
-void cmTargetTraceDependencies::Trace()
+std::string cmGeneratorTarget::GetSOName(const std::string& config) const
 {
-  // Process one dependency at a time until the queue is empty.
-  while(!this->SourceQueue.empty())
+  if(this->Target->IsImported())
     {
-    // Get the next source from the queue.
-    cmSourceFile* sf = this->SourceQueue.front();
-    this->SourceQueue.pop();
-    this->CurrentEntry = &this->GeneratorTarget->SourceEntries[sf];
-
-    // Queue dependencies added explicitly by the user.
-    if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
+    // Lookup the imported soname.
+    if(cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config))
       {
-      std::vector<std::string> objDeps;
-      cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
-      for(std::vector<std::string>::iterator odi = objDeps.begin();
-          odi != objDeps.end(); ++odi)
+      if(info->NoSOName)
         {
-        if (cmSystemTools::FileIsFullPath(*odi))
+        // The imported library has no builtin soname so the name
+        // searched at runtime will be just the filename.
+        return cmSystemTools::GetFilenameName(info->Location);
+        }
+      else
+        {
+        // Use the soname given if any.
+        if(info->SOName.find("@rpath/") == 0)
           {
-          *odi = cmSystemTools::CollapseFullPath(*odi);
+          return info->SOName.substr(6);
           }
+        return info->SOName;
         }
-      this->FollowNames(objDeps);
       }
+    else
+      {
+      return "";
+      }
+    }
+  else
+    {
+    // Compute the soname that will be built.
+    std::string name;
+    std::string soName;
+    std::string realName;
+    std::string impName;
+    std::string pdbName;
+    this->GetLibraryNames(name, soName, realName,
+                          impName, pdbName, config);
+    return soName;
+    }
+}
 
-    // Queue the source needed to generate this file, if any.
-    this->FollowName(sf->GetFullPath());
 
-    // Queue dependencies added programatically by commands.
-    this->FollowNames(sf->GetDepends());
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetAppBundleDirectory(const std::string& config,
+                                         bool contentOnly) const
+{
+  std::string fpath = this->GetFullName(config, false);
+  fpath += ".app";
+  if(!this->Makefile->PlatformIsAppleIos())
+    {
+    fpath += "/Contents";
+    if(!contentOnly)
+      fpath += "/MacOS";
+    }
+  return fpath;
+}
 
-    // Queue custom command dependencies.
-    if(cmCustomCommand const* cc = sf->GetCustomCommand())
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsBundleOnApple() const
+{
+  return this->Target->IsFrameworkOnApple()
+      || this->Target->IsAppBundleOnApple()
+      || this->Target->IsCFBundleOnApple();
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetCFBundleDirectory(const std::string& config,
+                                                    bool contentOnly) const
+{
+  std::string fpath;
+  fpath += this->GetOutputName(config, false);
+  fpath += ".";
+  const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION");
+  if (!ext)
+    {
+    if (this->Target->IsXCTestOnApple())
       {
-      this->CheckCustomCommand(*cc);
+      ext = "xctest";
+      }
+    else
+      {
+      ext = "bundle";
       }
     }
-  this->CurrentEntry = 0;
-
-  this->Target->AddTracedSources(this->NewSources);
+  fpath += ext;
+  if(!this->Makefile->PlatformIsAppleIos())
+  {
+    fpath += "/Contents";
+    if(!contentOnly)
+      fpath += "/MacOS";
+  }
+  return fpath;
 }
 
 //----------------------------------------------------------------------------
-void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
+std::string
+cmGeneratorTarget::GetFrameworkDirectory(const std::string& config,
+                                         bool rootDir) const
 {
-  if(this->SourcesQueued.insert(sf).second)
+  std::string fpath;
+  fpath += this->GetOutputName(config, false);
+  fpath += ".framework";
+  if(!rootDir && !this->Makefile->PlatformIsAppleIos())
     {
-    this->SourceQueue.push(sf);
-
-    // Make sure this file is in the target at the end.
-    this->NewSources.push_back(sf->GetFullPath());
+    fpath += "/Versions/";
+    fpath += this->Target->GetFrameworkVersion();
     }
+  return fpath;
 }
 
 //----------------------------------------------------------------------------
-void cmTargetTraceDependencies::FollowName(std::string const& name)
+std::string
+cmGeneratorTarget::GetFullName(const std::string& config, bool implib) const
 {
-  NameMapType::iterator i = this->NameMap.find(name);
-  if(i == this->NameMap.end())
+  if(this->Target->IsImported())
     {
-    // Check if we know how to generate this file.
-    cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name);
-    NameMapType::value_type entry(name, sf);
-    i = this->NameMap.insert(entry).first;
+    return this->Target->GetFullNameImported(config, implib);
     }
-  if(cmSourceFile* sf = i->second)
+  else
     {
-    // Record the dependency we just followed.
-    if(this->CurrentEntry)
-      {
-      this->CurrentEntry->Depends.push_back(sf);
-      }
-    this->QueueSource(sf);
+    return this->GetFullNameInternal(config, implib);
     }
 }
 
 //----------------------------------------------------------------------------
-void
-cmTargetTraceDependencies::FollowNames(std::vector<std::string> const& names)
+std::string
+cmGeneratorTarget::GetInstallNameDirForBuildTree(
+                                            const std::string& config) const
 {
-  for(std::vector<std::string>::const_iterator i = names.begin();
-      i != names.end(); ++i)
+  // If building directly for installation then the build tree install_name
+  // is the same as the install tree.
+  if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
     {
-    this->FollowName(*i);
+    return this->GetInstallNameDirForInstallTree();
+    }
+
+  // Use the build tree directory for the target.
+  if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
+     !this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
+     !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
+    {
+    std::string dir;
+    if(this->Target->MacOSXRpathInstallNameDirDefault())
+      {
+      dir = "@rpath";
+      }
+    else
+      {
+      dir = this->Target->GetDirectory(config);
+      }
+    dir += "/";
+    return dir;
+    }
+  else
+    {
+    return "";
     }
 }
 
 //----------------------------------------------------------------------------
-bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
+std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
 {
-  // Dependencies on targets (utilities) are supposed to be named by
-  // just the target name.  However for compatibility we support
-  // naming the output file generated by the target (assuming there is
-  // no output-name property which old code would not have set).  In
-  // that case the target name will be the file basename of the
-  // dependency.
-  std::string util = cmSystemTools::GetFilenameName(dep);
-  if(cmSystemTools::GetFilenameLastExtension(util) == ".exe")
+  if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
     {
-    util = cmSystemTools::GetFilenameWithoutLastExtension(util);
-    }
+    std::string dir;
+    const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
 
-  // Check for a target with this name.
-  if(cmTarget* t = this->Makefile->FindTargetToUse(util))
-    {
-    // If we find the target and the dep was given as a full path,
-    // then make sure it was not a full path to something else, and
-    // the fact that the name matched a target was just a coincidence.
-    if(cmSystemTools::FileIsFullPath(dep.c_str()))
+    if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
+       !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"))
       {
-      if(t->GetType() >= cmTarget::EXECUTABLE &&
-         t->GetType() <= cmTarget::MODULE_LIBRARY)
+      if(install_name_dir && *install_name_dir)
         {
-        // This is really only for compatibility so we do not need to
-        // worry about configuration names and output names.
-        std::string tLocation = t->GetLocationForBuild();
-        tLocation = cmSystemTools::GetFilenamePath(tLocation);
-        std::string depLocation = cmSystemTools::GetFilenamePath(dep);
-        depLocation = cmSystemTools::CollapseFullPath(depLocation);
-        tLocation = cmSystemTools::CollapseFullPath(tLocation);
-        if(depLocation == tLocation)
-          {
-          this->Target->AddUtility(util);
-          return true;
-          }
+        dir = install_name_dir;
+        dir += "/";
         }
       }
-    else
+    if(!install_name_dir)
       {
-      // The original name of the dependency was not a full path.  It
-      // must name a target, so add the target-level dependency.
-      this->Target->AddUtility(util);
-      return true;
+      if(this->Target->MacOSXRpathInstallNameDirDefault())
+        {
+        dir = "@rpath/";
+        }
       }
+    return dir;
+    }
+  else
+    {
+    return "";
     }
-
-  // The dependency does not name a target built in this project.
-  return false;
 }
 
 //----------------------------------------------------------------------------
-void
-cmTargetTraceDependencies
-::CheckCustomCommand(cmCustomCommand const& cc)
+class cmTargetCollectLinkLanguages
 {
-  // Transform command names that reference targets built in this
-  // project to corresponding target-level dependencies.
-  cmGeneratorExpression ge(&cc.GetBacktrace());
-
-  // Add target-level dependencies referenced by generator expressions.
-  std::set<cmTarget*> targets;
+public:
+  cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
+                               const std::string& config,
+                               UNORDERED_SET<std::string>& languages,
+                               cmTarget const* head):
+    Config(config), Languages(languages), HeadTarget(head),
+    Makefile(target->Target->GetMakefile()), Target(target)
+  { this->Visited.insert(target->Target); }
 
-  for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
-      cit != cc.GetCommandLines().end(); ++cit)
+  void Visit(cmLinkItem const& item)
     {
-    std::string const& command = *cit->begin();
-    // Check for a target with this name.
-    if(cmTarget* t = this->Makefile->FindTargetToUse(command))
+    if(!item.Target)
       {
-      if(t->GetType() == cmTarget::EXECUTABLE)
+      if(item.find("::") != std::string::npos)
         {
-        // The command refers to an executable target built in
-        // this project.  Add the target-level dependency to make
-        // sure the executable is up to date before this custom
-        // command possibly runs.
-        this->Target->AddUtility(command);
+        bool noMessage = false;
+        cmake::MessageType messageType = cmake::FATAL_ERROR;
+        std::stringstream e;
+        switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028))
+          {
+          case cmPolicies::WARN:
+            {
+            e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0028) << "\n";
+            messageType = cmake::AUTHOR_WARNING;
+            }
+            break;
+          case cmPolicies::OLD:
+            noMessage = true;
+          case cmPolicies::REQUIRED_IF_USED:
+          case cmPolicies::REQUIRED_ALWAYS:
+          case cmPolicies::NEW:
+            // Issue the fatal message.
+            break;
+          }
+
+        if(!noMessage)
+          {
+          e << "Target \"" << this->Target->GetName()
+            << "\" links to target \"" << item
+            << "\" but the target was not found.  Perhaps a find_package() "
+            "call is missing for an IMPORTED target, or an ALIAS target is "
+            "missing?";
+          this->Makefile->GetCMakeInstance()->IssueMessage(
+            messageType, e.str(), this->Target->Target->GetBacktrace());
+          }
         }
+      return;
+      }
+    if(!this->Visited.insert(item.Target).second)
+      {
+      return;
       }
+    cmGeneratorTarget* gtgt =
+        this->Target->GetLocalGenerator()->GetGlobalGenerator()
+            ->GetGeneratorTarget(item.Target);
+    cmLinkInterface const* iface =
+      gtgt->GetLinkInterface(this->Config, this->HeadTarget);
+    if(!iface) { return; }
 
-    // Check for target references in generator expressions.
-    for(cmCustomCommandLine::const_iterator cli = cit->begin();
-        cli != cit->end(); ++cli)
+    for(std::vector<std::string>::const_iterator
+          li = iface->Languages.begin(); li != iface->Languages.end(); ++li)
       {
-      const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
-                                                              = ge.Parse(*cli);
-      cge->Evaluate(this->Makefile, "", true);
-      std::set<cmTarget*> geTargets = cge->GetTargets();
-      targets.insert(geTargets.begin(), geTargets.end());
+      this->Languages.insert(*li);
+      }
+
+    for(std::vector<cmLinkItem>::const_iterator
+          li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
+      {
+      this->Visit(*li);
       }
     }
+private:
+  std::string Config;
+  UNORDERED_SET<std::string>& Languages;
+  cmTarget const* HeadTarget;
+  cmMakefile* Makefile;
+  const cmGeneratorTarget* Target;
+  std::set<cmTarget const*> Visited;
+};
 
-  for(std::set<cmTarget*>::iterator ti = targets.begin();
-      ti != targets.end(); ++ti)
+//----------------------------------------------------------------------------
+cmGeneratorTarget::LinkClosure const*
+cmGeneratorTarget::GetLinkClosure(const std::string& config) const
+{
+  std::string key(cmSystemTools::UpperCase(config));
+  LinkClosureMapType::iterator
+    i = this->LinkClosureMap.find(key);
+  if(i == this->LinkClosureMap.end())
     {
-    this->Target->AddUtility((*ti)->GetName());
+    LinkClosure lc;
+    this->ComputeLinkClosure(config, lc);
+    LinkClosureMapType::value_type entry(key, lc);
+    i = this->LinkClosureMap.insert(entry).first;
     }
+  return &i->second;
+}
 
-  // Queue the custom command dependencies.
-  std::vector<std::string> configs;
-  std::set<std::string> emitted;
-  this->Makefile->GetConfigurations(configs);
-  if (configs.empty())
+//----------------------------------------------------------------------------
+class cmTargetSelectLinker
+{
+  int Preference;
+  cmGeneratorTarget const* Target;
+  cmMakefile* Makefile;
+  cmGlobalGenerator* GG;
+  std::set<std::string> Preferred;
+public:
+  cmTargetSelectLinker(cmGeneratorTarget const* target)
+      : Preference(0), Target(target)
     {
-    configs.push_back("");
+    this->Makefile = this->Target->Makefile;
+    this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator();
     }
-  for(std::vector<std::string>::const_iterator ci = configs.begin();
-      ci != configs.end(); ++ci)
+  void Consider(const char* lang)
     {
-    this->FollowCommandDepends(cc, *ci, emitted);
+    int preference = this->GG->GetLinkerPreference(lang);
+    if(preference > this->Preference)
+      {
+      this->Preference = preference;
+      this->Preferred.clear();
+      }
+    if(preference == this->Preference)
+      {
+      this->Preferred.insert(lang);
+      }
     }
-}
+  std::string Choose()
+    {
+    if(this->Preferred.empty())
+      {
+      return "";
+      }
+    else if(this->Preferred.size() > 1)
+      {
+      std::stringstream e;
+      e << "Target " << this->Target->GetName()
+        << " contains multiple languages with the highest linker preference"
+        << " (" << this->Preference << "):\n";
+      for(std::set<std::string>::const_iterator
+            li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
+        {
+        e << "  " << *li << "\n";
+        }
+      e << "Set the LINKER_LANGUAGE property for this target.";
+      cmake* cm = this->Makefile->GetCMakeInstance();
+      cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+                       this->Target->Target->GetBacktrace());
+      }
+    return *this->Preferred.begin();
+    }
+};
 
 //----------------------------------------------------------------------------
-void cmTargetTraceDependencies::FollowCommandDepends(cmCustomCommand const& cc,
-                                              const std::string& config,
-                                              std::set<std::string>& emitted)
+void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+                                           LinkClosure& lc) const
 {
-  cmCustomCommandGenerator ccg(cc, config, this->Makefile);
+  // Get languages built in this target.
+  UNORDERED_SET<std::string> languages;
+  cmLinkImplementation const* impl =
+                            this->GetLinkImplementation(config);
+  assert(impl);
+  for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
+      li != impl->Languages.end(); ++li)
+    {
+    languages.insert(*li);
+    }
 
-  const std::vector<std::string>& depends = ccg.GetDepends();
+  // Add interface languages from linked targets.
+  cmTargetCollectLinkLanguages cll(this, config, languages, this->Target);
+  for(std::vector<cmLinkImplItem>::const_iterator li = impl->Libraries.begin();
+      li != impl->Libraries.end(); ++li)
+    {
+    cll.Visit(*li);
+    }
 
-  for(std::vector<std::string>::const_iterator di = depends.begin();
-      di != depends.end(); ++di)
+  // Store the transitive closure of languages.
+  for(UNORDERED_SET<std::string>::const_iterator li = languages.begin();
+      li != languages.end(); ++li)
     {
-    std::string const& dep = *di;
-    if(emitted.insert(dep).second)
+    lc.Languages.push_back(*li);
+    }
+
+  // Choose the language whose linker should be used.
+  if(this->GetProperty("HAS_CXX"))
+    {
+    lc.LinkerLanguage = "CXX";
+    }
+  else if(const char* linkerLang = this->GetProperty("LINKER_LANGUAGE"))
+    {
+    lc.LinkerLanguage = linkerLang;
+    }
+  else
+    {
+    // Find the language with the highest preference value.
+    cmTargetSelectLinker tsl(this);
+
+    // First select from the languages compiled directly in this target.
+    for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
+        li != impl->Languages.end(); ++li)
       {
-      if(!this->IsUtility(dep))
+      tsl.Consider(li->c_str());
+      }
+
+    // Now consider languages that propagate from linked targets.
+    for(UNORDERED_SET<std::string>::const_iterator sit = languages.begin();
+        sit != languages.end(); ++sit)
+      {
+      std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
+      if(this->Makefile->IsOn(propagates))
         {
-        // The dependency does not name a target and may be a file we
-        // know how to generate.  Queue it.
-        this->FollowName(dep);
+        tsl.Consider(sit->c_str());
         }
       }
+
+    lc.LinkerLanguage = tsl.Choose();
     }
 }
 
 //----------------------------------------------------------------------------
-void
-cmTargetTraceDependencies
-::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
+void cmGeneratorTarget::GetFullNameComponents(std::string& prefix,
+                                              std::string& base,
+                                              std::string& suffix,
+                                              const std::string& config,
+                                              bool implib) const
 {
-  for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
-      cli != commands.end(); ++cli)
-    {
-    this->CheckCustomCommand(*cli);
-    }
+  this->GetFullNameInternal(config, implib, prefix, base, suffix);
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::TraceDependencies()
+std::string
+cmGeneratorTarget::BuildMacContentDirectory(const std::string& base,
+                                            const std::string& config,
+                                            bool contentOnly) const
 {
-  // CMake-generated targets have no dependencies to trace.  Normally tracing
-  // would find nothing anyway, but when building CMake itself the "install"
-  // target command ends up referencing the "cmake" target but we do not
-  // really want the dependency because "install" depend on "all" anyway.
-  if(this->GetType() == cmTarget::GLOBAL_TARGET)
+  std::string fpath = base;
+  if(this->Target->IsAppBundleOnApple())
     {
-    return;
+    fpath += this->GetAppBundleDirectory(config, contentOnly);
+    }
+  if(this->Target->IsFrameworkOnApple())
+    {
+    fpath += this->GetFrameworkDirectory(config, contentOnly);
+    }
+  if(this->Target->IsCFBundleOnApple())
+    {
+    fpath += this->GetCFBundleDirectory(config, contentOnly);
+    }
+  return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetMacContentDirectory(const std::string& config,
+                                          bool implib) const
+{
+  // Start with the output directory for the target.
+  std::string fpath = this->Target->GetDirectory(config, implib);
+  fpath += "/";
+  bool contentOnly = true;
+  if(this->Target->IsFrameworkOnApple())
+    {
+    // additional files with a framework go into the version specific
+    // directory
+    contentOnly = false;
+    }
+  fpath = this->BuildMacContentDirectory(fpath, config, contentOnly);
+  return fpath;
+}
+
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
+                                            const std::string& config) const
+{
+  // There is no compile information for imported targets.
+  if(this->IsImported())
+    {
+    return 0;
+    }
+
+  if(this->GetType() > cmTarget::OBJECT_LIBRARY)
+    {
+    std::string msg = "cmTarget::GetCompileInfo called for ";
+    msg += this->GetName();
+    msg += " which has type ";
+    msg += cmTarget::GetTargetTypeName(this->Target->GetType());
+    this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+    return 0;
+    }
+
+  // Lookup/compute/cache the compile information for this configuration.
+  std::string config_upper;
+  if(!config.empty())
+    {
+    config_upper = cmSystemTools::UpperCase(config);
+    }
+  CompileInfoMapType::const_iterator i =
+    this->CompileInfoMap.find(config_upper);
+  if(i == this->CompileInfoMap.end())
+    {
+    CompileInfo info;
+    this->Target
+        ->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
+    CompileInfoMapType::value_type entry(config_upper, info);
+    i = this->CompileInfoMap.insert(entry).first;
+    }
+  return &i->second;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetModuleDefinitionFile(const std::string& config) const
+{
+  std::string data;
+  IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
+  return data;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs,
+                                      const std::string &config) const
+{
+  std::vector<cmSourceFile const*> objectFiles;
+  this->GetExternalObjects(objectFiles, config);
+  std::vector<cmTarget*> objectLibraries;
+  for(std::vector<cmSourceFile const*>::const_iterator
+      it = objectFiles.begin(); it != objectFiles.end(); ++it)
+    {
+    std::string objLib = (*it)->GetObjectLibrary();
+    if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
+      {
+      objectLibraries.push_back(tgt);
+      }
+    }
+
+  std::vector<cmTarget*>::const_iterator end
+      = cmRemoveDuplicates(objectLibraries);
+
+  for(std::vector<cmTarget*>::const_iterator
+        ti = objectLibraries.begin();
+      ti != end; ++ti)
+    {
+    cmTarget* objLib = *ti;
+    cmGeneratorTarget* ogt =
+      this->GlobalGenerator->GetGeneratorTarget(objLib);
+    std::vector<cmSourceFile const*> objectSources;
+    ogt->GetObjectSources(objectSources, config);
+    for(std::vector<cmSourceFile const*>::const_iterator
+          si = objectSources.begin();
+        si != objectSources.end(); ++si)
+      {
+      std::string obj = ogt->ObjectDirectory;
+      obj += ogt->Objects[*si];
+      objs.push_back(obj);
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string> &result,
+                                 const std::string& config) const
+{
+  const char *prop
+            = this->GetLinkInterfaceDependentStringProperty("AUTOUIC_OPTIONS",
+                                                            config);
+  if (!prop)
+    {
+    return;
+    }
+  cmGeneratorExpression ge;
+
+  cmGeneratorExpressionDAGChecker dagChecker(
+                                      this->GetName(),
+                                      "AUTOUIC_OPTIONS", 0, 0);
+  cmSystemTools::ExpandListArgument(ge.Parse(prop)
+                                      ->Evaluate(this->Makefile,
+                                                config,
+                                                false,
+                                                this->Target,
+                                                &dagChecker),
+                                  result);
+}
+
+//----------------------------------------------------------------------------
+void processILibs(const std::string& config,
+                  cmTarget const* headTarget,
+                  cmLinkItem const& item,
+                  cmGlobalGenerator* gg,
+                  std::vector<cmTarget const*>& tgts,
+                  std::set<cmTarget const*>& emitted)
+{
+  if (item.Target && emitted.insert(item.Target).second)
+    {
+    tgts.push_back(item.Target);
+    cmGeneratorTarget* gt = gg->GetGeneratorTarget(item.Target);
+    if(cmLinkInterfaceLibraries const* iface =
+       gt->GetLinkInterfaceLibraries(config, headTarget, true))
+      {
+      for(std::vector<cmLinkItem>::const_iterator
+            it = iface->Libraries.begin();
+          it != iface->Libraries.end(); ++it)
+        {
+        processILibs(config, headTarget, *it, gg, tgts, emitted);
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+const std::vector<const cmTarget*>&
+cmGeneratorTarget::GetLinkImplementationClosure(
+    const std::string& config) const
+{
+  LinkImplClosure& tgts =
+    this->LinkImplClosureMap[config];
+  if(!tgts.Done)
+    {
+    tgts.Done = true;
+    std::set<cmTarget const*> emitted;
+
+    cmLinkImplementationLibraries const* impl
+      = this->Target->GetLinkImplementationLibraries(config);
+
+    for(std::vector<cmLinkImplItem>::const_iterator
+          it = impl->Libraries.begin();
+        it != impl->Libraries.end(); ++it)
+      {
+      processILibs(config, this->Target, *it,
+                   this->LocalGenerator->GetGlobalGenerator(),
+                   tgts , emitted);
+      }
+    }
+  return tgts;
+}
+
+//----------------------------------------------------------------------------
+class cmTargetTraceDependencies
+{
+public:
+  cmTargetTraceDependencies(cmGeneratorTarget* target);
+  void Trace();
+private:
+  cmTarget* Target;
+  cmGeneratorTarget* GeneratorTarget;
+  cmMakefile* Makefile;
+  cmGlobalGenerator const* GlobalGenerator;
+  typedef cmGeneratorTarget::SourceEntry SourceEntry;
+  SourceEntry* CurrentEntry;
+  std::queue<cmSourceFile*> SourceQueue;
+  std::set<cmSourceFile*> SourcesQueued;
+  typedef std::map<std::string, cmSourceFile*> NameMapType;
+  NameMapType NameMap;
+  std::vector<std::string> NewSources;
+
+  void QueueSource(cmSourceFile* sf);
+  void FollowName(std::string const& name);
+  void FollowNames(std::vector<std::string> const& names);
+  bool IsUtility(std::string const& dep);
+  void CheckCustomCommand(cmCustomCommand const& cc);
+  void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
+  void FollowCommandDepends(cmCustomCommand const& cc,
+                            const std::string& config,
+                            std::set<std::string>& emitted);
+};
+
+//----------------------------------------------------------------------------
+cmTargetTraceDependencies
+::cmTargetTraceDependencies(cmGeneratorTarget* target):
+  Target(target->Target), GeneratorTarget(target)
+{
+  // Convenience.
+  this->Makefile = this->Target->GetMakefile();
+  this->GlobalGenerator = target->GetLocalGenerator()->GetGlobalGenerator();
+  this->CurrentEntry = 0;
+
+  // Queue all the source files already specified for the target.
+  if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
+    {
+    std::vector<std::string> configs;
+    this->Makefile->GetConfigurations(configs);
+    if (configs.empty())
+      {
+      configs.push_back("");
+      }
+    std::set<cmSourceFile*> emitted;
+    for(std::vector<std::string>::const_iterator ci = configs.begin();
+        ci != configs.end(); ++ci)
+      {
+      std::vector<cmSourceFile*> sources;
+      this->Target->GetSourceFiles(sources, *ci);
+      for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
+          si != sources.end(); ++si)
+        {
+        cmSourceFile* sf = *si;
+        const std::set<cmTarget const*> tgts =
+                          this->GlobalGenerator->GetFilenameTargetDepends(sf);
+        if (tgts.find(this->Target) != tgts.end())
+          {
+          std::ostringstream e;
+          e << "Evaluation output file\n  \"" << sf->GetFullPath()
+            << "\"\ndepends on the sources of a target it is used in.  This "
+              "is a dependency loop and is not allowed.";
+          this->GeneratorTarget
+              ->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
+          return;
+          }
+        if(emitted.insert(sf).second && this->SourcesQueued.insert(sf).second)
+          {
+          this->SourceQueue.push(sf);
+          }
+        }
+      }
+    }
+
+  // Queue pre-build, pre-link, and post-build rule dependencies.
+  this->CheckCustomCommands(this->Target->GetPreBuildCommands());
+  this->CheckCustomCommands(this->Target->GetPreLinkCommands());
+  this->CheckCustomCommands(this->Target->GetPostBuildCommands());
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::Trace()
+{
+  // Process one dependency at a time until the queue is empty.
+  while(!this->SourceQueue.empty())
+    {
+    // Get the next source from the queue.
+    cmSourceFile* sf = this->SourceQueue.front();
+    this->SourceQueue.pop();
+    this->CurrentEntry = &this->GeneratorTarget->SourceEntries[sf];
+
+    // Queue dependencies added explicitly by the user.
+    if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
+      {
+      std::vector<std::string> objDeps;
+      cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
+      for(std::vector<std::string>::iterator odi = objDeps.begin();
+          odi != objDeps.end(); ++odi)
+        {
+        if (cmSystemTools::FileIsFullPath(*odi))
+          {
+          *odi = cmSystemTools::CollapseFullPath(*odi);
+          }
+        }
+      this->FollowNames(objDeps);
+      }
+
+    // Queue the source needed to generate this file, if any.
+    this->FollowName(sf->GetFullPath());
+
+    // Queue dependencies added programatically by commands.
+    this->FollowNames(sf->GetDepends());
+
+    // Queue custom command dependencies.
+    if(cmCustomCommand const* cc = sf->GetCustomCommand())
+      {
+      this->CheckCustomCommand(*cc);
+      }
+    }
+  this->CurrentEntry = 0;
+
+  this->Target->AddTracedSources(this->NewSources);
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
+{
+  if(this->SourcesQueued.insert(sf).second)
+    {
+    this->SourceQueue.push(sf);
+
+    // Make sure this file is in the target at the end.
+    this->NewSources.push_back(sf->GetFullPath());
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::FollowName(std::string const& name)
+{
+  NameMapType::iterator i = this->NameMap.find(name);
+  if(i == this->NameMap.end())
+    {
+    // Check if we know how to generate this file.
+    cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name);
+    NameMapType::value_type entry(name, sf);
+    i = this->NameMap.insert(entry).first;
+    }
+  if(cmSourceFile* sf = i->second)
+    {
+    // Record the dependency we just followed.
+    if(this->CurrentEntry)
+      {
+      this->CurrentEntry->Depends.push_back(sf);
+      }
+    this->QueueSource(sf);
+    }
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetTraceDependencies::FollowNames(std::vector<std::string> const& names)
+{
+  for(std::vector<std::string>::const_iterator i = names.begin();
+      i != names.end(); ++i)
+    {
+    this->FollowName(*i);
+    }
+}
+
+//----------------------------------------------------------------------------
+bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
+{
+  // Dependencies on targets (utilities) are supposed to be named by
+  // just the target name.  However for compatibility we support
+  // naming the output file generated by the target (assuming there is
+  // no output-name property which old code would not have set).  In
+  // that case the target name will be the file basename of the
+  // dependency.
+  std::string util = cmSystemTools::GetFilenameName(dep);
+  if(cmSystemTools::GetFilenameLastExtension(util) == ".exe")
+    {
+    util = cmSystemTools::GetFilenameWithoutLastExtension(util);
+    }
+
+  // Check for a target with this name.
+  if(cmGeneratorTarget* t
+                    = this->Makefile->FindGeneratorTargetToUse(util))
+    {
+    // If we find the target and the dep was given as a full path,
+    // then make sure it was not a full path to something else, and
+    // the fact that the name matched a target was just a coincidence.
+    if(cmSystemTools::FileIsFullPath(dep.c_str()))
+      {
+      if(t->GetType() >= cmTarget::EXECUTABLE &&
+         t->GetType() <= cmTarget::MODULE_LIBRARY)
+        {
+        // This is really only for compatibility so we do not need to
+        // worry about configuration names and output names.
+        std::string tLocation = t->GetLocationForBuild();
+        tLocation = cmSystemTools::GetFilenamePath(tLocation);
+        std::string depLocation = cmSystemTools::GetFilenamePath(dep);
+        depLocation = cmSystemTools::CollapseFullPath(depLocation);
+        tLocation = cmSystemTools::CollapseFullPath(tLocation);
+        if(depLocation == tLocation)
+          {
+          this->Target->AddUtility(util);
+          return true;
+          }
+        }
+      }
+    else
+      {
+      // The original name of the dependency was not a full path.  It
+      // must name a target, so add the target-level dependency.
+      this->Target->AddUtility(util);
+      return true;
+      }
+    }
+
+  // The dependency does not name a target built in this project.
+  return false;
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetTraceDependencies
+::CheckCustomCommand(cmCustomCommand const& cc)
+{
+  // Transform command names that reference targets built in this
+  // project to corresponding target-level dependencies.
+  cmGeneratorExpression ge(cc.GetBacktrace());
+
+  // Add target-level dependencies referenced by generator expressions.
+  std::set<cmTarget*> targets;
+
+  for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
+      cit != cc.GetCommandLines().end(); ++cit)
+    {
+    std::string const& command = *cit->begin();
+    // Check for a target with this name.
+    if(cmTarget* t = this->Makefile->FindTargetToUse(command))
+      {
+      if(t->GetType() == cmTarget::EXECUTABLE)
+        {
+        // The command refers to an executable target built in
+        // this project.  Add the target-level dependency to make
+        // sure the executable is up to date before this custom
+        // command possibly runs.
+        this->Target->AddUtility(command);
+        }
+      }
+
+    // Check for target references in generator expressions.
+    for(cmCustomCommandLine::const_iterator cli = cit->begin();
+        cli != cit->end(); ++cli)
+      {
+      const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
+                                                              = ge.Parse(*cli);
+      cge->Evaluate(this->Makefile, "", true);
+      std::set<cmTarget*> geTargets = cge->GetTargets();
+      targets.insert(geTargets.begin(), geTargets.end());
+      }
+    }
+
+  for(std::set<cmTarget*>::iterator ti = targets.begin();
+      ti != targets.end(); ++ti)
+    {
+    this->Target->AddUtility((*ti)->GetName());
+    }
+
+  // Queue the custom command dependencies.
+  std::vector<std::string> configs;
+  std::set<std::string> emitted;
+  this->Makefile->GetConfigurations(configs);
+  if (configs.empty())
+    {
+    configs.push_back("");
+    }
+  for(std::vector<std::string>::const_iterator ci = configs.begin();
+      ci != configs.end(); ++ci)
+    {
+    this->FollowCommandDepends(cc, *ci, emitted);
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::FollowCommandDepends(cmCustomCommand const& cc,
+                                              const std::string& config,
+                                              std::set<std::string>& emitted)
+{
+  cmCustomCommandGenerator ccg(cc, config,
+                               this->GeneratorTarget->LocalGenerator);
+
+  const std::vector<std::string>& depends = ccg.GetDepends();
+
+  for(std::vector<std::string>::const_iterator di = depends.begin();
+      di != depends.end(); ++di)
+    {
+    std::string const& dep = *di;
+    if(emitted.insert(dep).second)
+      {
+      if(!this->IsUtility(dep))
+        {
+        // The dependency does not name a target and may be a file we
+        // know how to generate.  Queue it.
+        this->FollowName(dep);
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetTraceDependencies
+::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
+{
+  for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
+      cli != commands.end(); ++cli)
+    {
+    this->CheckCustomCommand(*cli);
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::TraceDependencies()
+{
+  // CMake-generated targets have no dependencies to trace.  Normally tracing
+  // would find nothing anyway, but when building CMake itself the "install"
+  // target command ends up referencing the "cmake" target but we do not
+  // really want the dependency because "install" depend on "all" anyway.
+  if(this->GetType() == cmTarget::GLOBAL_TARGET)
+    {
+    return;
+    }
+
+  // Use a helper object to trace the dependencies.
+  cmTargetTraceDependencies tracer(this);
+  tracer.Trace();
+}
+
+std::string
+cmGeneratorTarget::GetCompilePDBDirectory(const std::string& config) const
+{
+  if(CompileInfo const* info = this->GetCompileInfo(config))
+    {
+    return info->CompilePdbDir;
+    }
+  return "";
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetAppleArchs(const std::string& config,
+                             std::vector<std::string>& archVec) const
+{
+  const char* archs = 0;
+  if(!config.empty())
+    {
+    std::string defVarName = "OSX_ARCHITECTURES_";
+    defVarName += cmSystemTools::UpperCase(config);
+    archs = this->Target->GetProperty(defVarName);
+    }
+  if(!archs)
+    {
+    archs = this->Target->GetProperty("OSX_ARCHITECTURES");
+    }
+  if(archs)
+    {
+    cmSystemTools::ExpandListArgument(std::string(archs), archVec);
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
+                                         std::string const& config) const
+{
+  switch(this->GetType())
+    {
+    case cmTarget::STATIC_LIBRARY:
+      {
+      std::string var = "CMAKE_" + lang + "_CREATE_STATIC_LIBRARY";
+      if(this->GetFeatureAsBool(
+           "INTERPROCEDURAL_OPTIMIZATION", config))
+        {
+        std::string varIPO = var + "_IPO";
+        if(this->Makefile->GetDefinition(varIPO))
+          {
+          return varIPO;
+          }
+        }
+      return var;
+      }
+    case cmTarget::SHARED_LIBRARY:
+      return "CMAKE_" + lang + "_CREATE_SHARED_LIBRARY";
+    case cmTarget::MODULE_LIBRARY:
+      return "CMAKE_" + lang + "_CREATE_SHARED_MODULE";
+    case cmTarget::EXECUTABLE:
+      return "CMAKE_" + lang + "_LINK_EXECUTABLE";
+    default:
+      break;
+    }
+  return "";
+}
+//----------------------------------------------------------------------------
+static void processIncludeDirectories(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &includes,
+      UNORDERED_SET<std::string> &uniqueIncludes,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugIncludes,
+      const std::string& language)
+{
+  cmMakefile *mf = tgt->Target->GetMakefile();
+
+  for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+      it = entries.begin(), end = entries.end(); it != end; ++it)
+    {
+    cmLinkImplItem const& item = (*it)->LinkImplItem;
+    std::string const& targetName = item;
+    bool const fromImported = item.Target && item.Target->IsImported();
+    bool const checkCMP0027 = item.FromGenex;
+    std::vector<std::string> entryIncludes;
+    cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+                                              config,
+                                              false,
+                                              tgt->Target,
+                                              dagChecker, language),
+                                    entryIncludes);
+
+    std::string usedIncludes;
+    for(std::vector<std::string>::iterator
+          li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
+      {
+      if (fromImported
+          && !cmSystemTools::FileExists(li->c_str()))
+        {
+        std::ostringstream e;
+        cmake::MessageType messageType = cmake::FATAL_ERROR;
+        if (checkCMP0027)
+          {
+          switch(tgt->Target->GetPolicyStatusCMP0027())
+            {
+            case cmPolicies::WARN:
+              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
+            case cmPolicies::OLD:
+              messageType = cmake::AUTHOR_WARNING;
+              break;
+            case cmPolicies::REQUIRED_ALWAYS:
+            case cmPolicies::REQUIRED_IF_USED:
+            case cmPolicies::NEW:
+              break;
+            }
+          }
+        e << "Imported target \"" << targetName << "\" includes "
+             "non-existent path\n  \"" << *li << "\"\nin its "
+             "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
+             "* The path was deleted, renamed, or moved to another "
+             "location.\n"
+             "* An install or uninstall procedure did not complete "
+             "successfully.\n"
+             "* The installation package was faulty and references files it "
+             "does not provide.\n";
+        tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
+        return;
+        }
+
+      if (!cmSystemTools::FileIsFullPath(li->c_str()))
+        {
+        std::ostringstream e;
+        bool noMessage = false;
+        cmake::MessageType messageType = cmake::FATAL_ERROR;
+        if (!targetName.empty())
+          {
+          e << "Target \"" << targetName << "\" contains relative "
+            "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
+            "  \"" << *li << "\"";
+          }
+        else
+          {
+          switch(tgt->Target->GetPolicyStatusCMP0021())
+            {
+            case cmPolicies::WARN:
+              {
+              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
+              messageType = cmake::AUTHOR_WARNING;
+              }
+              break;
+            case cmPolicies::OLD:
+              noMessage = true;
+            case cmPolicies::REQUIRED_IF_USED:
+            case cmPolicies::REQUIRED_ALWAYS:
+            case cmPolicies::NEW:
+              // Issue the fatal message.
+              break;
+            }
+          e << "Found relative path while evaluating include directories of "
+          "\"" << tgt->GetName() << "\":\n  \"" << *li << "\"\n";
+          }
+        if (!noMessage)
+          {
+          tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
+          if (messageType == cmake::FATAL_ERROR)
+            {
+            return;
+            }
+          }
+        }
+
+      if (!cmSystemTools::IsOff(li->c_str()))
+        {
+        cmSystemTools::ConvertToUnixSlashes(*li);
+        }
+      std::string inc = *li;
+
+      if(uniqueIncludes.insert(inc).second)
+        {
+        includes.push_back(inc);
+        if (debugIncludes)
+          {
+          usedIncludes += " * " + inc + "\n";
+          }
+        }
+      }
+    if (!usedIncludes.empty())
+      {
+      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+                            std::string("Used includes for target ")
+                            + tgt->GetName() + ":\n"
+                            + usedIncludes, (*it)->ge->GetBacktrace());
+      }
+    }
+}
+
+
+//----------------------------------------------------------------------------
+static void AddInterfaceEntries(
+  cmGeneratorTarget const* thisTarget, std::string const& config,
+  std::string const& prop,
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+{
+  if(cmLinkImplementationLibraries const* impl =
+     thisTarget->Target->GetLinkImplementationLibraries(config))
+    {
+    for (std::vector<cmLinkImplItem>::const_iterator
+           it = impl->Libraries.begin(), end = impl->Libraries.end();
+         it != end; ++it)
+      {
+      if(it->Target)
+        {
+        std::string genex =
+          "$<TARGET_PROPERTY:" + *it + "," + prop + ">";
+        cmGeneratorExpression ge(it->Backtrace);
+        cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
+        cge->SetEvaluateForBuildsystem(true);
+        entries.push_back(
+          new cmGeneratorTarget::TargetPropertyEntry(cge, *it));
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string>
+cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
+                                         const std::string& lang) const
+{
+  std::vector<std::string> includes;
+  UNORDERED_SET<std::string> uniqueIncludes;
+
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+                                             "INCLUDE_DIRECTORIES", 0, 0);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugIncludes = !this->DebugIncludesDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "INCLUDE_DIRECTORIES")
+                        != debugProperties.end();
+
+  if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+    {
+    this->DebugIncludesDone = true;
+    }
+
+  processIncludeDirectories(this,
+                            this->IncludeDirectoriesEntries,
+                            includes,
+                            uniqueIncludes,
+                            &dagChecker,
+                            config,
+                            debugIncludes,
+                            lang);
+
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+    linkInterfaceIncludeDirectoriesEntries;
+  AddInterfaceEntries(
+    this, config, "INTERFACE_INCLUDE_DIRECTORIES",
+    linkInterfaceIncludeDirectoriesEntries);
+
+  if(this->Makefile->IsOn("APPLE"))
+    {
+    cmLinkImplementationLibraries const* impl =
+        this->Target->GetLinkImplementationLibraries(config);
+    for(std::vector<cmLinkImplItem>::const_iterator
+        it = impl->Libraries.begin();
+        it != impl->Libraries.end(); ++it)
+      {
+      std::string libDir = cmSystemTools::CollapseFullPath(*it);
+
+      static cmsys::RegularExpression
+        frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
+      if(!frameworkCheck.find(libDir))
+        {
+        continue;
+        }
+
+      libDir = frameworkCheck.match(1);
+
+      cmGeneratorExpression ge;
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+                ge.Parse(libDir.c_str());
+      linkInterfaceIncludeDirectoriesEntries
+              .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+      }
+    }
+
+  processIncludeDirectories(this,
+                            linkInterfaceIncludeDirectoriesEntries,
+                            includes,
+                            uniqueIncludes,
+                            &dagChecker,
+                            config,
+                            debugIncludes,
+                            lang);
+
+  cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
+
+  return includes;
+}
+
+//----------------------------------------------------------------------------
+static void processCompileOptionsInternal(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      UNORDERED_SET<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugOptions, const char *logName,
+      std::string const& language)
+{
+  cmMakefile *mf = tgt->Target->GetMakefile();
+
+  for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+      it = entries.begin(), end = entries.end(); it != end; ++it)
+    {
+    std::vector<std::string> entryOptions;
+    cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+                                              config,
+                                              false,
+                                              tgt->Target,
+                                              dagChecker,
+                                              language),
+                                    entryOptions);
+    std::string usedOptions;
+    for(std::vector<std::string>::iterator
+          li = entryOptions.begin(); li != entryOptions.end(); ++li)
+      {
+      std::string const& opt = *li;
+
+      if(uniqueOptions.insert(opt).second)
+        {
+        options.push_back(opt);
+        if (debugOptions)
+          {
+          usedOptions += " * " + opt + "\n";
+          }
+        }
+      }
+    if (!usedOptions.empty())
+      {
+      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+                            std::string("Used compile ") + logName
+                            + std::string(" for target ")
+                            + tgt->GetName() + ":\n"
+                            + usedOptions, (*it)->ge->GetBacktrace());
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+static void processCompileOptions(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      UNORDERED_SET<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugOptions,
+      std::string const& language)
+{
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions, "options",
+                                language);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileOptions(std::vector<std::string> &result,
+                                 const std::string& config,
+                                 const std::string& language) const
+{
+  UNORDERED_SET<std::string> uniqueOptions;
+
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+                                             "COMPILE_OPTIONS", 0, 0);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugOptions = !this->DebugCompileOptionsDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "COMPILE_OPTIONS")
+                        != debugProperties.end();
+
+  if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+    {
+    this->DebugCompileOptionsDone = true;
+    }
+
+  processCompileOptions(this,
+                            this->CompileOptionsEntries,
+                            result,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugOptions,
+                            language);
+
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+    linkInterfaceCompileOptionsEntries;
+
+  AddInterfaceEntries(
+    this, config, "INTERFACE_COMPILE_OPTIONS",
+    linkInterfaceCompileOptionsEntries);
+
+  processCompileOptions(this,
+                        linkInterfaceCompileOptionsEntries,
+                            result,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugOptions,
+                            language);
+
+  cmDeleteAll(linkInterfaceCompileOptionsEntries);
+}
+
+//----------------------------------------------------------------------------
+static void processCompileFeatures(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      UNORDERED_SET<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugOptions)
+{
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions, "features",
+                                std::string());
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string> &result,
+                                  const std::string& config) const
+{
+  UNORDERED_SET<std::string> uniqueFeatures;
+
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+                                             "COMPILE_FEATURES",
+                                             0, 0);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugFeatures = !this->DebugCompileFeaturesDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "COMPILE_FEATURES")
+                        != debugProperties.end();
+
+  if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+    {
+    this->DebugCompileFeaturesDone = true;
+    }
+
+  processCompileFeatures(this,
+                            this->CompileFeaturesEntries,
+                            result,
+                            uniqueFeatures,
+                            &dagChecker,
+                            config,
+                            debugFeatures);
+
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+    linkInterfaceCompileFeaturesEntries;
+  AddInterfaceEntries(
+    this, config, "INTERFACE_COMPILE_FEATURES",
+    linkInterfaceCompileFeaturesEntries);
+
+  processCompileFeatures(this,
+                         linkInterfaceCompileFeaturesEntries,
+                            result,
+                            uniqueFeatures,
+                            &dagChecker,
+                            config,
+                            debugFeatures);
+
+  cmDeleteAll(linkInterfaceCompileFeaturesEntries);
+}
+
+//----------------------------------------------------------------------------
+static void processCompileDefinitions(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      UNORDERED_SET<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugOptions,
+      std::string const& language)
+{
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions,
+                                "definitions", language);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileDefinitions(std::vector<std::string> &list,
+                                            const std::string& config,
+                                            const std::string& language) const
+{
+  UNORDERED_SET<std::string> uniqueOptions;
+
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+                                             "COMPILE_DEFINITIONS", 0, 0);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugDefines = !this->DebugCompileDefinitionsDone
+                          && std::find(debugProperties.begin(),
+                                debugProperties.end(),
+                                "COMPILE_DEFINITIONS")
+                        != debugProperties.end();
+
+  if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+    {
+    this->DebugCompileDefinitionsDone = true;
+    }
+
+  processCompileDefinitions(this,
+                            this->CompileDefinitionsEntries,
+                            list,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugDefines,
+                            language);
+
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+    linkInterfaceCompileDefinitionsEntries;
+  AddInterfaceEntries(
+    this, config, "INTERFACE_COMPILE_DEFINITIONS",
+    linkInterfaceCompileDefinitionsEntries);
+  if (!config.empty())
+    {
+    std::string configPropName = "COMPILE_DEFINITIONS_"
+                                        + cmSystemTools::UpperCase(config);
+    const char *configProp = this->Target->GetProperty(configPropName);
+    if (configProp)
+      {
+      switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
+        {
+        case cmPolicies::WARN:
+          {
+          std::ostringstream e;
+          e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043);
+          this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING,
+                                       e.str());
+          }
+        case cmPolicies::OLD:
+          {
+          cmGeneratorExpression ge;
+          cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+                                                      ge.Parse(configProp);
+          linkInterfaceCompileDefinitionsEntries
+                .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+          }
+          break;
+        case cmPolicies::NEW:
+        case cmPolicies::REQUIRED_ALWAYS:
+        case cmPolicies::REQUIRED_IF_USED:
+          break;
+        }
+      }
+    }
+
+  processCompileDefinitions(this,
+                            linkInterfaceCompileDefinitionsEntries,
+                            list,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugDefines,
+                            language);
+
+  cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeTargetManifest(
+                                              const std::string& config) const
+{
+  if (this->Target->IsImported())
+    {
+    return;
+    }
+  cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
+
+  // Get the names.
+  std::string name;
+  std::string soName;
+  std::string realName;
+  std::string impName;
+  std::string pdbName;
+  if(this->GetType() == cmTarget::EXECUTABLE)
+    {
+    this->GetExecutableNames(name, realName, impName, pdbName, config);
+    }
+  else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
+          this->GetType() == cmTarget::SHARED_LIBRARY ||
+          this->GetType() == cmTarget::MODULE_LIBRARY)
+    {
+    this->GetLibraryNames(name, soName, realName, impName, pdbName,
+                                  config);
+    }
+  else
+    {
+    return;
+    }
+
+  // Get the directory.
+  std::string dir = this->Target->GetDirectory(config, false);
+
+  // Add each name.
+  std::string f;
+  if(!name.empty())
+    {
+    f = dir;
+    f += "/";
+    f += name;
+    gg->AddToManifest(f);
+    }
+  if(!soName.empty())
+    {
+    f = dir;
+    f += "/";
+    f += soName;
+    gg->AddToManifest(f);
+    }
+  if(!realName.empty())
+    {
+    f = dir;
+    f += "/";
+    f += realName;
+    gg->AddToManifest(f);
+    }
+  if(!pdbName.empty())
+    {
+    f = dir;
+    f += "/";
+    f += pdbName;
+    gg->AddToManifest(f);
+    }
+  if(!impName.empty())
+    {
+    f = this->Target->GetDirectory(config, true);
+    f += "/";
+    f += impName;
+    gg->AddToManifest(f);
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFullPath(const std::string& config,
+                                           bool implib, bool realname) const
+{
+  if(this->Target->IsImported())
+    {
+    return this->Target->ImportedGetFullPath(config, implib);
+    }
+  else
+    {
+    return this->NormalGetFullPath(config, implib, realname);
+    }
+}
+
+std::string cmGeneratorTarget::NormalGetFullPath(const std::string& config,
+                                                 bool implib,
+                                                 bool realname) const
+{
+  std::string fpath = this->Target->GetDirectory(config, implib);
+  fpath += "/";
+  if(this->Target->IsAppBundleOnApple())
+    {
+    fpath = this->BuildMacContentDirectory(fpath, config, false);
+    fpath += "/";
+    }
+
+  // Add the full name of the target.
+  if(implib)
+    {
+    fpath += this->GetFullName(config, true);
+    }
+  else if(realname)
+    {
+    fpath += this->NormalGetRealName(config);
+    }
+  else
+    {
+    fpath += this->GetFullName(config, false);
+    }
+  return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::NormalGetRealName(const std::string& config) const
+{
+  // This should not be called for imported targets.
+  // TODO: Split cmTarget into a class hierarchy to get compile-time
+  // enforcement of the limited imported target API.
+  if(this->Target->IsImported())
+    {
+    std::string msg =  "NormalGetRealName called on imported target: ";
+    msg += this->GetName();
+    this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+    }
+
+  if(this->GetType() == cmTarget::EXECUTABLE)
+    {
+    // Compute the real name that will be built.
+    std::string name;
+    std::string realName;
+    std::string impName;
+    std::string pdbName;
+    this->GetExecutableNames(name, realName, impName, pdbName, config);
+    return realName;
+    }
+  else
+    {
+    // Compute the real name that will be built.
+    std::string name;
+    std::string soName;
+    std::string realName;
+    std::string impName;
+    std::string pdbName;
+    this->GetLibraryNames(name, soName, realName,
+                          impName, pdbName, config);
+    return realName;
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetLibraryNames(std::string& name,
+                               std::string& soName,
+                               std::string& realName,
+                               std::string& impName,
+                               std::string& pdbName,
+                               const std::string& config) const
+{
+  // This should not be called for imported targets.
+  // TODO: Split cmTarget into a class hierarchy to get compile-time
+  // enforcement of the limited imported target API.
+  if(this->Target->IsImported())
+    {
+    std::string msg =  "GetLibraryNames called on imported target: ";
+    msg += this->GetName();
+    this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR,
+                                 msg);
+    return;
+    }
+
+  // Check for library version properties.
+  const char* version = this->GetProperty("VERSION");
+  const char* soversion = this->GetProperty("SOVERSION");
+  if(!this->HasSOName(config) ||
+     this->Target->IsFrameworkOnApple())
+    {
+    // Versioning is supported only for shared libraries and modules,
+    // and then only when the platform supports an soname flag.
+    version = 0;
+    soversion = 0;
+    }
+  if(version && !soversion)
+    {
+    // The soversion must be set if the library version is set.  Use
+    // the library version as the soversion.
+    soversion = version;
+    }
+  if(!version && soversion)
+    {
+    // Use the soversion as the library version.
+    version = soversion;
+    }
+
+  // Get the components of the library name.
+  std::string prefix;
+  std::string base;
+  std::string suffix;
+  this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+  // The library name.
+  name = prefix+base+suffix;
+
+  if(this->Target->IsFrameworkOnApple())
+    {
+    realName = prefix;
+    if(!this->Makefile->PlatformIsAppleIos())
+      {
+      realName += "Versions/";
+      realName += this->Target->GetFrameworkVersion();
+      realName += "/";
+      }
+    realName += base;
+    soName = realName;
+    }
+  else
+  {
+    // The library's soname.
+    this->Target->ComputeVersionedName(soName, prefix, base, suffix,
+                              name, soversion);
+
+    // The library's real name on disk.
+    this->Target->ComputeVersionedName(realName, prefix, base, suffix,
+                              name, version);
+  }
+
+  // The import library name.
+  if(this->GetType() == cmTarget::SHARED_LIBRARY ||
+     this->GetType() == cmTarget::MODULE_LIBRARY)
+    {
+    impName = this->GetFullNameInternal(config, true);
+    }
+  else
+    {
+    impName = "";
+    }
+
+  // The program database file name.
+  pdbName = this->GetPDBName(config);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetExecutableNames(std::string& name,
+                                  std::string& realName,
+                                  std::string& impName,
+                                  std::string& pdbName,
+                                  const std::string& config) const
+{
+  // This should not be called for imported targets.
+  // TODO: Split cmTarget into a class hierarchy to get compile-time
+  // enforcement of the limited imported target API.
+  if(this->Target->IsImported())
+    {
+    std::string msg =
+      "GetExecutableNames called on imported target: ";
+    msg += this->GetName();
+    this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+    }
+
+  // This versioning is supported only for executables and then only
+  // when the platform supports symbolic links.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  const char* version = 0;
+#else
+  // Check for executable version properties.
+  const char* version = this->GetProperty("VERSION");
+  if(this->GetType() != cmTarget::EXECUTABLE || this->Makefile->IsOn("XCODE"))
+    {
+    version = 0;
+    }
+#endif
+
+  // Get the components of the executable name.
+  std::string prefix;
+  std::string base;
+  std::string suffix;
+  this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+  // The executable name.
+  name = prefix+base+suffix;
+
+  // The executable's real name on disk.
+#if defined(__CYGWIN__)
+  realName = prefix+base;
+#else
+  realName = name;
+#endif
+  if(version)
+    {
+    realName += "-";
+    realName += version;
+    }
+#if defined(__CYGWIN__)
+  realName += suffix;
+#endif
+
+  // The import library name.
+  impName = this->GetFullNameInternal(config, true);
+
+  // The program database file name.
+  pdbName = this->GetPDBName(config);
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFullNameInternal(const std::string& config,
+                                                   bool implib) const
+{
+  std::string prefix;
+  std::string base;
+  std::string suffix;
+  this->GetFullNameInternal(config, implib, prefix, base, suffix);
+  return prefix+base+suffix;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
+                                            bool implib,
+                                            std::string& outPrefix,
+                                            std::string& outBase,
+                                            std::string& outSuffix) const
+{
+  // Use just the target name for non-main target types.
+  if(this->GetType() != cmTarget::STATIC_LIBRARY &&
+     this->GetType() != cmTarget::SHARED_LIBRARY &&
+     this->GetType() != cmTarget::MODULE_LIBRARY &&
+     this->GetType() != cmTarget::EXECUTABLE)
+    {
+    outPrefix = "";
+    outBase = this->GetName();
+    outSuffix = "";
+    return;
+    }
+
+  // Return an empty name for the import library if this platform
+  // does not support import libraries.
+  if(implib &&
+     !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
+    {
+    outPrefix = "";
+    outBase = "";
+    outSuffix = "";
+    return;
+    }
+
+  // The implib option is only allowed for shared libraries, module
+  // libraries, and executables.
+  if(this->GetType() != cmTarget::SHARED_LIBRARY &&
+     this->GetType() != cmTarget::MODULE_LIBRARY &&
+     this->GetType() != cmTarget::EXECUTABLE)
+    {
+    implib = false;
+    }
+
+  // Compute the full name for main target types.
+  const char* targetPrefix = (implib
+                              ? this->GetProperty("IMPORT_PREFIX")
+                              : this->GetProperty("PREFIX"));
+  const char* targetSuffix = (implib
+                              ? this->GetProperty("IMPORT_SUFFIX")
+                              : this->GetProperty("SUFFIX"));
+  const char* configPostfix = 0;
+  if(!config.empty())
+    {
+    std::string configProp = cmSystemTools::UpperCase(config);
+    configProp += "_POSTFIX";
+    configPostfix = this->GetProperty(configProp);
+    // Mac application bundles and frameworks have no postfix.
+    if(configPostfix &&
+       (this->Target->IsAppBundleOnApple()
+         || this->Target->IsFrameworkOnApple()))
+      {
+      configPostfix = 0;
+      }
+    }
+  const char* prefixVar = this->Target->GetPrefixVariableInternal(implib);
+  const char* suffixVar = this->Target->GetSuffixVariableInternal(implib);
+
+  // Check for language-specific default prefix and suffix.
+  std::string ll = this->GetLinkerLanguage(config);
+  if(!ll.empty())
+    {
+    if(!targetSuffix && suffixVar && *suffixVar)
+      {
+      std::string langSuff = suffixVar + std::string("_") + ll;
+      targetSuffix = this->Makefile->GetDefinition(langSuff);
+      }
+    if(!targetPrefix && prefixVar && *prefixVar)
+      {
+      std::string langPrefix = prefixVar + std::string("_") + ll;
+      targetPrefix = this->Makefile->GetDefinition(langPrefix);
+      }
+    }
+
+  // if there is no prefix on the target use the cmake definition
+  if(!targetPrefix && prefixVar)
+    {
+    targetPrefix = this->Makefile->GetSafeDefinition(prefixVar);
+    }
+  // if there is no suffix on the target use the cmake definition
+  if(!targetSuffix && suffixVar)
+    {
+    targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
+    }
+
+  // frameworks have directory prefix but no suffix
+  std::string fw_prefix;
+  if(this->Target->IsFrameworkOnApple())
+    {
+    fw_prefix = this->GetOutputName(config, false);
+    fw_prefix += ".framework/";
+    targetPrefix = fw_prefix.c_str();
+    targetSuffix = 0;
+    }
+
+  if(this->Target->IsCFBundleOnApple())
+    {
+    fw_prefix = this->GetCFBundleDirectory(config, false);
+    fw_prefix += "/";
+    targetPrefix = fw_prefix.c_str();
+    targetSuffix = 0;
+    }
+
+  // Begin the final name with the prefix.
+  outPrefix = targetPrefix?targetPrefix:"";
+
+  // Append the target name or property-specified name.
+  outBase += this->GetOutputName(config, implib);
+
+  // Append the per-configuration postfix.
+  outBase += configPostfix?configPostfix:"";
+
+  // Name shared libraries with their version number on some platforms.
+  if(const char* soversion = this->GetProperty("SOVERSION"))
+    {
+    if(this->GetType() == cmTarget::SHARED_LIBRARY && !implib &&
+       this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION"))
+      {
+      outBase += "-";
+      outBase += soversion;
+      }
+    }
+
+  // Append the suffix.
+  outSuffix = targetSuffix?targetSuffix:"";
+}
+
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetLinkerLanguage(const std::string& config) const
+{
+  return this->GetLinkClosure(config)->LinkerLanguage;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
+{
+  std::string prefix;
+  std::string base;
+  std::string suffix;
+  this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+  std::vector<std::string> props;
+  std::string configUpper =
+    cmSystemTools::UpperCase(config);
+  if(!configUpper.empty())
+    {
+    // PDB_NAME_<CONFIG>
+    props.push_back("PDB_NAME_" + configUpper);
+    }
+
+  // PDB_NAME
+  props.push_back("PDB_NAME");
+
+  for(std::vector<std::string>::const_iterator i = props.begin();
+      i != props.end(); ++i)
+    {
+    if(const char* outName = this->GetProperty(*i))
+      {
+      base = outName;
+      break;
+      }
+    }
+  return prefix+base+".pdb";
+}
+
+bool cmStrictTargetComparison::operator()(cmTarget const* t1,
+                                          cmTarget const* t2) const
+{
+  int nameResult = strcmp(t1->GetName().c_str(), t2->GetName().c_str());
+  if (nameResult == 0)
+    {
+    return strcmp(t1->GetMakefile()->GetCurrentBinaryDirectory(),
+                  t2->GetMakefile()->GetCurrentBinaryDirectory()) < 0;
+    }
+  return nameResult < 0;
+}
+
+//----------------------------------------------------------------------------
+struct cmGeneratorTarget::SourceFileFlags
+cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
+{
+  struct SourceFileFlags flags;
+  this->ConstructSourceFileFlags();
+  std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
+    this->SourceFlagsMap.find(sf);
+  if(si != this->SourceFlagsMap.end())
+    {
+    flags = si->second;
+    }
+  else
+    {
+    // Handle the MACOSX_PACKAGE_LOCATION property on source files that
+    // were not listed in one of the other lists.
+    if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
+      {
+      flags.MacFolder = location;
+      if(strcmp(location, "Resources") == 0)
+        {
+        flags.Type = cmGeneratorTarget::SourceFileTypeResource;
+        }
+      else
+        {
+        flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
+        }
+      }
+    }
+  return flags;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ConstructSourceFileFlags() const
+{
+  if(this->SourceFileFlagsConstructed)
+    {
+    return;
+    }
+  this->SourceFileFlagsConstructed = true;
+
+  // Process public headers to mark the source files.
+  if(const char* files = this->Target->GetProperty("PUBLIC_HEADER"))
+    {
+    std::vector<std::string> relFiles;
+    cmSystemTools::ExpandListArgument(files, relFiles);
+    for(std::vector<std::string>::iterator it = relFiles.begin();
+        it != relFiles.end(); ++it)
+      {
+      if(cmSourceFile* sf = this->Makefile->GetSource(*it))
+        {
+        SourceFileFlags& flags = this->SourceFlagsMap[sf];
+        flags.MacFolder = "Headers";
+        flags.Type = cmGeneratorTarget::SourceFileTypePublicHeader;
+        }
+      }
+    }
+
+  // Process private headers after public headers so that they take
+  // precedence if a file is listed in both.
+  if(const char* files = this->Target->GetProperty("PRIVATE_HEADER"))
+    {
+    std::vector<std::string> relFiles;
+    cmSystemTools::ExpandListArgument(files, relFiles);
+    for(std::vector<std::string>::iterator it = relFiles.begin();
+        it != relFiles.end(); ++it)
+      {
+      if(cmSourceFile* sf = this->Makefile->GetSource(*it))
+        {
+        SourceFileFlags& flags = this->SourceFlagsMap[sf];
+        flags.MacFolder = "PrivateHeaders";
+        flags.Type = cmGeneratorTarget::SourceFileTypePrivateHeader;
+        }
+      }
+    }
+
+  // Mark sources listed as resources.
+  if(const char* files = this->Target->GetProperty("RESOURCE"))
+    {
+    std::vector<std::string> relFiles;
+    cmSystemTools::ExpandListArgument(files, relFiles);
+    for(std::vector<std::string>::iterator it = relFiles.begin();
+        it != relFiles.end(); ++it)
+      {
+      if(cmSourceFile* sf = this->Makefile->GetSource(*it))
+        {
+        SourceFileFlags& flags = this->SourceFlagsMap[sf];
+        flags.MacFolder = "Resources";
+        flags.Type = cmGeneratorTarget::SourceFileTypeResource;
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+const cmGeneratorTarget::CompatibleInterfacesBase&
+cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
+{
+  cmGeneratorTarget::CompatibleInterfaces& compat =
+    this->CompatibleInterfacesMap[config];
+  if(!compat.Done)
+    {
+    compat.Done = true;
+    compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
+    compat.PropsString.insert("AUTOUIC_OPTIONS");
+    std::vector<cmTarget const*> const& deps =
+      this->GetLinkImplementationClosure(config);
+    for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
+        li != deps.end(); ++li)
+      {
+#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
+      if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \
+        { \
+        std::vector<std::string> props; \
+        cmSystemTools::ExpandListArgument(prop, props); \
+        compat.Props##x.insert(props.begin(), props.end()); \
+        }
+      CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
+      CM_READ_COMPATIBLE_INTERFACE(STRING, String)
+      CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin)
+      CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax)
+#undef CM_READ_COMPATIBLE_INTERFACE
+      }
+    }
+  return compat;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentBoolProperty(
+    const std::string &p, const std::string& config) const
+{
+  if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
+      || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+    {
+    return false;
+    }
+  return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentStringProperty(
+    const std::string &p, const std::string& config) const
+{
+  if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
+      || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+    {
+    return false;
+    }
+  return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMinProperty(
+    const std::string &p, const std::string& config) const
+{
+  if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
+      || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+    {
+    return false;
+    }
+  return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMaxProperty(
+    const std::string &p, const std::string& config) const
+{
+  if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
+      || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+    {
+    return false;
+    }
+  return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
+}
+
+enum CompatibleType
+{
+  BoolType,
+  StringType,
+  NumberMinType,
+  NumberMaxType
+};
+
+template<typename PropertyType>
+PropertyType getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
+                                               const std::string& prop,
+                                               const std::string& config,
+                                               CompatibleType,
+                                               PropertyType *);
+
+template<>
+bool getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
+                                       const std::string& prop,
+                                       const std::string& config,
+                                       CompatibleType, bool *)
+{
+  return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
+}
+
+template<>
+const char * getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
+                                               const std::string& prop,
+                                               const std::string& config,
+                                               CompatibleType t,
+                                               const char **)
+{
+  switch(t)
+  {
+  case BoolType:
+    assert(0 && "String compatibility check function called for boolean");
+    return 0;
+  case StringType:
+    return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
+  case NumberMinType:
+    return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
+  case NumberMaxType:
+    return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
+  }
+  assert(0 && "Unreachable!");
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+void checkPropertyConsistency(cmGeneratorTarget const* depender,
+                              cmTarget const* dependee,
+                              const std::string& propName,
+                              std::set<std::string> &emitted,
+                              const std::string& config,
+                              CompatibleType t,
+                              PropertyType *)
+{
+  const char *prop = dependee->GetProperty(propName);
+  if (!prop)
+    {
+    return;
+    }
+
+  std::vector<std::string> props;
+  cmSystemTools::ExpandListArgument(prop, props);
+  std::string pdir =
+    dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
+  pdir += "/Help/prop_tgt/";
+
+  for(std::vector<std::string>::iterator pi = props.begin();
+      pi != props.end(); ++pi)
+    {
+    std::string pname = cmSystemTools::HelpFileName(*pi);
+    std::string pfile = pdir + pname + ".rst";
+    if(cmSystemTools::FileExists(pfile.c_str(), true))
+      {
+      std::ostringstream e;
+      e << "Target \"" << dependee->GetName() << "\" has property \""
+        << *pi << "\" listed in its " << propName << " property.  "
+          "This is not allowed.  Only user-defined properties may appear "
+          "listed in the " << propName << " property.";
+      depender->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, e.str());
+      return;
+      }
+    if(emitted.insert(*pi).second)
+      {
+      getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
+                                                      t, 0);
+      if (cmSystemTools::GetErrorOccuredFlag())
+        {
+        return;
+        }
+      }
+    }
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+                             const std::set<std::string> &s2)
+{
+  std::set<std::string> intersect;
+  std::set_intersection(s1.begin(),s1.end(),
+                        s2.begin(),s2.end(),
+                      std::inserter(intersect,intersect.begin()));
+  if (!intersect.empty())
+    {
+    return *intersect.begin();
+    }
+  return "";
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+                       const std::set<std::string> &s2,
+                       const std::set<std::string> &s3)
+{
+  std::string result;
+  result = intersect(s1, s2);
+  if (!result.empty())
+    return result;
+  result = intersect(s1, s3);
+  if (!result.empty())
+    return result;
+  return intersect(s2, s3);
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+                       const std::set<std::string> &s2,
+                       const std::set<std::string> &s3,
+                       const std::set<std::string> &s4)
+{
+  std::string result;
+  result = intersect(s1, s2);
+  if (!result.empty())
+    return result;
+  result = intersect(s1, s3);
+  if (!result.empty())
+    return result;
+  result = intersect(s1, s4);
+  if (!result.empty())
+    return result;
+  return intersect(s2, s3, s4);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::CheckPropertyCompatibility(
+    cmComputeLinkInformation *info, const std::string& config) const
+{
+  const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+  std::set<std::string> emittedBools;
+  static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
+  std::set<std::string> emittedStrings;
+  static std::string strString = "COMPATIBLE_INTERFACE_STRING";
+  std::set<std::string> emittedMinNumbers;
+  static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
+  std::set<std::string> emittedMaxNumbers;
+  static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
+
+  for(cmComputeLinkInformation::ItemVector::const_iterator li =
+      deps.begin(); li != deps.end(); ++li)
+    {
+    if (!li->Target)
+      {
+      continue;
+      }
+
+    checkPropertyConsistency<bool>(this, li->Target,
+                                strBool,
+                                emittedBools, config, BoolType, 0);
+    if (cmSystemTools::GetErrorOccuredFlag())
+      {
+      return;
+      }
+    checkPropertyConsistency<const char *>(this, li->Target,
+                                strString,
+                                emittedStrings, config,
+                                StringType, 0);
+    if (cmSystemTools::GetErrorOccuredFlag())
+      {
+      return;
+      }
+    checkPropertyConsistency<const char *>(this, li->Target,
+                                strNumMin,
+                                emittedMinNumbers, config,
+                                NumberMinType, 0);
+    if (cmSystemTools::GetErrorOccuredFlag())
+      {
+      return;
+      }
+    checkPropertyConsistency<const char *>(this, li->Target,
+                                strNumMax,
+                                emittedMaxNumbers, config,
+                                NumberMaxType, 0);
+    if (cmSystemTools::GetErrorOccuredFlag())
+      {
+      return;
+      }
+    }
+
+  std::string prop = intersect(emittedBools,
+                               emittedStrings,
+                               emittedMinNumbers,
+                               emittedMaxNumbers);
+
+  if (!prop.empty())
+    {
+    // Use a sorted std::vector to keep the error message sorted.
+    std::vector<std::string> props;
+    std::set<std::string>::const_iterator i = emittedBools.find(prop);
+    if (i != emittedBools.end())
+      {
+      props.push_back(strBool);
+      }
+    i = emittedStrings.find(prop);
+    if (i != emittedStrings.end())
+      {
+      props.push_back(strString);
+      }
+    i = emittedMinNumbers.find(prop);
+    if (i != emittedMinNumbers.end())
+      {
+      props.push_back(strNumMin);
+      }
+    i = emittedMaxNumbers.find(prop);
+    if (i != emittedMaxNumbers.end())
+      {
+      props.push_back(strNumMax);
+      }
+    std::sort(props.begin(), props.end());
+
+    std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", ");
+    propsString += " and the " + props.back();
+
+    std::ostringstream e;
+    e << "Property \"" << prop << "\" appears in both the "
+      << propsString <<
+    " property in the dependencies of target \"" << this->GetName() <<
+    "\".  This is not allowed. A property may only require compatibility "
+    "in a boolean interpretation, a numeric minimum, a numeric maximum or a "
+    "string interpretation, but not a mixture.";
+    this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string compatibilityType(CompatibleType t)
+{
+  switch(t)
+    {
+    case BoolType:
+      return "Boolean compatibility";
+    case StringType:
+      return "String compatibility";
+    case NumberMaxType:
+      return "Numeric maximum compatibility";
+    case NumberMinType:
+      return "Numeric minimum compatibility";
+    }
+  assert(0 && "Unreachable!");
+  return "";
+}
+
+//----------------------------------------------------------------------------
+std::string compatibilityAgree(CompatibleType t, bool dominant)
+{
+  switch(t)
+    {
+    case BoolType:
+    case StringType:
+      return dominant ? "(Disagree)\n" : "(Agree)\n";
+    case NumberMaxType:
+    case NumberMinType:
+      return dominant ? "(Dominant)\n" : "(Ignored)\n";
+    }
+  assert(0 && "Unreachable!");
+  return "";
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop);
+
+//----------------------------------------------------------------------------
+template<>
+bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop)
+{
+  return tgt->GetPropertyAsBool(prop);
+}
+
+//----------------------------------------------------------------------------
+template<>
+const char *getTypedProperty<const char *>(cmTarget const* tgt,
+                                           const std::string& prop)
+{
+  return tgt->GetProperty(prop);
+}
+
+template<typename PropertyType>
+std::string valueAsString(PropertyType);
+template<>
+std::string valueAsString<bool>(bool value)
+{
+  return value ? "TRUE" : "FALSE";
+}
+template<>
+std::string valueAsString<const char*>(const char* value)
+{
+  return value ? value : "(unset)";
+}
+
+template<typename PropertyType>
+PropertyType impliedValue(PropertyType);
+template<>
+bool impliedValue<bool>(bool)
+{
+  return false;
+}
+template<>
+const char* impliedValue<const char*>(const char*)
+{
+  return "";
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
+                                                 PropertyType rhs,
+                                                 CompatibleType t);
+
+//----------------------------------------------------------------------------
+template<>
+std::pair<bool, bool> consistentProperty(bool lhs, bool rhs,
+                                         CompatibleType)
+{
+  return std::make_pair(lhs == rhs, lhs);
+}
+
+//----------------------------------------------------------------------------
+std::pair<bool, const char*> consistentStringProperty(const char *lhs,
+                                                      const char *rhs)
+{
+  const bool b = strcmp(lhs, rhs) == 0;
+  return std::make_pair(b, b ? lhs : 0);
+}
+
+//----------------------------------------------------------------------------
+std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
+                                                   const char *rhs,
+                                                   CompatibleType t)
+{
+  char *pEnd;
+
+  const char* const null_ptr = 0;
+
+  long lnum = strtol(lhs, &pEnd, 0);
+  if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
+    {
+    return std::pair<bool, const char*>(false, null_ptr);
+    }
+
+  long rnum = strtol(rhs, &pEnd, 0);
+  if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
+    {
+    return std::pair<bool, const char*>(false, null_ptr);
+    }
+
+  if (t == NumberMaxType)
+    {
+    return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
+    }
+  else
+    {
+    return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs);
+    }
+}
+
+//----------------------------------------------------------------------------
+template<>
+std::pair<bool, const char*> consistentProperty(const char *lhs,
+                                                const char *rhs,
+                                                CompatibleType t)
+{
+  if (!lhs && !rhs)
+    {
+    return std::make_pair(true, lhs);
+    }
+  if (!lhs)
+    {
+    return std::make_pair(true, rhs);
+    }
+  if (!rhs)
+    {
+    return std::make_pair(true, lhs);
+    }
+
+  const char* const null_ptr = 0;
+
+  switch(t)
+  {
+  case BoolType:
+    assert(0 && "consistentProperty for strings called with BoolType");
+    return std::pair<bool, const char*>(false, null_ptr);
+  case StringType:
+    return consistentStringProperty(lhs, rhs);
+  case NumberMinType:
+  case NumberMaxType:
+    return consistentNumberProperty(lhs, rhs, t);
+  }
+  assert(0 && "Unreachable!");
+  return std::pair<bool, const char*>(false, null_ptr);
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
+                                          const std::string &p,
+                                          const std::string& config,
+                                          const char *defaultValue,
+                                          CompatibleType t,
+                                          PropertyType *)
+{
+  PropertyType propContent = getTypedProperty<PropertyType>(tgt->Target, p);
+  const bool explicitlySet = tgt->Target->GetProperties()
+                                  .find(p)
+                                  != tgt->Target->GetProperties().end();
+  const bool impliedByUse =
+          tgt->Target->IsNullImpliedByLinkLibraries(p);
+  assert((impliedByUse ^ explicitlySet)
+      || (!impliedByUse && !explicitlySet));
+
+  std::vector<cmTarget const*> const& deps =
+    tgt->GetLinkImplementationClosure(config);
+
+  if(deps.empty())
+    {
+    return propContent;
+    }
+  bool propInitialized = explicitlySet;
+
+  std::string report = " * Target \"";
+  report += tgt->GetName();
+  if (explicitlySet)
+    {
+    report += "\" has property content \"";
+    report += valueAsString<PropertyType>(propContent);
+    report += "\"\n";
+    }
+  else if (impliedByUse)
+    {
+    report += "\" property is implied by use.\n";
+    }
+  else
+    {
+    report += "\" property not set.\n";
+    }
+
+  std::string interfaceProperty = "INTERFACE_" + p;
+  for(std::vector<cmTarget const*>::const_iterator li =
+      deps.begin();
+      li != deps.end(); ++li)
+    {
+    // An error should be reported if one dependency
+    // has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other
+    // has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the
+    // target itself has a POSITION_INDEPENDENT_CODE which disagrees
+    // with a dependency.
+
+    cmTarget const* theTarget = *li;
+
+    const bool ifaceIsSet = theTarget->GetProperties()
+                            .find(interfaceProperty)
+                            != theTarget->GetProperties().end();
+    PropertyType ifacePropContent =
+                    getTypedProperty<PropertyType>(theTarget,
+                              interfaceProperty);
+
+    std::string reportEntry;
+    if (ifaceIsSet)
+      {
+      reportEntry += " * Target \"";
+      reportEntry += theTarget->GetName();
+      reportEntry += "\" property value \"";
+      reportEntry += valueAsString<PropertyType>(ifacePropContent);
+      reportEntry += "\" ";
+      }
+
+    if (explicitlySet)
+      {
+      if (ifaceIsSet)
+        {
+        std::pair<bool, PropertyType> consistent =
+                                  consistentProperty(propContent,
+                                                     ifacePropContent, t);
+        report += reportEntry;
+        report += compatibilityAgree(t, propContent != consistent.second);
+        if (!consistent.first)
+          {
+          std::ostringstream e;
+          e << "Property " << p << " on target \""
+            << tgt->GetName() << "\" does\nnot match the "
+            "INTERFACE_" << p << " property requirement\nof "
+            "dependency \"" << theTarget->GetName() << "\".\n";
+          cmSystemTools::Error(e.str().c_str());
+          break;
+          }
+        else
+          {
+          propContent = consistent.second;
+          continue;
+          }
+        }
+      else
+        {
+        // Explicitly set on target and not set in iface. Can't disagree.
+        continue;
+        }
+      }
+    else if (impliedByUse)
+      {
+      propContent = impliedValue<PropertyType>(propContent);
+
+      if (ifaceIsSet)
+        {
+        std::pair<bool, PropertyType> consistent =
+                                  consistentProperty(propContent,
+                                                     ifacePropContent, t);
+        report += reportEntry;
+        report += compatibilityAgree(t, propContent != consistent.second);
+        if (!consistent.first)
+          {
+          std::ostringstream e;
+          e << "Property " << p << " on target \""
+            << tgt->GetName() << "\" is\nimplied to be " << defaultValue
+            << " because it was used to determine the link libraries\n"
+               "already. The INTERFACE_" << p << " property on\ndependency \""
+            << theTarget->GetName() << "\" is in conflict.\n";
+          cmSystemTools::Error(e.str().c_str());
+          break;
+          }
+        else
+          {
+          propContent = consistent.second;
+          continue;
+          }
+        }
+      else
+        {
+        // Implicitly set on target and not set in iface. Can't disagree.
+        continue;
+        }
+      }
+    else
+      {
+      if (ifaceIsSet)
+        {
+        if (propInitialized)
+          {
+          std::pair<bool, PropertyType> consistent =
+                                    consistentProperty(propContent,
+                                                       ifacePropContent, t);
+          report += reportEntry;
+          report += compatibilityAgree(t, propContent != consistent.second);
+          if (!consistent.first)
+            {
+            std::ostringstream e;
+            e << "The INTERFACE_" << p << " property of \""
+              << theTarget->GetName() << "\" does\nnot agree with the value "
+                "of " << p << " already determined\nfor \""
+              << tgt->GetName() << "\".\n";
+            cmSystemTools::Error(e.str().c_str());
+            break;
+            }
+          else
+            {
+            propContent = consistent.second;
+            continue;
+            }
+          }
+        else
+          {
+          report += reportEntry + "(Interface set)\n";
+          propContent = ifacePropContent;
+          propInitialized = true;
+          }
+        }
+      else
+        {
+        // Not set. Nothing to agree on.
+        continue;
+        }
+      }
+    }
+
+  tgt->ReportPropertyOrigin(p, valueAsString<PropertyType>(propContent),
+                            report, compatibilityType(t));
+  return propContent;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetLinkInterfaceDependentBoolProperty(
+    const std::string &p, const std::string& config) const
+{
+  return checkInterfacePropertyCompatibility<bool>(this, p, config,
+                                                   "FALSE",
+                                                   BoolType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetLinkInterfaceDependentStringProperty(
+                                              const std::string &p,
+                                              const std::string& config) const
+{
+  return checkInterfacePropertyCompatibility<const char *>(this,
+                                                           p,
+                                                           config,
+                                                           "empty",
+                                                     StringType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char * cmGeneratorTarget::GetLinkInterfaceDependentNumberMinProperty(
+                                              const std::string &p,
+                                              const std::string& config) const
+{
+  return checkInterfacePropertyCompatibility<const char *>(this,
+                                                           p,
+                                                           config,
+                                                           "empty",
+                                                   NumberMinType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char * cmGeneratorTarget::GetLinkInterfaceDependentNumberMaxProperty(
+                                              const std::string &p,
+                                              const std::string& config) const
+{
+  return checkInterfacePropertyCompatibility<const char *>(this,
+                                                           p,
+                                                           config,
+                                                           "empty",
+                                                   NumberMaxType, 0);
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkInformation*
+cmGeneratorTarget::GetLinkInformation(const std::string& config) const
+{
+  // Lookup any existing information for this configuration.
+  std::string key(cmSystemTools::UpperCase(config));
+  cmTargetLinkInformationMap::iterator
+    i = this->LinkInformation.find(key);
+  if(i == this->LinkInformation.end())
+    {
+    // Compute information for this configuration.
+    cmComputeLinkInformation* info =
+      new cmComputeLinkInformation(this, config);
+    if(!info || !info->Compute())
+      {
+      delete info;
+      info = 0;
+      }
+
+    // Store the information for this configuration.
+    cmTargetLinkInformationMap::value_type entry(key, info);
+    i = this->LinkInformation.insert(entry).first;
+
+    if (info)
+      {
+      this->CheckPropertyCompatibility(info, config);
+      }
+    }
+  return i->second;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
+                               const std::string &result,
+                               const std::string &report,
+                               const std::string &compatibilityType) const
+{
+  std::vector<std::string> debugProperties;
+  const char *debugProp = this->Target->GetMakefile()
+      ->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugOrigin = !this->DebugCompatiblePropertiesDone[p]
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 p)
+                        != debugProperties.end();
+
+  if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+    {
+    this->DebugCompatiblePropertiesDone[p] = true;
+    }
+  if (!debugOrigin)
+    {
+    return;
+    }
+
+  std::string areport = compatibilityType;
+  areport += std::string(" of property \"") + p + "\" for target \"";
+  areport += std::string(this->GetName());
+  areport += "\" (result: \"";
+  areport += result;
+  areport += "\"):\n" + report;
+
+  this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
+                               std::vector<cmLinkItem>& items) const
+{
+  for(std::vector<std::string>::const_iterator i = names.begin();
+      i != names.end(); ++i)
+    {
+    std::string name = this->Target->CheckCMP0004(*i);
+    if(name == this->GetName() || name.empty())
+      {
+      continue;
+      }
+    items.push_back(cmLinkItem(name, this->Target->FindTargetToLink(name)));
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
+                               std::string const& value,
+                               std::string const& config,
+                               cmTarget const* headTarget,
+                               bool usage_requirements_only,
+                               std::vector<cmLinkItem>& items,
+                               bool& hadHeadSensitiveCondition) const
+{
+  cmGeneratorExpression ge;
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
+  // The $<LINK_ONLY> expression may be in a link interface to specify private
+  // link dependencies that are otherwise excluded from usage requirements.
+  if(usage_requirements_only)
+    {
+    dagChecker.SetTransitivePropertiesOnly();
     }
-
-  // Use a helper object to trace the dependencies.
-  cmTargetTraceDependencies tracer(this);
-  tracer.Trace();
+  std::vector<std::string> libs;
+  cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+  cmSystemTools::ExpandListArgument(cge->Evaluate(
+                                      this->Makefile,
+                                      config,
+                                      false,
+                                      headTarget,
+                                      this->Target, &dagChecker), libs);
+  this->LookupLinkItems(libs, items);
+  hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::GetAppleArchs(const std::string& config,
-                             std::vector<std::string>& archVec) const
+cmLinkInterface const*
+cmGeneratorTarget::GetLinkInterface(const std::string& config,
+                                    cmTarget const* head) const
 {
-  const char* archs = 0;
-  if(!config.empty())
+  // Imported targets have their own link interface.
+  if(this->IsImported())
     {
-    std::string defVarName = "OSX_ARCHITECTURES_";
-    defVarName += cmSystemTools::UpperCase(config);
-    archs = this->Target->GetProperty(defVarName);
+    return this->GetImportLinkInterface(config, head, false);
     }
-  if(!archs)
+
+  // Link interfaces are not supported for executables that do not
+  // export symbols.
+  if(this->GetType() == cmTarget::EXECUTABLE &&
+     !this->Target->IsExecutableWithExports())
     {
-    archs = this->Target->GetProperty("OSX_ARCHITECTURES");
+    return 0;
     }
-  if(archs)
+
+  // Lookup any existing link interface for this configuration.
+  cmHeadToLinkInterfaceMap& hm =
+      this->GetHeadToLinkInterfaceMap(config);
+
+  // If the link interface does not depend on the head target
+  // then return the one we computed first.
+  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
     {
-    cmSystemTools::ExpandListArgument(std::string(archs), archVec);
+    return &hm.begin()->second;
+    }
+
+  cmOptionalLinkInterface& iface = hm[head];
+  if(!iface.LibrariesDone)
+    {
+    iface.LibrariesDone = true;
+    this->ComputeLinkInterfaceLibraries(
+      config, iface, head, false);
+    }
+  if(!iface.AllDone)
+    {
+    iface.AllDone = true;
+    if(iface.Exists)
+      {
+      this->ComputeLinkInterface(config, iface, head);
+      }
     }
+
+  return iface.Exists? &iface : 0;
 }
 
 //----------------------------------------------------------------------------
-std::string
-cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
-                                         std::string const& config) const
+void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
+                                    cmOptionalLinkInterface &iface,
+                                    cmTarget const* headTarget) const
 {
-  switch(this->GetType())
+  if(iface.ExplicitLibraries)
     {
-    case cmTarget::STATIC_LIBRARY:
+    if(this->GetType() == cmTarget::SHARED_LIBRARY
+        || this->GetType() == cmTarget::STATIC_LIBRARY
+        || this->GetType() == cmTarget::INTERFACE_LIBRARY)
       {
-      std::string var = "CMAKE_" + lang + "_CREATE_STATIC_LIBRARY";
-      if(this->Target->GetFeatureAsBool(
-           "INTERPROCEDURAL_OPTIMIZATION", config))
+      // Shared libraries may have runtime implementation dependencies
+      // on other shared libraries that are not in the interface.
+      UNORDERED_SET<std::string> emitted;
+      for(std::vector<cmLinkItem>::const_iterator
+          li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
         {
-        std::string varIPO = var + "_IPO";
-        if(this->Makefile->GetDefinition(varIPO))
+        emitted.insert(*li);
+        }
+      if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
+        {
+        cmLinkImplementation const* impl =
+            this->GetLinkImplementation(config);
+        for(std::vector<cmLinkImplItem>::const_iterator
+              li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
           {
-          return varIPO;
+          if(emitted.insert(*li).second)
+            {
+            if(li->Target)
+              {
+              // This is a runtime dependency on another shared library.
+              if(li->Target->GetType() == cmTarget::SHARED_LIBRARY)
+                {
+                iface.SharedDeps.push_back(*li);
+                }
+              }
+            else
+              {
+              // TODO: Recognize shared library file names.  Perhaps this
+              // should be moved to cmComputeLinkInformation, but that creates
+              // a chicken-and-egg problem since this list is needed for its
+              // construction.
+              }
+            }
           }
         }
-      return var;
       }
-    case cmTarget::SHARED_LIBRARY:
-      return "CMAKE_" + lang + "_CREATE_SHARED_LIBRARY";
-    case cmTarget::MODULE_LIBRARY:
-      return "CMAKE_" + lang + "_CREATE_SHARED_MODULE";
-    case cmTarget::EXECUTABLE:
-      return "CMAKE_" + lang + "_LINK_EXECUTABLE";
-    default:
-      break;
     }
-  return "";
+  else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN
+        || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+    {
+    // The link implementation is the default link interface.
+    cmLinkImplementationLibraries const*
+      impl = this->Target->GetLinkImplementationLibrariesInternal(config,
+                                                                headTarget);
+    iface.ImplementationIsInterface = true;
+    iface.WrongConfigLibraries = impl->WrongConfigLibraries;
+    }
+
+  if(this->Target->LinkLanguagePropagatesToDependents())
+    {
+    // Targets using this archive need its language runtime libraries.
+    if(cmLinkImplementation const* impl =
+       this->GetLinkImplementation(config))
+      {
+      iface.Languages = impl->Languages;
+      }
+    }
+
+  if(this->GetType() == cmTarget::STATIC_LIBRARY)
+    {
+    // Construct the property name suffix for this configuration.
+    std::string suffix = "_";
+    if(!config.empty())
+      {
+      suffix += cmSystemTools::UpperCase(config);
+      }
+    else
+      {
+      suffix += "NOCONFIG";
+      }
+
+    // How many repetitions are needed if this library has cyclic
+    // dependencies?
+    std::string propName = "LINK_INTERFACE_MULTIPLICITY";
+    propName += suffix;
+    if(const char* config_reps = this->GetProperty(propName))
+      {
+      sscanf(config_reps, "%u", &iface.Multiplicity);
+      }
+    else if(const char* reps =
+            this->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
+      {
+      sscanf(reps, "%u", &iface.Multiplicity);
+      }
+    }
 }
 
 //----------------------------------------------------------------------------
-std::vector<std::string>
-cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
-                                         const std::string& lang) const
+const cmLinkInterfaceLibraries *
+cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
+                                    cmTarget const* head,
+                                    bool usage_requirements_only) const
 {
-  return this->Target->GetIncludeDirectories(config, lang);
+  // Imported targets have their own link interface.
+  if(this->IsImported())
+    {
+    return this->GetImportLinkInterface(config, head,
+                                                usage_requirements_only);
+    }
+
+  // Link interfaces are not supported for executables that do not
+  // export symbols.
+  if(this->GetType() == cmTarget::EXECUTABLE &&
+     !this->Target->IsExecutableWithExports())
+    {
+    return 0;
+    }
+
+  // Lookup any existing link interface for this configuration.
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  cmHeadToLinkInterfaceMap& hm =
+    (usage_requirements_only ?
+     this->GetHeadToLinkInterfaceUsageRequirementsMap(config) :
+     this->GetHeadToLinkInterfaceMap(config));
+
+  // If the link interface does not depend on the head target
+  // then return the one we computed first.
+  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+    {
+    return &hm.begin()->second;
+    }
+
+  cmOptionalLinkInterface& iface = hm[head];
+  if(!iface.LibrariesDone)
+    {
+    iface.LibrariesDone = true;
+    this->ComputeLinkInterfaceLibraries(
+      config, iface, head, usage_requirements_only);
+    }
+
+  return iface.Exists? &iface : 0;
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::GenerateTargetManifest(
-                                              const std::string& config) const
+void
+cmGeneratorTarget::ComputeLinkInterfaceLibraries(
+  const std::string& config,
+  cmOptionalLinkInterface& iface,
+  cmTarget const* headTarget,
+  bool usage_requirements_only) const
 {
-  if (this->Target->IsImported())
+  // Construct the property name suffix for this configuration.
+  std::string suffix = "_";
+  if(!config.empty())
     {
-    return;
+    suffix += cmSystemTools::UpperCase(config);
+    }
+  else
+    {
+    suffix += "NOCONFIG";
     }
-  cmMakefile* mf = this->Target->GetMakefile();
-  cmGlobalGenerator* gg = mf->GetGlobalGenerator();
 
-  // Get the names.
-  std::string name;
-  std::string soName;
-  std::string realName;
-  std::string impName;
-  std::string pdbName;
-  if(this->GetType() == cmTarget::EXECUTABLE)
+  // An explicit list of interface libraries may be set for shared
+  // libraries and executables that export symbols.
+  const char* explicitLibraries = 0;
+  std::string linkIfaceProp;
+  if(this->Target->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
+     this->Target->GetPolicyStatusCMP0022() != cmPolicies::WARN)
     {
-    this->Target->GetExecutableNames(name, realName, impName, pdbName,
-                                     config);
+    // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
+    linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
+    explicitLibraries = this->GetProperty(linkIfaceProp);
     }
-  else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
-          this->GetType() == cmTarget::SHARED_LIBRARY ||
-          this->GetType() == cmTarget::MODULE_LIBRARY)
+  else if(this->GetType() == cmTarget::SHARED_LIBRARY ||
+          this->Target->IsExecutableWithExports())
     {
-    this->Target->GetLibraryNames(name, soName, realName, impName, pdbName,
-                                  config);
+    // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
+    // shared lib or executable.
+
+    // Lookup the per-configuration property.
+    linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+    linkIfaceProp += suffix;
+    explicitLibraries = this->GetProperty(linkIfaceProp);
+
+    // If not set, try the generic property.
+    if(!explicitLibraries)
+      {
+      linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+      explicitLibraries = this->GetProperty(linkIfaceProp);
+      }
     }
-  else
+
+  if(explicitLibraries &&
+     this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+     !this->PolicyWarnedCMP0022)
     {
-    return;
+    // Compare the explicitly set old link interface properties to the
+    // preferred new link interface property one and warn if different.
+    const char* newExplicitLibraries =
+      this->GetProperty("INTERFACE_LINK_LIBRARIES");
+    if (newExplicitLibraries
+        && strcmp(newExplicitLibraries, explicitLibraries) != 0)
+      {
+      std::ostringstream w;
+      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
+        "Target \"" << this->GetName() << "\" has an "
+        "INTERFACE_LINK_LIBRARIES property which differs from its " <<
+        linkIfaceProp << " properties."
+        "\n"
+        "INTERFACE_LINK_LIBRARIES:\n"
+        "  " << newExplicitLibraries << "\n" <<
+        linkIfaceProp << ":\n"
+        "  " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
+      this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+      this->PolicyWarnedCMP0022 = true;
+      }
     }
 
-  // Get the directory.
-  std::string dir = this->Target->GetDirectory(config, false);
+  // There is no implicit link interface for executables or modules
+  // so if none was explicitly set then there is no link interface.
+  if(!explicitLibraries &&
+     (this->GetType() == cmTarget::EXECUTABLE ||
+      (this->GetType() == cmTarget::MODULE_LIBRARY)))
+    {
+    return;
+    }
+  iface.Exists = true;
+  iface.ExplicitLibraries = explicitLibraries;
 
-  // Add each name.
-  std::string f;
-  if(!name.empty())
+  if(explicitLibraries)
     {
-    f = dir;
-    f += "/";
-    f += name;
-    gg->AddToManifest(config, f);
+    // The interface libraries have been explicitly set.
+    this->ExpandLinkItems(linkIfaceProp, explicitLibraries,
+                                  config,
+                                headTarget, usage_requirements_only,
+                                iface.Libraries,
+                                iface.HadHeadSensitiveCondition);
     }
-  if(!soName.empty())
+  else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN
+        || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+    // If CMP0022 is NEW then the plain tll signature sets the
+    // INTERFACE_LINK_LIBRARIES, so if we get here then the project
+    // cleared the property explicitly and we should not fall back
+    // to the link implementation.
     {
-    f = dir;
-    f += "/";
-    f += soName;
-    gg->AddToManifest(config, f);
+    // The link implementation is the default link interface.
+    cmLinkImplementationLibraries const* impl =
+      this->Target->GetLinkImplementationLibrariesInternal(config,
+                                                           headTarget);
+    iface.Libraries.insert(iface.Libraries.end(),
+                           impl->Libraries.begin(), impl->Libraries.end());
+    if(this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+       !this->PolicyWarnedCMP0022 && !usage_requirements_only)
+      {
+      // Compare the link implementation fallback link interface to the
+      // preferred new link interface property and warn if different.
+      std::vector<cmLinkItem> ifaceLibs;
+      static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
+      if(const char* newExplicitLibraries = this->GetProperty(newProp))
+        {
+        bool hadHeadSensitiveConditionDummy = false;
+        this->ExpandLinkItems(newProp, newExplicitLibraries, config,
+                                    headTarget, usage_requirements_only,
+                                ifaceLibs, hadHeadSensitiveConditionDummy);
+        }
+      if (ifaceLibs != iface.Libraries)
+        {
+        std::string oldLibraries = cmJoin(impl->Libraries, ";");
+        std::string newLibraries = cmJoin(ifaceLibs, ";");
+        if(oldLibraries.empty())
+          { oldLibraries = "(empty)"; }
+        if(newLibraries.empty())
+          { newLibraries = "(empty)"; }
+
+        std::ostringstream w;
+        w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
+          "Target \"" << this->GetName() << "\" has an "
+          "INTERFACE_LINK_LIBRARIES property.  "
+          "This should be preferred as the source of the link interface "
+          "for this library but because CMP0022 is not set CMake is "
+          "ignoring the property and using the link implementation "
+          "as the link interface instead."
+          "\n"
+          "INTERFACE_LINK_LIBRARIES:\n"
+          "  " << newLibraries << "\n"
+          "Link implementation:\n"
+          "  " << oldLibraries << "\n";
+        this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+        this->PolicyWarnedCMP0022 = true;
+        }
+      }
     }
-  if(!realName.empty())
+}
+
+//----------------------------------------------------------------------------
+const cmLinkInterface *
+cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
+                                 cmTarget const* headTarget,
+                                 bool usage_requirements_only) const
+{
+  cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config);
+  if(!info)
     {
-    f = dir;
-    f += "/";
-    f += realName;
-    gg->AddToManifest(config, f);
+    return 0;
     }
-  if(!pdbName.empty())
+
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  cmHeadToLinkInterfaceMap& hm =
+    (usage_requirements_only ?
+     this->GetHeadToLinkInterfaceUsageRequirementsMap(config) :
+     this->GetHeadToLinkInterfaceMap(config));
+
+  // If the link interface does not depend on the head target
+  // then return the one we computed first.
+  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
     {
-    f = dir;
-    f += "/";
-    f += pdbName;
-    gg->AddToManifest(config, f);
+    return &hm.begin()->second;
     }
-  if(!impName.empty())
+
+  cmOptionalLinkInterface& iface = hm[headTarget];
+  if(!iface.AllDone)
     {
-    f = this->Target->GetDirectory(config, true);
-    f += "/";
-    f += impName;
-    gg->AddToManifest(config, f);
+    iface.AllDone = true;
+    iface.Multiplicity = info->Multiplicity;
+    cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
+    this->ExpandLinkItems(info->LibrariesProp, info->Libraries,
+                                  config,
+                          headTarget, usage_requirements_only,
+                          iface.Libraries,
+                          iface.HadHeadSensitiveCondition);
+    std::vector<std::string> deps;
+    cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
+    this->LookupLinkItems(deps, iface.SharedDeps);
     }
+
+  return &iface;
 }
 
-bool cmStrictTargetComparison::operator()(cmTarget const* t1,
-                                          cmTarget const* t2) const
+cmHeadToLinkInterfaceMap&
+cmGeneratorTarget::GetHeadToLinkInterfaceMap(const std::string &config) const
 {
-  int nameResult = strcmp(t1->GetName().c_str(), t2->GetName().c_str());
-  if (nameResult == 0)
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  return this->LinkInterfaceMap[CONFIG];
+}
+
+cmHeadToLinkInterfaceMap&
+cmGeneratorTarget::GetHeadToLinkInterfaceUsageRequirementsMap(
+    const std::string &config) const
+{
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  return this->LinkInterfaceUsageRequirementsOnlyMap[CONFIG];
+}
+
+//----------------------------------------------------------------------------
+const cmLinkImplementation *
+cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
+{
+  // There is no link implementation for imported targets.
+  if(this->Target->IsImported())
     {
-    return strcmp(t1->GetMakefile()->GetCurrentBinaryDirectory(),
-                  t2->GetMakefile()->GetCurrentBinaryDirectory()) < 0;
+    return 0;
     }
-  return nameResult < 0;
+
+  cmOptionalLinkImplementation& impl = this->Target->GetLinkImplMap(config);
+  if(!impl.LibrariesDone)
+    {
+    impl.LibrariesDone = true;
+    this->Target->ComputeLinkImplementationLibraries(config, impl,
+                                                     this->Target);
+    }
+  if(!impl.LanguagesDone)
+    {
+    impl.LanguagesDone = true;
+    this->ComputeLinkImplementationLanguages(config, impl);
+    }
+  return &impl;
 }
 
 //----------------------------------------------------------------------------
-struct cmGeneratorTarget::SourceFileFlags
-cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
+bool cmGeneratorTarget::GetConfigCommonSourceFiles(
+    std::vector<cmSourceFile*>& files) const
 {
-  struct SourceFileFlags flags;
-  this->ConstructSourceFileFlags();
-  std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
-    this->SourceFlagsMap.find(sf);
-  if(si != this->SourceFlagsMap.end())
+  std::vector<std::string> configs;
+  this->Makefile->GetConfigurations(configs);
+  if (configs.empty())
     {
-    flags = si->second;
+    configs.push_back("");
     }
-  else
+
+  std::vector<std::string>::const_iterator it = configs.begin();
+  const std::string& firstConfig = *it;
+  this->Target->GetSourceFiles(files, firstConfig);
+
+  for ( ; it != configs.end(); ++it)
     {
-    // Handle the MACOSX_PACKAGE_LOCATION property on source files that
-    // were not listed in one of the other lists.
-    if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
+    std::vector<cmSourceFile*> configFiles;
+    this->Target->GetSourceFiles(configFiles, *it);
+    if (configFiles != files)
       {
-      flags.MacFolder = location;
-      if(strcmp(location, "Resources") == 0)
+      std::string firstConfigFiles;
+      const char* sep = "";
+      for (std::vector<cmSourceFile*>::const_iterator fi = files.begin();
+           fi != files.end(); ++fi)
         {
-        flags.Type = cmGeneratorTarget::SourceFileTypeResource;
+        firstConfigFiles += sep;
+        firstConfigFiles += (*fi)->GetFullPath();
+        sep = "\n  ";
         }
-      else
+
+      std::string thisConfigFiles;
+      sep = "";
+      for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin();
+           fi != configFiles.end(); ++fi)
         {
-        flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
+        thisConfigFiles += sep;
+        thisConfigFiles += (*fi)->GetFullPath();
+        sep = "\n  ";
         }
+      std::ostringstream e;
+      e << "Target \"" << this->GetName()
+        << "\" has source files which vary by "
+        "configuration. This is not supported by the \""
+        << this->GlobalGenerator->GetName()
+        << "\" generator.\n"
+          "Config \"" << firstConfig << "\":\n"
+          "  " << firstConfigFiles << "\n"
+          "Config \"" << *it << "\":\n"
+          "  " << thisConfigFiles << "\n";
+      this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
+      return false;
       }
     }
-  return flags;
+  return true;
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::ConstructSourceFileFlags() const
+void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
+                            const std::string& config) const
 {
-  if(this->SourceFileFlagsConstructed)
+  std::vector<cmSourceFile*> sourceFiles;
+  this->GetSourceFiles(sourceFiles, config);
+  for(std::vector<cmSourceFile*>::const_iterator
+        i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
     {
-    return;
+    const std::string& lang = (*i)->GetLanguage();
+    if(!lang.empty())
+      {
+      languages.insert(lang);
+      }
     }
-  this->SourceFileFlagsConstructed = true;
 
-  // Process public headers to mark the source files.
-  if(const char* files = this->Target->GetProperty("PUBLIC_HEADER"))
+  std::vector<cmGeneratorTarget*> objectLibraries;
+  std::vector<cmSourceFile const*> externalObjects;
+  if (!this->GlobalGenerator->GetConfigureDoneCMP0026())
     {
-    std::vector<std::string> relFiles;
-    cmSystemTools::ExpandListArgument(files, relFiles);
-    for(std::vector<std::string>::iterator it = relFiles.begin();
-        it != relFiles.end(); ++it)
+    std::vector<cmTarget*> objectTargets;
+    this->Target->GetObjectLibrariesCMP0026(objectTargets);
+    objectLibraries.reserve(objectTargets.size());
+    for (std::vector<cmTarget*>::const_iterator it = objectTargets.begin();
+         it != objectTargets.end(); ++it)
       {
-      if(cmSourceFile* sf = this->Makefile->GetSource(*it))
-        {
-        SourceFileFlags& flags = this->SourceFlagsMap[sf];
-        flags.MacFolder = "Headers";
-        flags.Type = cmGeneratorTarget::SourceFileTypePublicHeader;
-        }
+      objectLibraries.push_back(this->GlobalGenerator
+                                ->GetGeneratorTarget(*it));
       }
     }
-
-  // Process private headers after public headers so that they take
-  // precedence if a file is listed in both.
-  if(const char* files = this->Target->GetProperty("PRIVATE_HEADER"))
+  else
     {
-    std::vector<std::string> relFiles;
-    cmSystemTools::ExpandListArgument(files, relFiles);
-    for(std::vector<std::string>::iterator it = relFiles.begin();
-        it != relFiles.end(); ++it)
+    this->GetExternalObjects(externalObjects, config);
+    for(std::vector<cmSourceFile const*>::const_iterator
+          i = externalObjects.begin(); i != externalObjects.end(); ++i)
       {
-      if(cmSourceFile* sf = this->Makefile->GetSource(*it))
+      std::string objLib = (*i)->GetObjectLibrary();
+      if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
         {
-        SourceFileFlags& flags = this->SourceFlagsMap[sf];
-        flags.MacFolder = "PrivateHeaders";
-        flags.Type = cmGeneratorTarget::SourceFileTypePrivateHeader;
+        objectLibraries.push_back(this->GlobalGenerator
+                                  ->GetGeneratorTarget(tgt));
         }
       }
     }
+  for(std::vector<cmGeneratorTarget*>::const_iterator
+      i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
+    {
+    (*i)->GetLanguages(languages, config);
+    }
+}
 
-  // Mark sources listed as resources.
-  if(const char* files = this->Target->GetProperty("RESOURCE"))
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkImplementationLanguages(
+  const std::string& config,
+  cmOptionalLinkImplementation& impl) const
+{
+  // This target needs runtime libraries for its source languages.
+  std::set<std::string> languages;
+  // Get languages used in our source files.
+  this->GetLanguages(languages, config);
+  // Copy the set of langauges to the link implementation.
+  impl.Languages.insert(impl.Languages.begin(),
+                        languages.begin(), languages.end());
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
+{
+  if (this->Target->GetPropertyAsBool("SKIP_BUILD_RPATH"))
     {
-    std::vector<std::string> relFiles;
-    cmSystemTools::ExpandListArgument(files, relFiles);
-    for(std::vector<std::string>::iterator it = relFiles.begin();
-        it != relFiles.end(); ++it)
-      {
-      if(cmSourceFile* sf = this->Makefile->GetSource(*it))
-        {
-        SourceFileFlags& flags = this->SourceFlagsMap[sf];
-        flags.MacFolder = "Resources";
-        flags.Type = cmGeneratorTarget::SourceFileTypeResource;
-        }
-      }
+    return false;
+    }
+  if(cmLinkImplementationLibraries const* impl =
+     this->Target->GetLinkImplementationLibraries(config))
+    {
+    return !impl->Libraries.empty();
     }
+  return false;
 }
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index c79aa72..916f281 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -12,7 +12,7 @@
 #ifndef cmGeneratorTarget_h
 #define cmGeneratorTarget_h
 
-#include "cmStandardIncludes.h"
+#include "cmLinkItem.h"
 
 class cmCustomCommand;
 class cmGlobalGenerator;
@@ -20,11 +20,26 @@ class cmLocalGenerator;
 class cmMakefile;
 class cmSourceFile;
 class cmTarget;
+class cmComputeLinkInformation;
 
 class cmGeneratorTarget
 {
 public:
-  cmGeneratorTarget(cmTarget*);
+  cmGeneratorTarget(cmTarget*, cmLocalGenerator* lg);
+  ~cmGeneratorTarget();
+
+  cmLocalGenerator* GetLocalGenerator() const;
+
+  bool IsImported() const;
+  const char *GetLocation(const std::string& config) const;
+
+  /** Get the location of the target in the build tree with a placeholder
+      referencing the configuration in the native build system.  This
+      location is suitable for use as the LOCATION target property.  */
+  const char* GetLocationForBuild() const;
+
+  cmComputeLinkInformation*
+    GetLinkInformation(const std::string& config) const;
 
   int GetType() const;
   std::string GetName() const;
@@ -56,6 +71,8 @@ public:
                               const std::string& config) const;
   void GetAppManifest(std::vector<cmSourceFile const*>&,
                       const std::string& config) const;
+  void GetManifests(std::vector<cmSourceFile const*>&,
+                    const std::string& config) const;
   void GetCertificates(std::vector<cmSourceFile const*>&,
                        const std::string& config) const;
   void GetXamlSources(std::vector<cmSourceFile const*>&,
@@ -67,6 +84,101 @@ public:
 
   void ComputeObjectMapping();
 
+  const char* GetFeature(const std::string& feature,
+                         const std::string& config) const;
+  bool GetFeatureAsBool(const std::string& feature,
+                        const std::string& config) const;
+
+  bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
+                         const std::string& config) const;
+  bool IsLinkInterfaceDependentStringProperty(const std::string &p,
+                         const std::string& config) const;
+  bool IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
+                         const std::string& config) const;
+  bool IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
+                         const std::string& config) const;
+
+  bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
+                                             const std::string& config) const;
+
+  const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
+                         const std::string& config) const;
+  const char *GetLinkInterfaceDependentNumberMinProperty(const std::string &p,
+                         const std::string& config) const;
+  const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p,
+                         const std::string& config) const;
+
+  cmLinkInterface const* GetLinkInterface(const std::string& config,
+                                        cmTarget const* headTarget) const;
+  void ComputeLinkInterface(const std::string& config,
+                            cmOptionalLinkInterface& iface,
+                            cmTarget const* head) const;
+
+  cmLinkInterfaceLibraries const*
+    GetLinkInterfaceLibraries(const std::string& config,
+                              cmTarget const* headTarget,
+                              bool usage_requirements_only) const;
+
+  void ComputeLinkInterfaceLibraries(const std::string& config,
+                                     cmOptionalLinkInterface &iface,
+                                     cmTarget const* head,
+                                     bool usage_requirements_only) const;
+
+  /** Get the full path to the target according to the settings in its
+      makefile and the configuration type.  */
+  std::string GetFullPath(const std::string& config="", bool implib = false,
+                          bool realname = false) const;
+  std::string NormalGetFullPath(const std::string& config, bool implib,
+                                bool realname) const;
+  std::string NormalGetRealName(const std::string& config) const;
+
+  /** @return the Mac App directory without the base */
+  std::string GetAppBundleDirectory(const std::string& config,
+                                    bool contentOnly) const;
+
+  /** Return whether this target is an executable Bundle, a framework
+      or CFBundle on Apple.  */
+  bool IsBundleOnApple() const;
+
+  /** Get the full name of the target according to the settings in its
+      makefile.  */
+  std::string GetFullName(const std::string& config="",
+                          bool implib = false) const;
+
+  /** @return the Mac framework directory without the base. */
+  std::string GetFrameworkDirectory(const std::string& config,
+                                    bool rootDir) const;
+
+  /** @return the Mac CFBundle directory without the base */
+  std::string GetCFBundleDirectory(const std::string& config,
+                                   bool contentOnly) const;
+
+  /** Return the install name directory for the target in the
+    * build tree.  For example: "\@rpath/", "\@loader_path/",
+    * or "/full/path/to/library".  */
+  std::string GetInstallNameDirForBuildTree(const std::string& config) const;
+
+  /** Return the install name directory for the target in the
+    * install tree.  For example: "\@rpath/" or "\@loader_path/". */
+  std::string GetInstallNameDirForInstallTree() const;
+
+  /** Get the soname of the target.  Allowed only for a shared library.  */
+  std::string GetSOName(const std::string& config) const;
+
+  void GetFullNameComponents(std::string& prefix,
+                             std::string& base, std::string& suffix,
+                             const std::string& config="",
+                             bool implib = false) const;
+
+  /** Append to @a base the mac content directory and return it. */
+  std::string BuildMacContentDirectory(const std::string& base,
+                                       const std::string& config = "",
+                                       bool contentOnly = true) const;
+
+  /** @return the mac content directory for this target. */
+  std::string GetMacContentDirectory(const std::string& config = 0,
+                                     bool implib = false) const;
+
   cmTarget* Target;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
@@ -74,6 +186,39 @@ public:
 
   std::string GetModuleDefinitionFile(const std::string& config) const;
 
+  /** Link information from the transitive closure of the link
+      implementation and the interfaces of its dependencies.  */
+  struct LinkClosure
+  {
+    // The preferred linker language.
+    std::string LinkerLanguage;
+
+    // Languages whose runtime libraries must be linked.
+    std::vector<std::string> Languages;
+  };
+
+  LinkClosure const* GetLinkClosure(const std::string& config) const;
+  void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
+
+  cmLinkImplementation const*
+    GetLinkImplementation(const std::string& config) const;
+
+  void ComputeLinkImplementationLanguages(const std::string& config,
+                                          cmOptionalLinkImplementation& impl
+                                          ) const;
+
+  // Compute the set of languages compiled by the target.  This is
+  // computed every time it is called because the languages can change
+  // when source file properties are changed and we do not have enough
+  // information to forward these property changes to the targets
+  // until we have per-target object file properties.
+  void GetLanguages(std::set<std::string>& languages,
+                    std::string const& config) const;
+
+  bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
+
+  bool HaveBuildTreeRPATH(const std::string& config) const;
+
   /** Full path with trailing slash to the top-level directory
       holding object files for this target.  Includes the build
       time config name placeholder if needed for the generator.  */
@@ -93,11 +238,22 @@ public:
   std::vector<std::string> GetIncludeDirectories(
       const std::string& config, const std::string& lang) const;
 
+  void GetCompileOptions(std::vector<std::string> &result,
+                         const std::string& config,
+                         const std::string& language) const;
+
+  void GetCompileFeatures(std::vector<std::string> &features,
+                          const std::string& config) const;
+
+  void GetCompileDefinitions(std::vector<std::string> &result,
+                             const std::string& config,
+                             const std::string& language) const;
+
   bool IsSystemIncludeDirectory(const std::string& dir,
                                 const std::string& config) const;
 
   /** Add the target output files to the global generator manifest.  */
-  void GenerateTargetManifest(const std::string& config) const;
+  void ComputeTargetManifest(const std::string& config) const;
 
   /**
    * Trace through the source files in this target and add al source files
@@ -105,10 +261,41 @@ public:
    */
   void TraceDependencies();
 
+  /** Get the directory in which to place the target compiler .pdb file.
+      If the configuration name is given then the generator will add its
+      subdirectory for that configuration.  Otherwise just the canonical
+      compiler pdb output directory is given.  */
+  std::string GetCompilePDBDirectory(const std::string& config = "") const;
+
   /** Get sources that must be built before the given source.  */
   std::vector<cmSourceFile*> const*
   GetSourceDepends(cmSourceFile const* sf) const;
 
+  /** Get the name of the pdb file for the target.  */
+  std::string GetPDBName(const std::string& config="") const;
+
+  /** Whether this library has soname enabled and platform supports it.  */
+  bool HasSOName(const std::string& config) const;
+
+  struct CompileInfo
+  {
+    std::string CompilePdbDir;
+  };
+
+  CompileInfo const* GetCompileInfo(const std::string& config) const;
+
+  typedef std::map<std::string, CompileInfo> CompileInfoMapType;
+  mutable CompileInfoMapType CompileInfoMap;
+
+  /** Get the name of the compiler pdb file for the target.  */
+  std::string GetCompilePDBName(const std::string& config="") const;
+
+  /** Get the path for the MSVC /Fd option for this target.  */
+  std::string GetCompilePDBPath(const std::string& config="") const;
+
+  // Get the target base name.
+  std::string GetOutputName(const std::string& config, bool implib) const;
+
   /**
    * Flags for a given source file as used in this target. Typically assigned
    * via SET_TARGET_PROPERTIES when the property is a list of source files.
@@ -130,6 +317,33 @@ public:
     SourceFileType Type;
     const char* MacFolder; // location inside Mac content folders
   };
+  void GetAutoUicOptions(std::vector<std::string> &result,
+                         const std::string& config) const;
+
+  /** Get the names of the executable needed to generate a build rule
+      that takes into account executable version numbers.  This should
+      be called only on an executable target.  */
+  void GetExecutableNames(std::string& name, std::string& realName,
+                          std::string& impName, std::string& pdbName,
+                          const std::string& config) const;
+
+  /** Get the names of the library needed to generate a build rule
+      that takes into account shared library version numbers.  This
+      should be called only on a library target.  */
+  void GetLibraryNames(std::string& name, std::string& soName,
+                       std::string& realName, std::string& impName,
+                       std::string& pdbName, const std::string& config) const;
+
+  /**
+   * Compute whether this target must be relinked before installing.
+   */
+  bool NeedRelinkBeforeInstall(const std::string& config) const;
+
+  /** Return true if builtin chrpath will work for this target */
+  bool IsChrpathUsed(const std::string& config) const;
+
+  ///! Return the preferred linker language for this target
+  std::string GetLinkerLanguage(const std::string& config = "") const;
 
   struct SourceFileFlags
   GetTargetSourceFileFlags(const cmSourceFile* sf) const;
@@ -145,12 +359,18 @@ public:
     std::vector<cmSourceFile const*> XamlSources;
   };
 
+  void ReportPropertyOrigin(const std::string &p,
+                            const std::string &result,
+                            const std::string &report,
+                            const std::string &compatibilityType) const;
+
+  class TargetPropertyEntry;
+
 private:
   friend class cmTargetTraceDependencies;
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
   typedef std::map<cmSourceFile const*, SourceEntry> SourceEntriesType;
   SourceEntriesType SourceEntries;
-
   mutable std::map<cmSourceFile const*, std::string> Objects;
   std::set<cmSourceFile const*> ExplicitObjectName;
   mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
@@ -159,8 +379,91 @@ private:
   mutable bool SourceFileFlagsConstructed;
   mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
 
+  mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
+
+  std::string GetFullNameInternal(const std::string& config,
+                                  bool implib) const;
+  void GetFullNameInternal(const std::string& config, bool implib,
+                           std::string& outPrefix, std::string& outBase,
+                           std::string& outSuffix) const;
+
+  typedef std::map<std::string, LinkClosure> LinkClosureMapType;
+  mutable LinkClosureMapType LinkClosureMap;
+
+  struct CompatibleInterfacesBase
+  {
+    std::set<std::string> PropsBool;
+    std::set<std::string> PropsString;
+    std::set<std::string> PropsNumberMax;
+    std::set<std::string> PropsNumberMin;
+  };
+  CompatibleInterfacesBase const&
+    GetCompatibleInterfaces(std::string const& config) const;
+
+  struct CompatibleInterfaces: public CompatibleInterfacesBase
+  {
+    CompatibleInterfaces(): Done(false) {}
+    bool Done;
+  };
+  mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
+
+  typedef std::map<std::string, cmComputeLinkInformation*>
+                                                   cmTargetLinkInformationMap;
+  mutable cmTargetLinkInformationMap LinkInformation;
+
+  void CheckPropertyCompatibility(cmComputeLinkInformation *info,
+                                  const std::string& config) const;
+
   cmGeneratorTarget(cmGeneratorTarget const&);
   void operator=(cmGeneratorTarget const&);
+
+  struct LinkImplClosure: public std::vector<cmTarget const*>
+  {
+    LinkImplClosure(): Done(false) {}
+    bool Done;
+  };
+  mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap;
+
+  typedef std::map<std::string, cmHeadToLinkInterfaceMap>
+                                                          LinkInterfaceMapType;
+  mutable LinkInterfaceMapType LinkInterfaceMap;
+  mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
+
+  cmHeadToLinkInterfaceMap&
+  GetHeadToLinkInterfaceMap(std::string const& config) const;
+  cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap(
+      std::string const& config) const;
+
+  cmLinkInterface const*
+    GetImportLinkInterface(const std::string& config, cmTarget const* head,
+                           bool usage_requirements_only) const;
+
+  std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
+  std::vector<TargetPropertyEntry*> CompileOptionsEntries;
+  std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
+  std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
+
+  void ExpandLinkItems(std::string const& prop, std::string const& value,
+                       std::string const& config, cmTarget const* headTarget,
+                       bool usage_requirements_only,
+                       std::vector<cmLinkItem>& items,
+                       bool& hadHeadSensitiveCondition) const;
+  void LookupLinkItems(std::vector<std::string> const& names,
+                       std::vector<cmLinkItem>& items) const;
+
+  typedef std::pair<std::string, bool> OutputNameKey;
+  typedef std::map<OutputNameKey, std::string> OutputNameMapType;
+  mutable OutputNameMapType OutputNameMap;
+  mutable bool PolicyWarnedCMP0022;
+  mutable bool DebugIncludesDone;
+  mutable bool DebugCompileOptionsDone;
+  mutable bool DebugCompileFeaturesDone;
+  mutable bool DebugCompileDefinitionsDone;
+
+public:
+  std::vector<cmTarget const*> const&
+    GetLinkImplementationClosure(const std::string& config) const;
+
 };
 
 struct cmStrictTargetComparison {
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index 76803c1..248ce59 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -32,17 +32,18 @@ bool cmGetCMakePropertyCommand
 
   if ( args[1] == "VARIABLES" )
     {
-    int cacheonly = 0;
-    std::vector<std::string> vars = this->Makefile->GetDefinitions(cacheonly);
-    if (!vars.empty())
+    if (const char* varsProp = this->Makefile->GetProperty("VARIABLES"))
       {
-      output = cmJoin(vars, ";");
+      output = varsProp;
       }
     }
   else if ( args[1] == "MACROS" )
     {
     output.clear();
-    this->Makefile->GetListOfMacros(output);
+    if (const char* macrosProp = this->Makefile->GetProperty("MACROS"))
+      {
+      output = macrosProp;
+      }
     }
   else if ( args[1] == "COMPONENTS" )
     {
@@ -52,9 +53,11 @@ bool cmGetCMakePropertyCommand
     }
   else
     {
-    const char *prop =
-      this->Makefile->GetState()
-          ->GetGlobalProperty(args[1]);
+    const char *prop = 0;
+    if (!args[1].empty())
+      {
+      prop = this->Makefile->GetState()->GetGlobalProperty(args[1]);
+      }
     if (prop)
       {
       output = prop;
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index 4fe3318..2558876 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -26,7 +26,6 @@ bool cmGetDirectoryPropertyCommand
   std::vector<std::string>::const_iterator i = args.begin();
   std::string variable = *i;
   ++i;
-  std::string output = "";
 
   // get the directory argument if there is one
   cmMakefile *dir = this->Makefile;
@@ -52,10 +51,8 @@ bool cmGetDirectoryPropertyCommand
     sd = cmSystemTools::CollapseFullPath(sd);
 
     // lookup the makefile from the directory name
-    cmLocalGenerator *lg =
-      this->Makefile->GetGlobalGenerator()->
-      FindLocalGenerator(sd);
-    if (!lg)
+    dir = this->Makefile->GetGlobalGenerator()->FindMakefile(sd);
+    if (!dir)
       {
       this->SetError
         ("DIRECTORY argument provided but requested directory not found. "
@@ -63,7 +60,6 @@ bool cmGetDirectoryPropertyCommand
          "it is valid but has not been processed yet.");
       return false;
       }
-    dir = lg->GetMakefile();
     ++i;
     }
 
@@ -79,18 +75,45 @@ bool cmGetDirectoryPropertyCommand
                      "providing the name of the variable to get.");
       return false;
       }
-    output = dir->GetSafeDefinition(*i);
+    std::string output = dir->GetSafeDefinition(*i);
     this->Makefile->AddDefinition(variable, output.c_str());
     return true;
     }
 
-  const char *prop = dir->GetProperty(*i);
+  const char *prop = 0;
+  if (!i->empty())
+    {
+    if (*i == "DEFINITIONS")
+      {
+      switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0059))
+        {
+        case cmPolicies::WARN:
+          this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+                           cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
+        case cmPolicies::OLD:
+          this->StoreResult(variable,
+                                   this->Makefile->GetDefineFlagsCMP0059());
+        return true;
+        case cmPolicies::NEW:
+        case cmPolicies::REQUIRED_ALWAYS:
+        case cmPolicies::REQUIRED_IF_USED:
+          break;
+        }
+      }
+    prop = dir->GetProperty(*i);
+    }
+  this->StoreResult(variable, prop);
+  return true;
+}
+
+void cmGetDirectoryPropertyCommand::StoreResult(std::string const& variable,
+                                                const char* prop)
+{
   if (prop)
     {
     this->Makefile->AddDefinition(variable, prop);
-    return true;
+    return;
     }
   this->Makefile->AddDefinition(variable, "");
-  return true;
 }
 
diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h
index 6c5750a..f418886 100644
--- a/Source/cmGetDirectoryPropertyCommand.h
+++ b/Source/cmGetDirectoryPropertyCommand.h
@@ -40,8 +40,9 @@ public:
   virtual std::string GetName() const { return "get_directory_property";}
 
   cmTypeMacro(cmGetDirectoryPropertyCommand, cmCommand);
-};
-
 
+private:
+  void StoreResult(const std::string& variable, const char* prop);
+};
 
 #endif
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 67f9f2d..0f56c8e 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -24,7 +24,7 @@ bool cmGetFilenameComponentCommand
 
   // Check and see if the value has been stored in the cache
   // already, if so use that value
-  if(args.size() == 4 && args[3] == "CACHE")
+  if(args.size() >= 4 && args[args.size() - 1] == "CACHE")
     {
     const char* cacheValue = this->Makefile->GetDefinition(args[0]);
     if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue))
@@ -93,11 +93,23 @@ bool cmGetFilenameComponentCommand
   else if (args[2] == "ABSOLUTE" ||
            args[2] == "REALPATH")
     {
+    // If the path given is relative, evaluate it relative to the
+    // current source directory unless the user passes a different
+    // base directory.
+    std::string baseDir = this->Makefile->GetCurrentSourceDirectory();
+    for(unsigned int i=3; i < args.size(); ++i)
+      {
+      if(args[i] == "BASE_DIR")
+        {
+        ++i;
+        if(i < args.size())
+          {
+          baseDir = args[i];
+          }
+        }
+      }
     // Collapse the path to its simplest form.
-    // If the path given is relative evaluate it relative to the
-    // current source directory.
-    result = cmSystemTools::CollapseFullPath(
-      filename, this->Makefile->GetCurrentSourceDirectory());
+    result = cmSystemTools::CollapseFullPath(filename, baseDir);
     if(args[2] == "REALPATH")
       {
       // Resolve symlinks if possible
@@ -111,7 +123,7 @@ bool cmGetFilenameComponentCommand
     return false;
     }
 
-  if(args.size() == 4 && args[3] == "CACHE")
+  if(args.size() >= 4 && args[args.size() - 1] == "CACHE")
     {
     if(!programArgs.empty() && !storeArgs.empty())
       {
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 250bd35..4c42f53 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -142,8 +142,7 @@ bool cmGetPropertyCommand
     {
     // Lookup brief documentation.
     std::string output;
-    if(cmPropertyDefinition* def =
-       this->Makefile->GetState()->
+    if(cmPropertyDefinition const* def = this->Makefile->GetState()->
        GetPropertyDefinition(this->PropertyName, scope))
       {
       output = def->GetShortDescription();
@@ -158,8 +157,7 @@ bool cmGetPropertyCommand
     {
     // Lookup full documentation.
     std::string output;
-    if(cmPropertyDefinition* def =
-       this->Makefile->GetState()->
+    if(cmPropertyDefinition const* def = this->Makefile->GetState()->
        GetPropertyDefinition(this->PropertyName, scope))
       {
       output = def->GetFullDescription();
@@ -264,13 +262,8 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
     dir = cmSystemTools::CollapseFullPath(dir);
 
     // Lookup the generator.
-    if(cmLocalGenerator* lg =
-       (this->Makefile->GetGlobalGenerator()->FindLocalGenerator(dir)))
-      {
-      // Use the makefile for the directory found.
-      mf = lg->GetMakefile();
-      }
-    else
+    mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+    if (!mf)
       {
       // Could not find the directory.
       this->SetError
@@ -281,6 +274,22 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
       }
     }
 
+  if (this->PropertyName == "DEFINITIONS")
+    {
+    switch(mf->GetPolicyStatus(cmPolicies::CMP0059))
+      {
+      case cmPolicies::WARN:
+        mf->IssueMessage(cmake::AUTHOR_WARNING,
+                         cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
+      case cmPolicies::OLD:
+        return this->StoreResult(mf->GetDefineFlagsCMP0059());
+      case cmPolicies::NEW:
+      case cmPolicies::REQUIRED_ALWAYS:
+      case cmPolicies::REQUIRED_IF_USED:
+        break;
+      }
+    }
+
   // Get the property.
   return this->StoreResult(mf->GetProperty(this->PropertyName));
 }
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index 7667a85..46daa34 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -38,7 +38,11 @@ bool cmGetSourceFilePropertyCommand
       this->Makefile->AddDefinition(var, sf->GetLanguage().c_str());
       return true;
       }
-    const char *prop = sf->GetPropertyForUser(args[2]);
+    const char *prop = 0;
+    if (!args[2].empty())
+      {
+      prop = sf->GetPropertyForUser(args[2]);
+      }
     if (prop)
       {
       this->Makefile->AddDefinition(var, prop);
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index 315e851..ca40bd0 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -40,7 +40,11 @@ bool cmGetTargetPropertyCommand
   else if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName))
     {
     cmTarget& target = *tgt;
-    const char* prop_cstr = target.GetProperty(args[2], this->Makefile);
+    const char* prop_cstr = 0;
+    if (!args[2].empty())
+      {
+      prop_cstr = target.GetProperty(args[2], this->Makefile);
+      }
     if(prop_cstr)
       {
       prop = prop_cstr;
diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx
index b3df4c3..bf34589 100644
--- a/Source/cmGetTestPropertyCommand.cxx
+++ b/Source/cmGetTestPropertyCommand.cxx
@@ -29,7 +29,11 @@ bool cmGetTestPropertyCommand
   cmTest *test = this->Makefile->GetTest(testName);
   if (test)
     {
-    const char *prop = test->GetProperty(args[1]);
+    const char *prop = 0;
+    if (!args[1].empty())
+      {
+      prop = test->GetProperty(args[1]);
+      }
     if (prop)
       {
       this->Makefile->AddDefinition(var, prop);
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 01e2011..cae5c2f 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -21,23 +21,24 @@
 
 std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
 
-cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmTarget *target)
-  : Target(target)
+cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget *target)
+  : Target(target->Target)
+  , GeneratorTarget(target)
   , LocalGenerator(static_cast<cmLocalGhsMultiGenerator *>(
-                     target->GetMakefile()->GetLocalGenerator()))
-  , Makefile(target->GetMakefile())
-  , TargetGroup(DetermineIfTargetGroup(target))
+                     target->GetLocalGenerator()))
+  , Makefile(target->Target->GetMakefile())
+  , TargetGroup(DetermineIfTargetGroup(target->Target))
   , DynamicDownload(false)
 {
-  this->RelBuildFilePath = this->GetRelBuildFilePath(target);
+  this->RelBuildFilePath = this->GetRelBuildFilePath(target->Target);
 
   this->RelOutputFileName =
     this->RelBuildFilePath + this->Target->GetName() + ".a";
 
   this->RelBuildFileName = this->RelBuildFilePath;
-  this->RelBuildFileName += this->GetBuildFileName(target);
+  this->RelBuildFileName += this->GetBuildFileName(target->Target);
 
-  std::string absPathToRoot = this->GetAbsPathToRoot(target);
+  std::string absPathToRoot = this->GetAbsPathToRoot(target->Target);
   absPathToRoot = this->AddSlashIfNeededToPath(absPathToRoot);
   this->AbsBuildFilePath = absPathToRoot + this->RelBuildFilePath;
   this->AbsBuildFileName = absPathToRoot + this->RelBuildFileName;
@@ -127,7 +128,8 @@ void cmGhsMultiTargetGenerator::Generate()
       {
       config = "RELEASE";
       }
-    const std::string language(this->Target->GetLinkerLanguage(config));
+    const std::string language(
+          this->GeneratorTarget->GetLinkerLanguage(config));
     config = cmSystemTools::UpperCase(config);
     this->DynamicDownload = this->DetermineIfDynamicDownload(config, language);
     if (this->DynamicDownload)
@@ -149,10 +151,6 @@ void cmGhsMultiTargetGenerator::Generate()
       this->WriteTargetLinkLibraries();
       }
     this->WriteCustomCommands();
-    if (this->DynamicDownload)
-      {
-      *this->GetFolderBuildStreams() << "    " << this->DDOption << std::endl;
-      }
 
     this->WriteSources(objectSources);
     }
@@ -228,9 +226,11 @@ void cmGhsMultiTargetGenerator::WriteTypeSpecifics(const std::string &config,
       }
     if (this->IsTargetGroup())
       {
-      *this->GetFolderBuildStreams() << "    -non_shared" << std::endl;
-      *this->GetFolderBuildStreams() << "    -o \"" << outputDir
-                                     << outputFilename << ".elf\""
+      *this->GetFolderBuildStreams()
+          << "    {optgroup=GhsCommonOptions} -o \"" << outputDir
+          << outputFilename << ".elf\"" << std::endl;
+      *this->GetFolderBuildStreams() << "    :extraOutputFile=\"" << outputDir
+                                     << outputFilename << ".elf.ael\""
                                      << std::endl;
       }
     else
@@ -328,7 +328,8 @@ void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
   const std::string &config, const std::string &language)
 {
   std::vector<std::string> compileDefinitions;
-  this->Target->GetCompileDefinitions(compileDefinitions, config, language);
+  this->GeneratorTarget->GetCompileDefinitions(compileDefinitions,
+                                               config, language);
   for (std::vector<std::string>::const_iterator cdI =
          compileDefinitions.begin();
        cdI != compileDefinitions.end(); ++cdI)
@@ -341,7 +342,7 @@ void cmGhsMultiTargetGenerator::WriteIncludes(const std::string &config,
                                               const std::string &language)
 {
   std::vector<std::string> includes =
-    this->Target->GetIncludeDirectories(config, language);
+    this->GeneratorTarget->GetIncludeDirectories(config, language);
   for (std::vector<std::string>::const_iterator includes_i = includes.begin();
        includes_i != includes.end(); ++includes_i)
     {
@@ -354,11 +355,11 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries()
 {
   // library directories
   cmTargetDependSet tds =
-    this->GetGlobalGenerator()->GetTargetDirectDepends(*this->Target);
+    this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
   for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end();
        ++tdsI)
     {
-    const cmTarget *tg(*tdsI);
+    const cmTarget *tg = (*tdsI)->Target;
     *this->GetFolderBuildStreams() << "    -L\"" << GetAbsBuildFilePath(tg)
                                    << "\"" << std::endl;
     }
@@ -373,7 +374,6 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries()
     cmTarget *tg(GetGlobalGenerator()->FindTarget(libName));
     if (NULL != tg)
       {
-      cmGhsMultiTargetGenerator gmtg(tg);
       libName = tg->GetName() + ".a";
       }
     *this->GetFolderBuildStreams() << "    -l\"" << libName << "\""
@@ -452,14 +452,17 @@ void cmGhsMultiTargetGenerator::WriteSources(
       this->Makefile->GetHomeOutputDirectory(), sgPath,
       GhsMultiGpj::SUBPROJECT, this->RelBuildFilePath);
 
-    if ((*si)->GetExtension() == ".int")
+    std::string fullSourcePath((*si)->GetFullPath());
+    if ((*si)->GetExtension() == "int" || (*si)->GetExtension() == "bsp")
       {
-      *this->FolderBuildStreams[sgPath] << "\"" << (*si)->GetFullPath() << "\""
-                                        << std::endl;
+      *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
       }
     else
       {
-      *this->FolderBuildStreams[sgPath] << (*si)->GetFullPath() << std::endl;
+      //WORKAROUND: GHS MULTI needs the path to use backslashes without quotes
+      //  to open files in search as of version 6.1.6
+      cmsys::SystemTools::ReplaceString(fullSourcePath, "/", "\\");
+      *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
       }
 
     if ("ld" != (*si)->GetExtension() && "int" != (*si)->GetExtension() &&
@@ -557,7 +560,7 @@ bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const &config,
 {
   bool output;
   std::vector<std::string> options;
-  this->Target->GetCompileOptions(options, config, language);
+  this->GeneratorTarget->GetCompileOptions(options, config, language);
   output =
     options.end() == std::find(options.begin(), options.end(), "-kernel");
   return output;
@@ -586,7 +589,7 @@ bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload(
 {
   std::vector<std::string> options;
   bool output = false;
-  this->Target->GetCompileOptions(options, config, language);
+  this->GeneratorTarget->GetCompileOptions(options, config, language);
   for (std::vector<std::string>::const_iterator options_i = options.begin();
        options_i != options.end(); ++options_i)
     {
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
index 8e81db8..c29a31e 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -27,7 +27,7 @@ class cmCustomCommand;
 class cmGhsMultiTargetGenerator
 {
 public:
-  cmGhsMultiTargetGenerator(cmTarget *target);
+  cmGhsMultiTargetGenerator(cmGeneratorTarget* target);
 
   virtual ~cmGhsMultiTargetGenerator();
 
@@ -100,6 +100,7 @@ private:
                                   const std::string &language);
 
   cmTarget *Target;
+  cmGeneratorTarget* GeneratorTarget;
   cmLocalGhsMultiGenerator *LocalGenerator;
   cmMakefile *Makefile;
   std::string AbsBuildFilePath;
diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx
index 87665a0..40e8d29 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.cxx
+++ b/Source/cmGlobalBorlandMakefileGenerator.cxx
@@ -44,10 +44,10 @@ void cmGlobalBorlandMakefileGenerator
 
 ///! Create a local generator appropriate to this Global Generator
 cmLocalGenerator *cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(
-    cmLocalGenerator* parent, cmState::Snapshot snapshot)
+    cmMakefile *mf)
 {
   cmLocalUnixMakefileGenerator3* lg =
-      new cmLocalUnixMakefileGenerator3(this, parent, snapshot);
+      new cmLocalUnixMakefileGenerator3(this, mf);
   lg->SetMakefileVariableSize(32);
   lg->SetMakeCommandEscapeTargetTwice(true);
   lg->SetBorlandMakeCurlyHack(true);
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index 2ec510d..b59c86d 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -36,8 +36,7 @@ public:
   static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
-  virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
-                                                 cmState::Snapshot snapshot);
+  virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
 
   /**
    * Try to determine system information such as shared library
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
new file mode 100644
index 0000000..dc8e5a7
--- /dev/null
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -0,0 +1,21 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmGlobalCommonGenerator.h"
+
+cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm):
+  cmGlobalGenerator(cm)
+{
+}
+
+cmGlobalCommonGenerator::~cmGlobalCommonGenerator()
+{
+}
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
new file mode 100644
index 0000000..7bb0e55
--- /dev/null
+++ b/Source/cmGlobalCommonGenerator.h
@@ -0,0 +1,27 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmGlobalCommonGenerator_h
+#define cmGlobalCommonGenerator_h
+
+#include "cmGlobalGenerator.h"
+
+/** \class cmGlobalCommonGenerator
+ * \brief Common infrastructure for Makefile and Ninja global generators.
+ */
+class cmGlobalCommonGenerator : public cmGlobalGenerator
+{
+public:
+  cmGlobalCommonGenerator(cmake* cm);
+  ~cmGlobalCommonGenerator();
+};
+
+#endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index cd05c54..4a48b5d 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -22,7 +22,7 @@
 #include "cmake.h"
 #include "cmState.h"
 #include "cmMakefile.h"
-#include "cmQtAutoGenerators.h"
+#include "cmQtAutoGeneratorInitializer.h"
 #include "cmSourceFile.h"
 #include "cmVersion.h"
 #include "cmTargetExport.h"
@@ -30,10 +30,10 @@
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorExpression.h"
-#include "cmGeneratorExpressionEvaluationFile.h"
 #include "cmExportBuildFileGenerator.h"
 #include "cmCPackPropertiesGenerator.h"
 #include "cmAlgorithms.h"
+#include "cmInstallGenerator.h"
 
 #include <cmsys/Directory.hxx>
 #include <cmsys/FStream.hxx>
@@ -70,8 +70,10 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm)
   this->TryCompileTimeout = 0;
 
   this->ExtraGenerator = 0;
-  this->CurrentLocalGenerator = 0;
+  this->CurrentMakefile = 0;
   this->TryCompileOuterMakefile = 0;
+
+  this->ConfigureDoneCMP0026 = false;
 }
 
 cmGlobalGenerator::~cmGlobalGenerator()
@@ -87,18 +89,16 @@ bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p,
     {
     return true;
     }
-  else
-    {
-    std::ostringstream e;
-    e <<
-      "Generator\n"
-      "  " << this->GetName() << "\n"
-      "does not support platform specification, but platform\n"
-      "  " << p << "\n"
-      "was specified.";
-    mf->IssueMessage(cmake::FATAL_ERROR, e.str());
-    return false;
-    }
+
+  std::ostringstream e;
+  e <<
+    "Generator\n"
+    "  " << this->GetName() << "\n"
+    "does not support platform specification, but platform\n"
+    "  " << p << "\n"
+    "was specified.";
+  mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+  return false;
 }
 
 bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
@@ -108,18 +108,15 @@ bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
     {
     return true;
     }
-  else
-    {
-    std::ostringstream e;
-    e <<
-      "Generator\n"
-      "  " << this->GetName() << "\n"
-      "does not support toolset specification, but toolset\n"
-      "  " << ts << "\n"
-      "was specified.";
-    mf->IssueMessage(cmake::FATAL_ERROR, e.str());
-    return false;
-    }
+  std::ostringstream e;
+  e <<
+    "Generator\n"
+    "  " << this->GetName() << "\n"
+    "does not support toolset specification, but toolset\n"
+    "  " << ts << "\n"
+    "was specified.";
+  mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+  return false;
 }
 
 std::string cmGlobalGenerator::SelectMakeProgram(
@@ -438,19 +435,22 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
     {
 #if defined(_WIN32) && !defined(__CYGWIN__)
     /* Windows version number data.  */
-    OSVERSIONINFO osvi;
-    ZeroMemory(&osvi, sizeof(osvi));
-    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    OSVERSIONINFOEXW osviex;
+    ZeroMemory(&osviex, sizeof(osviex));
+    osviex.dwOSVersionInfoSize = sizeof(osviex);
+
 #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
 # pragma warning (push)
 # pragma warning (disable:4996)
 #endif
-    GetVersionEx (&osvi);
+    GetVersionExW((OSVERSIONINFOW*)&osviex);
 #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
 # pragma warning (pop)
 #endif
     std::ostringstream windowsVersionString;
-    windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion;
+    windowsVersionString << osviex.dwMajorVersion << "."
+                         << osviex.dwMinorVersion << "."
+                         << osviex.dwBuildNumber;
     windowsVersionString.str();
     mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
                       windowsVersionString.str().c_str());
@@ -569,6 +569,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
         cmSystemTools::Error("Could not find cmake module file: ",
                              determineCompiler.c_str());
         }
+      if (cmSystemTools::GetFatalErrorOccured())
+        {
+        return;
+        }
       needTestLanguage[lang] = true;
       // Some generators like visual studio should not use the env variables
       // So the global generator can specify that in this variable
@@ -1087,42 +1091,70 @@ void cmGlobalGenerator::ClearEnabledLanguages()
   return this->CMakeInstance->GetState()->ClearEnabledLanguages();
 }
 
+void cmGlobalGenerator::CreateLocalGenerators()
+{
+  cmDeleteAll(this->LocalGenerators);
+  this->LocalGenerators.clear();
+  this->LocalGenerators.reserve(this->Makefiles.size());
+  for (std::vector<cmMakefile*>::const_iterator it = this->Makefiles.begin();
+       it != this->Makefiles.end(); ++it)
+    {
+    this->LocalGenerators.push_back(this->CreateLocalGenerator(*it));
+    }
+}
+
 void cmGlobalGenerator::Configure()
 {
   this->FirstTimeProgress = 0.0f;
   this->ClearGeneratorMembers();
 
-  // start with this directory
-  cmLocalGenerator *lg = this->MakeLocalGenerator();
-  this->LocalGenerators.push_back(lg);
+  cmMakefile* dirMf =
+      new cmMakefile(this, this->GetCMakeInstance()->GetCurrentSnapshot());
+  this->Makefiles.push_back(dirMf);
 
   // set the Start directories
-  lg->GetMakefile()->SetCurrentSourceDirectory
+  dirMf->SetCurrentSourceDirectory
     (this->CMakeInstance->GetHomeDirectory());
-  lg->GetMakefile()->SetCurrentBinaryDirectory
+  dirMf->SetCurrentBinaryDirectory
     (this->CMakeInstance->GetHomeOutputDirectory());
 
   this->BinaryDirectories.insert(
       this->CMakeInstance->GetHomeOutputDirectory());
 
   // now do it
-  lg->Configure();
+  this->ConfigureDoneCMP0026 = false;
+  dirMf->Configure();
+  dirMf->EnforceDirectoryLevelRules();
+
+  this->ConfigureDoneCMP0026 = true;
+
+  // Put a copy of each global target in every directory.
+  cmTargets globalTargets;
+  this->CreateDefaultGlobalTargets(&globalTargets);
+
+  for (unsigned int i = 0; i < this->Makefiles.size(); ++i)
+    {
+    cmMakefile* mf = this->Makefiles[i];
+    cmTargets* targets = &(mf->GetTargets());
+    cmTargets::iterator tit;
+    for ( tit = globalTargets.begin(); tit != globalTargets.end(); ++ tit )
+      {
+      (*targets)[tit->first] = tit->second;
+      (*targets)[tit->first].SetMakefile(mf);
+      }
+    }
 
   // update the cache entry for the number of local generators, this is used
   // for progress
   char num[100];
-  sprintf(num,"%d",static_cast<int>(this->LocalGenerators.size()));
+  sprintf(num,"%d",static_cast<int>(this->Makefiles.size()));
   this->GetCMakeInstance()->AddCacheEntry
-    ("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num,
+    ("CMAKE_NUMBER_OF_MAKEFILES", num,
      "number of local generators", cmState::INTERNAL);
 
   // check for link libraries and include directories containing "NOTFOUND"
   // and for infinite loops
-  this->CheckLocalGenerators();
-
-  // at this point this->LocalGenerators has been filled,
-  // so create the map from project name to vector of local generators
-  this->FillProjectMap();
+  this->CheckTargetProperties();
 
   if ( this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE)
     {
@@ -1151,6 +1183,14 @@ void cmGlobalGenerator::Configure()
     }
 }
 
+void cmGlobalGenerator::CreateGenerationObjects(TargetTypes targetTypes)
+{
+  this->CreateLocalGenerators();
+  cmDeleteAll(this->GeneratorTargets);
+  this->GeneratorTargets.clear();
+  this->CreateGeneratorTargets(targetTypes);
+}
+
 cmExportBuildFileGenerator*
 cmGlobalGenerator::GetExportedTargetsFile(const std::string &filename) const
 {
@@ -1186,7 +1226,7 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const
   return false;
 }
 
-void cmGlobalGenerator::DoGenerate()
+bool cmGlobalGenerator::Compute()
 {
   // Some generators track files replaced during the Generate.
   // Start with an empty vector:
@@ -1195,61 +1235,60 @@ void cmGlobalGenerator::DoGenerate()
   // clear targets to issue warning CMP0042 for
   this->CMP0042WarnTargets.clear();
 
-  this->Generate();
-}
-
-void cmGlobalGenerator::Generate()
-{
   // Check whether this generator is allowed to run.
   if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
     {
-    return;
+    return false;
     }
-
   this->FinalizeTargetCompileInfo();
 
+  this->CreateGenerationObjects();
+
+  // at this point this->LocalGenerators has been filled,
+  // so create the map from project name to vector of local generators
+  this->FillProjectMap();
+
 #ifdef CMAKE_BUILD_WITH_CMAKE
   // Iterate through all targets and set up automoc for those which have
   // the AUTOMOC, AUTOUIC or AUTORCC property set
-  AutogensType autogens;
-  this->CreateQtAutoGeneratorsTargets(autogens);
+  std::vector<cmTarget const*> autogenTargets =
+      this->CreateQtAutoGeneratorsTargets();
 #endif
 
-  // For each existing cmLocalGenerator
   unsigned int i;
 
-  // Put a copy of each global target in every directory.
-  cmTargets globalTargets;
-  this->CreateDefaultGlobalTargets(&globalTargets);
-  for (i = 0; i < this->LocalGenerators.size(); ++i)
-    {
-    cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
-    cmTargets* targets = &(mf->GetTargets());
-    cmTargets::iterator tit;
-    for ( tit = globalTargets.begin(); tit != globalTargets.end(); ++ tit )
-      {
-      (*targets)[tit->first] = tit->second;
-      (*targets)[tit->first].SetMakefile(mf);
-      }
-    }
-
   // Add generator specific helper commands
   for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
     this->LocalGenerators[i]->AddHelperCommands();
     }
 
-  // Create per-target generator information.
-  this->CreateGeneratorTargets();
-
 #ifdef CMAKE_BUILD_WITH_CMAKE
-  for (AutogensType::iterator it = autogens.begin(); it != autogens.end();
-       ++it)
+  for (std::vector<cmTarget const*>::iterator it = autogenTargets.begin();
+       it != autogenTargets.end(); ++it)
     {
-    it->first.SetupAutoGenerateTarget(it->second);
+    cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(*it);
     }
 #endif
 
+  for (i = 0; i < this->LocalGenerators.size(); ++i)
+    {
+    cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
+    std::vector<cmInstallGenerator*>& gens = mf->GetInstallGenerators();
+    for (std::vector<cmInstallGenerator*>::const_iterator git = gens.begin();
+         git != gens.end(); ++git)
+      {
+      (*git)->Compute(this->LocalGenerators[i]);
+      }
+    }
+
+  return true;
+}
+
+void cmGlobalGenerator::Generate()
+{
+  unsigned int i;
+
   // Trace the dependencies, after that no custom commands should be added
   // because their dependencies might not be handled correctly
   for (i = 0; i < this->LocalGenerators.size(); ++i)
@@ -1262,11 +1301,9 @@ void cmGlobalGenerator::Generate()
   // Compute the manifest of main targets generated.
   for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
-    this->LocalGenerators[i]->GenerateTargetManifest();
+    this->LocalGenerators[i]->ComputeTargetManifest();
     }
 
-  this->ProcessEvaluationFiles();
-
   // Compute the inter-target dependencies.
   if(!this->ComputeTargetDepends())
     {
@@ -1275,13 +1312,19 @@ void cmGlobalGenerator::Generate()
 
   // Create a map from local generator to the complete set of targets
   // it builds by default.
-  this->FillLocalGeneratorToTargetMap();
+  this->InitializeProgressMarks();
+
+  this->ProcessEvaluationFiles();
+
+  for (i = 0; i < this->LocalGenerators.size(); ++i)
+    {
+    this->LocalGenerators[i]->ComputeHomeRelativeOutputPath();
+    }
 
   // Generate project files
   for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
-    this->LocalGenerators[i]->GetMakefile()->SetGeneratingBuildSystem();
-    this->SetCurrentLocalGenerator(this->LocalGenerators[i]);
+    this->SetCurrentMakefile(this->LocalGenerators[i]->GetMakefile());
     this->LocalGenerators[i]->Generate();
     if(!this->LocalGenerators[i]->GetMakefile()->IsOn(
       "CMAKE_SKIP_INSTALL_RULES"))
@@ -1293,7 +1336,7 @@ void cmGlobalGenerator::Generate()
       (static_cast<float>(i)+1.0f)/
        static_cast<float>(this->LocalGenerators.size()));
     }
-  this->SetCurrentLocalGenerator(0);
+  this->SetCurrentMakefile(0);
 
   if(!this->GenerateCPackPropertiesFile())
     {
@@ -1350,9 +1393,9 @@ bool cmGlobalGenerator::ComputeTargetDepends()
     {
     return false;
     }
-  std::vector<cmTarget const*> const& targets = ctd.GetTargets();
-  for(std::vector<cmTarget const*>::const_iterator ti = targets.begin();
-      ti != targets.end(); ++ti)
+  std::vector<cmGeneratorTarget const*> const& targets = ctd.GetTargets();
+  for(std::vector<cmGeneratorTarget const*>::const_iterator ti
+      = targets.begin(); ti != targets.end(); ++ti)
     {
     ctd.GetTargetDirectDepends(*ti, this->TargetDependencies[*ti]);
     }
@@ -1360,8 +1403,11 @@ bool cmGlobalGenerator::ComputeTargetDepends()
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
+std::vector<const cmTarget*>
+cmGlobalGenerator::CreateQtAutoGeneratorsTargets()
 {
+  std::vector<const cmTarget*> autogenTargets;
+
 #ifdef CMAKE_BUILD_WITH_CMAKE
   for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
     {
@@ -1372,54 +1418,76 @@ void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
     for(cmTargets::iterator ti = targets.begin();
         ti != targets.end(); ++ti)
       {
+      if (ti->second.GetType() == cmTarget::GLOBAL_TARGET)
+        {
+        continue;
+        }
+      if(ti->second.GetType() != cmTarget::EXECUTABLE &&
+         ti->second.GetType() != cmTarget::STATIC_LIBRARY &&
+         ti->second.GetType() != cmTarget::SHARED_LIBRARY &&
+         ti->second.GetType() != cmTarget::MODULE_LIBRARY &&
+         ti->second.GetType() != cmTarget::OBJECT_LIBRARY)
+        {
+        continue;
+        }
+      if((!ti->second.GetPropertyAsBool("AUTOMOC")
+            && !ti->second.GetPropertyAsBool("AUTOUIC")
+            && !ti->second.GetPropertyAsBool("AUTORCC"))
+          || ti->second.IsImported())
+        {
+        continue;
+        }
+      // don't do anything if there is no Qt4 or Qt5Core (which contains moc):
+      cmMakefile* mf = ti->second.GetMakefile();
+      std::string qtMajorVersion = mf->GetSafeDefinition("QT_VERSION_MAJOR");
+      if (qtMajorVersion == "")
+        {
+        qtMajorVersion = mf->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
+        }
+      if (qtMajorVersion != "4" && qtMajorVersion != "5")
+        {
+        continue;
+        }
+
+      cmQtAutoGeneratorInitializer::InitializeAutogenSources(&ti->second);
       targetNames.push_back(ti->second.GetName());
       }
     for(std::vector<std::string>::iterator ti = targetNames.begin();
         ti != targetNames.end(); ++ti)
       {
-      cmTarget& target = *this->LocalGenerators[i]
+      cmTarget* target = this->LocalGenerators[i]
                               ->GetMakefile()->FindTarget(*ti, true);
-      if(target.GetType() == cmTarget::EXECUTABLE ||
-         target.GetType() == cmTarget::STATIC_LIBRARY ||
-         target.GetType() == cmTarget::SHARED_LIBRARY ||
-         target.GetType() == cmTarget::MODULE_LIBRARY ||
-         target.GetType() == cmTarget::OBJECT_LIBRARY)
-        {
-        if((target.GetPropertyAsBool("AUTOMOC")
-              || target.GetPropertyAsBool("AUTOUIC")
-              || target.GetPropertyAsBool("AUTORCC"))
-            && !target.IsImported())
-          {
-          cmQtAutoGenerators autogen;
-          if(autogen.InitializeAutogenTarget(&target))
-            {
-            autogens.push_back(std::make_pair(autogen, &target));
-            }
-          }
-        }
+      cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
+           this->LocalGenerators[i], target);
+      autogenTargets.push_back(target);
       }
     }
-#else
-  (void)autogens;
 #endif
+  return autogenTargets;
 }
 
 //----------------------------------------------------------------------------
 void cmGlobalGenerator::FinalizeTargetCompileInfo()
 {
   // Construct per-target generator information.
-  for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
+  for(unsigned int i=0; i < this->Makefiles.size(); ++i)
     {
-    cmMakefile *mf = this->LocalGenerators[i]->GetMakefile();
+    cmMakefile *mf = this->Makefiles[i];
 
-    const std::vector<cmValueWithOrigin> noconfig_compile_definitions =
+    const cmStringRange noconfig_compile_definitions =
                                 mf->GetCompileDefinitionsEntries();
+    const cmBacktraceRange noconfig_compile_definitions_bts =
+                                mf->GetCompileDefinitionsBacktraces();
 
     cmTargets& targets = mf->GetTargets();
     for(cmTargets::iterator ti = targets.begin();
         ti != targets.end(); ++ti)
       {
       cmTarget* t = &ti->second;
+      if (t->GetType() == cmTarget::GLOBAL_TARGET)
+        {
+        continue;
+        }
 
       t->AppendBuildInterfaceIncludes();
 
@@ -1428,11 +1496,13 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
         continue;
         }
 
-      for (std::vector<cmValueWithOrigin>::const_iterator it
+      cmBacktraceRange::const_iterator btIt
+          = noconfig_compile_definitions_bts.begin();
+      for (cmStringRange::const_iterator it
                                       = noconfig_compile_definitions.begin();
-          it != noconfig_compile_definitions.end(); ++it)
+          it != noconfig_compile_definitions.end(); ++it, ++btIt)
         {
-        t->InsertCompileDefinition(*it);
+        t->InsertCompileDefinition(*it, *btIt);
         }
 
       cmPolicies::PolicyStatus polSt
@@ -1456,25 +1526,29 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalGenerator::CreateGeneratorTargets(cmMakefile *mf)
+void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes,
+                                               cmLocalGenerator *lg)
 {
   cmGeneratorTargetsType generatorTargets;
-  cmTargets& targets = mf->GetTargets();
-  for(cmTargets::iterator ti = targets.begin();
-      ti != targets.end(); ++ti)
+  cmMakefile* mf = lg->GetMakefile();
+  if (targetTypes == AllTargets)
     {
-    cmTarget* t = &ti->second;
-    cmGeneratorTarget* gt = new cmGeneratorTarget(t);
-    this->ComputeTargetObjectDirectory(gt);
-    this->GeneratorTargets[t] = gt;
-    generatorTargets[t] = gt;
+    cmTargets& targets = mf->GetTargets();
+    for(cmTargets::iterator ti = targets.begin();
+        ti != targets.end(); ++ti)
+      {
+      cmTarget* t = &ti->second;
+      cmGeneratorTarget* gt = new cmGeneratorTarget(t, lg);
+      this->GeneratorTargets[t] = gt;
+      generatorTargets[t] = gt;
+      }
     }
 
   for(std::vector<cmTarget*>::const_iterator
         j = mf->GetOwnedImportedTargets().begin();
       j != mf->GetOwnedImportedTargets().end(); ++j)
     {
-    cmGeneratorTarget* gt = new cmGeneratorTarget(*j);
+    cmGeneratorTarget* gt = new cmGeneratorTarget(*j, lg);
     this->GeneratorTargets[*j] = gt;
     generatorTargets[*j] = gt;
     }
@@ -1482,12 +1556,12 @@ void cmGlobalGenerator::CreateGeneratorTargets(cmMakefile *mf)
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalGenerator::CreateGeneratorTargets()
+void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes)
 {
   // Construct per-target generator information.
   for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
     {
-    this->CreateGeneratorTargets(this->LocalGenerators[i]->GetMakefile());
+    this->CreateGeneratorTargets(targetTypes, this->LocalGenerators[i]);
     }
 }
 
@@ -1498,12 +1572,12 @@ void cmGlobalGenerator::ClearGeneratorMembers()
   cmDeleteAll(this->GeneratorTargets);
   this->GeneratorTargets.clear();
 
-  cmDeleteAll(this->EvaluationFiles);
-  this->EvaluationFiles.clear();
-
   cmDeleteAll(this->BuildExportSets);
   this->BuildExportSets.clear();
 
+  cmDeleteAll(this->Makefiles);
+  this->Makefiles.clear();
+
   cmDeleteAll(this->LocalGenerators);
   this->LocalGenerators.clear();
 
@@ -1511,7 +1585,6 @@ void cmGlobalGenerator::ClearGeneratorMembers()
   this->TargetDependencies.clear();
   this->TotalTargets.clear();
   this->ImportedTargets.clear();
-  this->LocalGeneratorToTargetMap.clear();
   this->ProjectMap.clear();
   this->RuleHashes.clear();
   this->DirectoryContentMap.clear();
@@ -1537,17 +1610,17 @@ void cmGlobalGenerator::ComputeTargetObjectDirectory(cmGeneratorTarget*) const
 {
 }
 
-void cmGlobalGenerator::CheckLocalGenerators()
+void cmGlobalGenerator::CheckTargetProperties()
 {
   std::map<std::string, std::string> notFoundMap;
 //  std::set<std::string> notFoundMap;
   // after it is all done do a ConfigureFinalPass
   cmState* state = this->GetCMakeInstance()->GetState();
-  for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+  for (unsigned int i = 0; i < this->Makefiles.size(); ++i)
     {
-    this->LocalGenerators[i]->ConfigureFinalPass();
+    this->Makefiles[i]->ConfigureFinalPass();
     cmTargets &targets =
-      this->LocalGenerators[i]->GetMakefile()->GetTargets();
+      this->Makefiles[i]->GetTargets();
     for (cmTargets::iterator l = targets.begin();
          l != targets.end(); l++)
       {
@@ -1572,8 +1645,7 @@ void cmGlobalGenerator::CheckLocalGenerators()
           text += "\n    linked by target \"";
           text += l->second.GetName();
           text += "\" in directory ";
-          text+=this->LocalGenerators[i]->GetMakefile()
-                    ->GetCurrentSourceDirectory();
+          text+=this->Makefiles[i]->GetCurrentSourceDirectory();
           notFoundMap[varName] = text;
           }
         }
@@ -1602,15 +1674,14 @@ void cmGlobalGenerator::CheckLocalGenerators()
             }
           std::string text = notFoundMap[varName];
           text += "\n   used as include directory in directory ";
-          text += this->LocalGenerators[i]
-                      ->GetMakefile()->GetCurrentSourceDirectory();
+          text += this->Makefiles[i]->GetCurrentSourceDirectory();
           notFoundMap[varName] = text;
           }
         }
       }
     this->CMakeInstance->UpdateProgress
       ("Configuring", 0.9f+0.1f*(static_cast<float>(i)+1.0f)/
-        static_cast<float>(this->LocalGenerators.size()));
+        static_cast<float>(this->Makefiles.size()));
     }
 
   if(!notFoundMap.empty())
@@ -1644,9 +1715,9 @@ int cmGlobalGenerator::TryCompile(const std::string& srcdir,
   // take the bulk of the time, so try and guess some progress
   // by getting closer and closer to 100 without actually getting there.
   if (!this->CMakeInstance->GetState()->GetInitializedCacheValue
-      ("CMAKE_NUMBER_OF_LOCAL_GENERATORS"))
+      ("CMAKE_NUMBER_OF_MAKEFILES"))
     {
-    // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
+    // If CMAKE_NUMBER_OF_MAKEFILES is not set
     // we are in the first time progress and we have no
     // idea how long it will be.  So, just move 1/10th of the way
     // there each time, and don't go over 95%
@@ -1834,19 +1905,19 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
+void cmGlobalGenerator::AddMakefile(cmMakefile *mf)
 {
-  this->LocalGenerators.push_back(lg);
+  this->Makefiles.push_back(mf);
 
   // update progress
   // estimate how many lg there will be
   const char *numGenC =
     this->CMakeInstance->GetState()->GetInitializedCacheValue
-    ("CMAKE_NUMBER_OF_LOCAL_GENERATORS");
+    ("CMAKE_NUMBER_OF_MAKEFILES");
 
   if (!numGenC)
     {
-    // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
+    // If CMAKE_NUMBER_OF_MAKEFILES is not set
     // we are in the first time progress and we have no
     // idea how long it will be.  So, just move half way
     // there each time, and don't go over 95%
@@ -1861,7 +1932,7 @@ void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
     }
 
   int numGen = atoi(numGenC);
-  float prog = 0.9f*static_cast<float>(this->LocalGenerators.size())/
+  float prog = 0.9f*static_cast<float>(this->Makefiles.size())/
     static_cast<float>(numGen);
   if (prog > 0.9f)
     {
@@ -1883,23 +1954,10 @@ void cmGlobalGenerator::EnableInstallTarget()
   this->InstallTargetEnabled = true;
 }
 
-cmLocalGenerator *
-cmGlobalGenerator::MakeLocalGenerator(cmState::Snapshot snapshot,
-                                      cmLocalGenerator *parent)
-{
-  if (!snapshot.IsValid())
-    {
-    snapshot = this->CMakeInstance->GetCurrentSnapshot();
-    }
-
-  return this->CreateLocalGenerator(parent, snapshot);
-}
-
 cmLocalGenerator*
-cmGlobalGenerator::CreateLocalGenerator(cmLocalGenerator* parent,
-                                        cmState::Snapshot snapshot)
+cmGlobalGenerator::CreateLocalGenerator(cmMakefile* mf)
 {
-  return new cmLocalGenerator(this, parent, snapshot);
+  return new cmLocalGenerator(this, mf);
 }
 
 void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
@@ -1938,41 +1996,51 @@ void cmGlobalGenerator::SetConfiguredFilesPath(cmGlobalGenerator* gen)
     }
 }
 
-bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
-                                   cmLocalGenerator* gen) const
+bool cmGlobalGenerator::IsExcluded(cmState::Snapshot const& rootSnp,
+                       cmState::Snapshot const& snp_) const
 {
-  if(!gen || gen == root)
+  cmState::Snapshot snp = snp_;
+  while (snp.IsValid())
     {
-    // No directory excludes itself.
-    return false;
-    }
+    if(snp == rootSnp)
+      {
+      // No directory excludes itself.
+      return false;
+      }
 
-  if(gen->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
-    {
-    // This directory is excluded from its parent.
-    return true;
+    if(snp.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+      {
+      // This directory is excluded from its parent.
+      return true;
+      }
+    snp = snp.GetBuildsystemDirectoryParent();
     }
+  return false;
+}
 
-  // This directory is included in its parent.  Check whether the
-  // parent is excluded.
-  return this->IsExcluded(root, gen->GetParent());
+bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
+                                   cmLocalGenerator* gen) const
+{
+  assert(gen);
+
+  cmState::Snapshot rootSnp = root->GetStateSnapshot();
+  cmState::Snapshot snp = gen->GetStateSnapshot();
+
+  return this->IsExcluded(rootSnp, snp);
 }
 
 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
-                                   cmTarget const& target) const
+                                   cmGeneratorTarget* target) const
 {
-  if(target.GetType() == cmTarget::INTERFACE_LIBRARY
-      || target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+  if(target->GetType() == cmTarget::INTERFACE_LIBRARY
+      || target->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
     {
     // This target is excluded from its directory.
     return true;
     }
-  else
-    {
-    // This target is included in its directory.  Check whether the
-    // directory is excluded.
-    return this->IsExcluded(root, target.GetMakefile()->GetLocalGenerator());
-    }
+  // This target is included in its directory.  Check whether the
+  // directory is excluded.
+  return this->IsExcluded(root, target->GetLocalGenerator());
 }
 
 void
@@ -1999,65 +2067,37 @@ void cmGlobalGenerator::FillProjectMap()
   for(i = 0; i < this->LocalGenerators.size(); ++i)
     {
     // for each local generator add all projects
-    cmLocalGenerator *lg = this->LocalGenerators[i];
+    cmState::Snapshot snp = this->LocalGenerators[i]->GetStateSnapshot();
     std::string name;
     do
       {
-      if (name != lg->GetMakefile()->GetProjectName())
+      std::string snpProjName = snp.GetProjectName();
+      if (name != snpProjName)
         {
-        name = lg->GetMakefile()->GetProjectName();
+        name = snpProjName;
         this->ProjectMap[name].push_back(this->LocalGenerators[i]);
         }
-      lg = lg->GetParent();
+      snp = snp.GetBuildsystemDirectoryParent();
       }
-    while (lg);
+    while (snp.IsValid());
     }
 }
 
-
-// Build a map that contains a the set of targets used by each local
-// generator directory level.
-void cmGlobalGenerator::FillLocalGeneratorToTargetMap()
+cmMakefile*
+cmGlobalGenerator::FindMakefile(const std::string& start_dir) const
 {
-  this->LocalGeneratorToTargetMap.clear();
-  // Loop over all targets in all local generators.
-  for(std::vector<cmLocalGenerator*>::const_iterator
-        lgi = this->LocalGenerators.begin();
-      lgi != this->LocalGenerators.end(); ++lgi)
+  for(std::vector<cmMakefile*>::const_iterator it =
+      this->Makefiles.begin(); it != this->Makefiles.end(); ++it)
     {
-    cmLocalGenerator* lg = *lgi;
-    cmMakefile* mf = lg->GetMakefile();
-    cmTargets const& targets = mf->GetTargets();
-    for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
+    std::string sd = (*it)->GetCurrentSourceDirectory();
+    if (sd == start_dir)
       {
-      cmTarget const& target = t->second;
-
-      // Consider the directory containing the target and all its
-      // parents until something excludes the target.
-      for(cmLocalGenerator* clg = lg; clg && !this->IsExcluded(clg, target);
-          clg = clg->GetParent())
-        {
-        // This local generator includes the target.
-        std::set<cmTarget const*>& targetSet =
-          this->LocalGeneratorToTargetMap[clg];
-        targetSet.insert(&target);
-
-        // Add dependencies of the included target.  An excluded
-        // target may still be included if it is a dependency of a
-        // non-excluded target.
-        TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
-        for(TargetDependSet::const_iterator ti = tgtdeps.begin();
-            ti != tgtdeps.end(); ++ti)
-          {
-          cmTarget const* ttt = *ti;
-          targetSet.insert(ttt);
-          }
-        }
+      return *it;
       }
     }
+  return 0;
 }
 
-
 ///! Find a local generator by its startdirectory
 cmLocalGenerator*
 cmGlobalGenerator::FindLocalGenerator(const std::string& start_dir) const
@@ -2144,7 +2184,7 @@ inline std::string removeQuotes(const std::string& s)
 
 void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
 {
-  cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
+  cmMakefile* mf = this->Makefiles[0];
   const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
 
   // CPack
@@ -2353,7 +2393,17 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
     if ( cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.' )
       {
       std::string cfgArg = "-DBUILD_TYPE=";
-      cfgArg += mf->GetDefinition("CMAKE_CFG_INTDIR");
+      bool iosPlatform = mf->PlatformIsAppleIos();
+      if(iosPlatform)
+        {
+        cfgArg += "$(CONFIGURATION)";
+        singleLine.push_back(cfgArg);
+        cfgArg = "-DEFFECTIVE_PLATFORM_NAME=$(EFFECTIVE_PLATFORM_NAME)";
+        }
+      else
+        {
+        cfgArg += mf->GetDefinition("CMAKE_CFG_INTDIR");
+        }
       singleLine.push_back(cfgArg);
       }
     singleLine.push_back("-P");
@@ -2443,7 +2493,6 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
 {
   // Package
   cmTarget target;
-  target.GetProperties().SetCMakeInstance(this->CMakeInstance);
   target.SetType(cmTarget::GLOBAL_TARGET, name);
   target.SetProperty("EXCLUDE_FROM_ALL","TRUE");
 
@@ -2513,9 +2562,9 @@ void cmGlobalGenerator::AppendDirectoryForConfig(const std::string&,
 
 //----------------------------------------------------------------------------
 cmGlobalGenerator::TargetDependSet const&
-cmGlobalGenerator::GetTargetDirectDepends(cmTarget const& target)
+cmGlobalGenerator::GetTargetDirectDepends(cmGeneratorTarget const* target)
 {
-  return this->TargetDependencies[&target];
+  return this->TargetDependencies[target];
 }
 
 void cmGlobalGenerator::AddTarget(cmTarget* t)
@@ -2615,9 +2664,10 @@ void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
         continue;
         }
       // put the target in the set of original targets
-      originalTargets.insert(target);
+      cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
+      originalTargets.insert(gt);
       // Get the set of targets that depend on target
-      this->AddTargetDepends(target, projectTargets);
+      this->AddTargetDepends(gt, projectTargets);
       }
     }
 }
@@ -2630,7 +2680,7 @@ bool cmGlobalGenerator::IsRootOnlyTarget(cmTarget* target) const
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalGenerator::AddTargetDepends(cmTarget const* target,
+void cmGlobalGenerator::AddTargetDepends(cmGeneratorTarget const* target,
                                          TargetDependSet& projectTargets)
 {
   // add the target itself
@@ -2638,23 +2688,18 @@ void cmGlobalGenerator::AddTargetDepends(cmTarget const* target,
     {
     // This is the first time we have encountered the target.
     // Recursively follow its dependencies.
-    TargetDependSet const& ts = this->GetTargetDirectDepends(*target);
+    TargetDependSet const& ts = this->GetTargetDirectDepends(target);
     for(TargetDependSet::const_iterator i = ts.begin(); i != ts.end(); ++i)
       {
-      cmTarget const* dtarget = *i;
-      this->AddTargetDepends(dtarget, projectTargets);
+      this->AddTargetDepends(*i, projectTargets);
       }
     }
 }
 
 
 //----------------------------------------------------------------------------
-void cmGlobalGenerator::AddToManifest(const std::string& config,
-                                      std::string const& f)
+void cmGlobalGenerator::AddToManifest(std::string const& f)
 {
-  // Add to the main manifest for this configuration.
-  this->TargetManifest[config].insert(f);
-
   // Add to the content listing for the file's directory.
   std::string dir = cmSystemTools::GetFilenamePath(f);
   std::string file = cmSystemTools::GetFilenameName(f);
@@ -2722,9 +2767,9 @@ cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
   }
 
   // Shorten the output name (in expected use case).
-  cmLocalGenerator* lg = this->GetLocalGenerators()[0];
-  std::string fname = lg->Convert(outputs[0],
-                                  cmLocalGenerator::HOME_OUTPUT);
+  cmOutputConverter converter(this->GetMakefiles()[0]->GetStateSnapshot());
+  std::string fname = converter.Convert(
+        outputs[0], cmLocalGenerator::HOME_OUTPUT);
 
   // Associate the hash with this output.
   this->RuleHashes[fname] = hash;
@@ -2974,61 +3019,21 @@ cmGlobalGenerator::GetFilenameTargetDepends(cmSourceFile* sf) const {
 void cmGlobalGenerator::CreateEvaluationSourceFiles(
                                               std::string const& config) const
 {
-  for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
-      li = this->EvaluationFiles.begin();
-      li != this->EvaluationFiles.end();
-      ++li)
+  unsigned int i;
+  for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
-    (*li)->CreateOutputFile(config);
+    this->LocalGenerators[i]->CreateEvaluationFileOutputs(config);
     }
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalGenerator::AddEvaluationFile(const std::string &inputFile,
-                    cmsys::auto_ptr<cmCompiledGeneratorExpression> outputExpr,
-                    cmMakefile *makefile,
-                    cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
-                    bool inputIsContent)
-{
-  this->EvaluationFiles.push_back(
-              new cmGeneratorExpressionEvaluationFile(inputFile, outputExpr,
-                                                      makefile, condition,
-                                                      inputIsContent));
-}
-
-//----------------------------------------------------------------------------
 void cmGlobalGenerator::ProcessEvaluationFiles()
 {
   std::vector<std::string> generatedFiles;
-  for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
-      li = this->EvaluationFiles.begin();
-      li != this->EvaluationFiles.end();
-      ++li)
+  unsigned int i;
+  for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
-    (*li)->Generate();
-    if (cmSystemTools::GetFatalErrorOccured())
-      {
-      return;
-      }
-    std::vector<std::string> files = (*li)->GetFiles();
-    std::sort(files.begin(), files.end());
-
-    std::vector<std::string> intersection;
-    std::set_intersection(files.begin(), files.end(),
-                          generatedFiles.begin(), generatedFiles.end(),
-                          std::back_inserter(intersection));
-    if (!intersection.empty())
-      {
-      cmSystemTools::Error("Files to be generated by multiple different "
-        "commands: ", cmWrap('"', intersection, '"', " ").c_str());
-      return;
-      }
-
-        generatedFiles.insert(generatedFiles.end(),
-                              files.begin(), files.end());
-    std::vector<std::string>::iterator newIt =
-        generatedFiles.end() - files.size();
-    std::inplace_merge(generatedFiles.begin(), newIt, generatedFiles.end());
+    this->LocalGenerators[i]->ProcessEvaluationFiles(generatedFiles);
     }
 }
 
@@ -3045,7 +3050,8 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
   cmake::InstalledFilesMap const& installedFiles =
     this->CMakeInstance->GetInstalledFiles();
 
-  cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
+  cmLocalGenerator* lg = this->LocalGenerators[0];
+  cmMakefile* mf = lg->GetMakefile();
 
   std::vector<std::string> configs;
   std::string config = mf->GetConfigurations(configs, false);
@@ -3067,7 +3073,7 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
     cmInstalledFile const& installedFile = i->second;
 
     cmCPackPropertiesGenerator cpackPropertiesGenerator(
-      mf, installedFile, configs);
+      lg, installedFile, configs);
 
     cpackPropertiesGenerator.Generate(file, config, configs);
     }
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 979e971..ba74c9e 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -34,7 +34,6 @@
 
 class cmake;
 class cmGeneratorTarget;
-class cmGeneratorExpressionEvaluationFile;
 class cmMakefile;
 class cmLocalGenerator;
 class cmExternalMakefileProjectGenerator;
@@ -42,7 +41,6 @@ class cmTarget;
 class cmInstallTargetGenerator;
 class cmInstallFilesGenerator;
 class cmExportBuildFileGenerator;
-class cmQtAutoGenerators;
 
 /** \class cmGlobalGenerator
  * \brief Responsible for overseeing the generation process for the entire tree
@@ -57,9 +55,8 @@ public:
   cmGlobalGenerator(cmake* cm);
   virtual ~cmGlobalGenerator();
 
-  cmLocalGenerator* MakeLocalGenerator(
-      cmState::Snapshot snapshot = cmState::Snapshot(),
-      cmLocalGenerator* parent = 0);
+  virtual cmLocalGenerator*
+  CreateLocalGenerator(cmMakefile* mf);
 
   ///! Get the name for this generator
   virtual std::string GetName() const { return "Generic"; }
@@ -86,12 +83,21 @@ public:
    */
   virtual void Configure();
 
+  virtual bool Compute();
+
+  enum TargetTypes {
+    AllTargets,
+    ImportedOnly
+  };
+
+  void CreateGenerationObjects(TargetTypes targetTypes = AllTargets);
+
   /**
    * Generate the all required files for building this project/tree. This
    * basically creates a series of LocalGenerators for each directory and
    * requests that they Generate.
    */
-  void DoGenerate();
+  virtual void Generate();
 
   /**
    * Set/Get and Clear the enabled languages.
@@ -117,7 +123,7 @@ public:
   /**
    * Try to determine system information, get it from another generator
    */
-  virtual void EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
+  void EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
                                             cmMakefile* mf);
 
   /**
@@ -165,16 +171,20 @@ public:
   cmake *GetCMakeInstance() const { return this->CMakeInstance; }
 
   void SetConfiguredFilesPath(cmGlobalGenerator* gen);
+  const std::vector<cmMakefile*>& GetMakefiles() const {
+    return this->Makefiles;}
   const std::vector<cmLocalGenerator *>& GetLocalGenerators() const {
     return this->LocalGenerators;}
 
-  cmLocalGenerator* GetCurrentLocalGenerator()
-                                          {return this->CurrentLocalGenerator;}
+  cmMakefile* GetCurrentMakefile() const
+  {
+    return this->CurrentMakefile;
+  }
 
-  void SetCurrentLocalGenerator(cmLocalGenerator* lg)
-                                            {this->CurrentLocalGenerator = lg;}
+  void SetCurrentMakefile(cmMakefile* mf)
+  {this->CurrentMakefile = mf;}
 
-  void AddLocalGenerator(cmLocalGenerator *lg);
+  void AddMakefile(cmMakefile *mf);
 
   ///! Set an generator for an "external makefile based project"
   void SetExternalMakefileProjectGenerator(
@@ -190,7 +200,7 @@ public:
   cmExportSetMap& GetExportSets() {return this->ExportSets;}
 
   /** Add a file to the manifest of generated targets for a configuration.  */
-  void AddToManifest(const std::string& config, std::string const& f);
+  void AddToManifest(std::string const& f);
 
   void EnableInstallTarget();
 
@@ -229,7 +239,7 @@ public:
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
   /** Is this the Visual Studio 6 generator?  */
-  virtual bool IsForVS6() const { return false; }
+  bool IsForVS6() const { return this->GetName() == "Visual Studio 6"; }
 #endif
 
   ///! Find a target by name by searching the local generators.
@@ -243,6 +253,7 @@ public:
       that is a framework. */
   bool NameResolvesToFramework(const std::string& libname) const;
 
+  cmMakefile* FindMakefile(const std::string& start_dir) const;
   ///! Find a local generator by its startdirectory
   cmLocalGenerator* FindLocalGenerator(const std::string& start_dir) const;
 
@@ -254,11 +265,6 @@ public:
                                         const std::string& suffix,
                                         std::string& dir);
 
-  /** Get the manifest of all targets that will be built for each
-      configuration.  This is valid during generation only.  */
-  cmTargetManifest const& GetTargetManifest() const
-    { return this->TargetManifest; }
-
   /** Get the content of a directory.  Directory listings are cached
       and re-loaded from disk only when modified.  During the generation
       step the content will include the target files to be built even if
@@ -290,11 +296,17 @@ public:
 
   // what targets does the specified target depend on directly
   // via a target_link_libraries or add_dependencies
-  TargetDependSet const& GetTargetDirectDepends(cmTarget const& target);
+  TargetDependSet const& GetTargetDirectDepends(
+      const cmGeneratorTarget* target);
 
   /** Get per-target generator information.  */
   cmGeneratorTarget* GetGeneratorTarget(cmTarget const*) const;
 
+  void AddGeneratorTarget(cmTarget* t, cmGeneratorTarget* gt)
+  {
+    this->GeneratorTargets[t] = gt;
+  }
+
   const std::map<std::string, std::vector<cmLocalGenerator*> >& GetProjectMap()
                                                const {return this->ProjectMap;}
 
@@ -310,8 +322,6 @@ public:
     {
     return this->BinaryDirectories.insert(dir).second;
     }
-  /** Supported systems creates a GUID for the given name */
-  virtual void CreateGUID(const std::string&) {}
 
   /** Return true if the generated build tree may contain multiple builds.
       i.e. "Can I build Debug and Release in the same tree?" */
@@ -324,12 +334,6 @@ public:
 
   static std::string EscapeJSON(const std::string& s);
 
-  void AddEvaluationFile(const std::string &inputFile,
-                  cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
-                  cmMakefile *makefile,
-                  cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
-                  bool inputIsContent);
-
   void ProcessEvaluationFiles();
 
   std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets()
@@ -357,10 +361,10 @@ public:
   cmFileLockPool& GetFileLockPool() { return FileLockPool; }
 #endif
 
+  bool GetConfigureDoneCMP0026() const { return this->ConfigureDoneCMP0026; }
+
   std::string MakeSilentFlag;
 protected:
-  virtual void Generate();
-
   typedef std::vector<cmLocalGenerator*> GeneratorVector;
   // for a project collect all its targets by following depend
   // information, and also collect all the targets
@@ -368,19 +372,19 @@ protected:
                              TargetDependSet& originalTargets,
                              cmLocalGenerator* root, GeneratorVector const&);
   bool IsRootOnlyTarget(cmTarget* target) const;
-  void AddTargetDepends(cmTarget const* target,
+  void AddTargetDepends(const cmGeneratorTarget* target,
                         TargetDependSet& projectTargets);
   void SetLanguageEnabledFlag(const std::string& l, cmMakefile* mf);
   void SetLanguageEnabledMaps(const std::string& l, cmMakefile* mf);
   void FillExtensionToLanguageMap(const std::string& l, cmMakefile* mf);
+  virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
+                                   const char* envVar) const;
 
   virtual bool ComputeTargetDepends();
 
   virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
 
-  typedef std::vector<std::pair<cmQtAutoGenerators,
-                                cmTarget const*> > AutogensType;
-  void CreateQtAutoGeneratorsTargets(AutogensType& autogens);
+  std::vector<cmTarget const*> CreateQtAutoGeneratorsTargets();
 
   std::string SelectMakeProgram(const std::string& makeProgram,
                                 const std::string& makeDefault = "") const;
@@ -388,42 +392,34 @@ protected:
   // Fill the ProjectMap, this must be called after LocalGenerators
   // has been populated.
   void FillProjectMap();
-  void CheckLocalGenerators();
+  void CheckTargetProperties();
+  bool IsExcluded(cmState::Snapshot const& root,
+                  cmState::Snapshot const& snp) const;
   bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
-  bool IsExcluded(cmLocalGenerator* root, cmTarget const& target) const;
-  void FillLocalGeneratorToTargetMap();
+  bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const;
+  virtual void InitializeProgressMarks() {}
   void CreateDefaultGlobalTargets(cmTargets* targets);
   cmTarget CreateGlobalTarget(const std::string& name, const char* message,
     const cmCustomCommandLines* commandLines,
     std::vector<std::string> depends, const char* workingDir,
     bool uses_terminal);
 
-  bool NeedSymbolicMark;
-  bool UseLinkScript;
-  bool ForceUnixPaths;
-  bool ToolSupportsColor;
   std::string FindMakeProgramFile;
   std::string ConfiguredFilesPath;
   cmake *CMakeInstance;
+  std::vector<cmMakefile*> Makefiles;
   std::vector<cmLocalGenerator *> LocalGenerators;
-  cmLocalGenerator* CurrentLocalGenerator;
+  cmMakefile* CurrentMakefile;
   // map from project name to vector of local generators in that project
   std::map<std::string, std::vector<cmLocalGenerator*> > ProjectMap;
-  std::map<cmLocalGenerator*, std::set<cmTarget const*> >
-                                                    LocalGeneratorToTargetMap;
 
   // Set of named installation components requested by the project.
   std::set<std::string> InstallComponents;
-  bool InstallTargetEnabled;
   // Sets of named target exports
   cmExportSetMap ExportSets;
   std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets;
   std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets;
 
-  // Manifest of all targets that will be built for each configuration.
-  // This is computed just before local generators generate.
-  cmTargetManifest TargetManifest;
-
   // All targets in the entire project.
 #if defined(CMAKE_BUILD_WITH_CMAKE)
 #ifdef CMake_HAVE_CXX11_UNORDERED_MAP
@@ -437,18 +433,12 @@ protected:
   TargetMap TotalTargets;
   TargetMap AliasTargets;
   TargetMap ImportedTargets;
-  std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
 
   const char* GetPredefinedTargetsFolder();
   virtual bool UseFolderProperty();
 
 private:
-  ///! Create a local generator appropriate to this Global Generator
-  virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
-                                                 cmState::Snapshot snapshot);
-
   cmMakefile* TryCompileOuterMakefile;
-  float FirstTimeProgress;
   // If you add a new map here, make sure it is copied
   // in EnableLanguagesFromGenerator
   std::map<std::string, bool> IgnoreExtensions;
@@ -472,8 +462,8 @@ private:
 
   virtual void ForceLinkerLanguages();
 
-  virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
-                                   const char* envVar) const;
+  void CreateLocalGenerators();
+
   void CheckCompilerIdCompatibility(cmMakefile* mf,
                                     std::string const& lang) const;
 
@@ -483,14 +473,14 @@ private:
   std::vector<std::string> FilesReplacedDuringGenerate;
 
   // Store computed inter-target dependencies.
-  typedef std::map<cmTarget const*, TargetDependSet> TargetDependMap;
+  typedef std::map<cmGeneratorTarget const*, TargetDependSet> TargetDependMap;
   TargetDependMap TargetDependencies;
 
   // Per-target generator information.
   cmGeneratorTargetsType GeneratorTargets;
   friend class cmake;
-  void CreateGeneratorTargets(cmMakefile* mf);
-  void CreateGeneratorTargets();
+  void CreateGeneratorTargets(TargetTypes targetTypes, cmLocalGenerator* lg);
+  void CreateGeneratorTargets(TargetTypes targetTypes);
 
   void ClearGeneratorMembers();
 
@@ -521,6 +511,15 @@ private:
   // Pool of file locks
   cmFileLockPool FileLockPool;
 #endif
+
+protected:
+  float FirstTimeProgress;
+  bool NeedSymbolicMark;
+  bool UseLinkScript;
+  bool ForceUnixPaths;
+  bool ToolSupportsColor;
+  bool InstallTargetEnabled;
+  bool ConfigureDoneCMP0026;
 };
 
 #endif
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index f764418..6dde1e3 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -33,10 +33,9 @@ cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator()
 }
 
 cmLocalGenerator *
-cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmLocalGenerator* parent,
-                                                cmState::Snapshot snapshot)
+cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmMakefile* mf)
 {
-  return new cmLocalGhsMultiGenerator(this, parent, snapshot);
+  return new cmLocalGhsMultiGenerator(this, mf);
 }
 
 void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry &entry)
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index f1a3ed7..8f88d4f 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -31,8 +31,7 @@ public:
   { return new cmGlobalGeneratorSimpleFactory<cmGlobalGhsMultiGenerator>(); }
 
   ///! create the correct local generator
-  virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
-                                                 cmState::Snapshot snapshot);
+  virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
 
   /// @return the name of this generator.
   static std::string GetActualName() { return "Green Hills MULTI"; }
diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx
index 50e7053..3f33f91 100644
--- a/Source/cmGlobalJOMMakefileGenerator.cxx
+++ b/Source/cmGlobalJOMMakefileGenerator.cxx
@@ -36,18 +36,6 @@ void cmGlobalJOMMakefileGenerator
   // pick a default
   mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
   mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
-  if(!(cmSystemTools::GetEnv("INCLUDE") &&
-       cmSystemTools::GetEnv("LIB"))
-    )
-    {
-    std::string message = "To use the JOM generator, cmake must be run "
-      "from a shell that can use the compiler cl from the command line. "
-      "This environment does not contain INCLUDE, LIB, or LIBPATH, and "
-      "these must be set for the cl compiler to work. ";
-    mf->IssueMessage(cmake::WARNING,
-                     message);
-    }
-
   this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
 }
 
@@ -58,3 +46,19 @@ void cmGlobalJOMMakefileGenerator
   entry.Name = cmGlobalJOMMakefileGenerator::GetActualName();
   entry.Brief = "Generates JOM makefiles.";
 }
+
+//----------------------------------------------------------------------------
+void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice(std::ostream& os,
+                                                  std::string const& lang,
+                                                  const char* envVar) const
+{
+  if(lang == "CXX" || lang == "C")
+    {
+    os <<
+      "To use the JOM generator with Visual C++, cmake must be run from a "
+      "shell that can use the compiler cl from the command line. This "
+      "environment is unable to invoke the cl compiler. To fix this problem, "
+      "run cmake from the Visual Studio Command Prompt (vcvarsall.bat).\n";
+    }
+  this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar);
+}
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index 2185b23..1869fed 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -42,6 +42,9 @@ public:
    */
   virtual void EnableLanguage(std::vector<std::string>const& languages,
                               cmMakefile *, bool optional);
+private:
+  void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
+                           const char* envVar) const;
 };
 
 #endif
diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx
index 98557cc..138ddbb 100644
--- a/Source/cmGlobalKdevelopGenerator.cxx
+++ b/Source/cmGlobalKdevelopGenerator.cxx
@@ -70,13 +70,13 @@ void cmGlobalKdevelopGenerator::Generate()
          lg!=lgs.end(); lg++)
       {
       cmMakefile* makefile=(*lg)->GetMakefile();
-      cmTargets& targets=makefile->GetTargets();
-      for (cmTargets::iterator ti = targets.begin();
+      cmGeneratorTargetsType const& targets = makefile->GetGeneratorTargets();
+      for (cmGeneratorTargetsType::const_iterator ti = targets.begin();
            ti != targets.end(); ti++)
         {
-        if (ti->second.GetType()==cmTarget::EXECUTABLE)
+        if (ti->second->GetType()==cmTarget::EXECUTABLE)
           {
-          executable = ti->second.GetLocation("");
+          executable = ti->second->GetLocation("");
           break;
           }
         }
diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx
index a84923b..9a6f3ba 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.cxx
+++ b/Source/cmGlobalMSYSMakefileGenerator.cxx
@@ -62,19 +62,19 @@ void cmGlobalMSYSMakefileGenerator
   locations.push_back("c:/mingw/bin");
   std::string tgcc = cmSystemTools::FindProgram("gcc", locations);
   std::string gcc = "gcc.exe";
-  if(tgcc.size())
+  if(!tgcc.empty())
     {
     gcc = tgcc;
     }
   std::string tgxx = cmSystemTools::FindProgram("g++", locations);
   std::string gxx = "g++.exe";
-  if(tgxx.size())
+  if(!tgxx.empty())
     {
     gxx = tgxx;
     }
   std::string trc = cmSystemTools::FindProgram("windres", locations);
   std::string rc = "windres.exe";
-  if(trc.size())
+  if(!trc.empty())
     {
     rc = trc;
     }
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
index 4219c34..7c570a6 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.cxx
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -36,18 +36,6 @@ void cmGlobalNMakeMakefileGenerator
   // pick a default
   mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
   mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
-  if(!(cmSystemTools::GetEnv("INCLUDE") &&
-       cmSystemTools::GetEnv("LIB"))
-    )
-    {
-    std::string message = "To use the NMake generator, cmake must be run "
-      "from a shell that can use the compiler cl from the command line. "
-      "This environment does not contain INCLUDE, LIB, or LIBPATH, and "
-      "these must be set for the cl compiler to work. ";
-    mf->IssueMessage(cmake::WARNING,
-                     message);
-    }
-
   this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
 }
 
@@ -58,3 +46,19 @@ void cmGlobalNMakeMakefileGenerator
   entry.Name = cmGlobalNMakeMakefileGenerator::GetActualName();
   entry.Brief = "Generates NMake makefiles.";
 }
+
+//----------------------------------------------------------------------------
+void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice(std::ostream& os,
+                                                  std::string const& lang,
+                                                  const char* envVar) const
+{
+  if(lang == "CXX" || lang == "C")
+    {
+    os <<
+      "To use the NMake generator with Visual C++, cmake must be run from a "
+      "shell that can use the compiler cl from the command line. This "
+      "environment is unable to invoke the cl compiler. To fix this problem, "
+      "run cmake from the Visual Studio Command Prompt (vcvarsall.bat).\n";
+    }
+  this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar);
+}
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index dd72c49..3c8375a 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -40,6 +40,9 @@ public:
    */
   virtual void EnableLanguage(std::vector<std::string>const& languages,
                               cmMakefile *, bool optional);
+private:
+  void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
+                           const char* envVar) const;
 };
 
 #endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 103d75a..9d8193b 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -505,7 +505,7 @@ void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os,
 
 
 cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
-  : cmGlobalGenerator(cm)
+  : cmGlobalCommonGenerator(cm)
   , BuildFileStream(0)
   , RulesFileStream(0)
   , CompileCommandsStream(0)
@@ -528,10 +528,9 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
 // Virtual public methods.
 
 cmLocalGenerator*
-cmGlobalNinjaGenerator::CreateLocalGenerator(cmLocalGenerator* parent,
-                                             cmState::Snapshot snapshot)
+cmGlobalNinjaGenerator::CreateLocalGenerator(cmMakefile* mf)
 {
-  return new cmLocalNinjaGenerator(this, parent, snapshot);
+  return new cmLocalNinjaGenerator(this, mf);
 }
 
 void cmGlobalNinjaGenerator
@@ -547,6 +546,18 @@ void cmGlobalNinjaGenerator
 //   Source/cmake.cxx
 void cmGlobalNinjaGenerator::Generate()
 {
+  // Check minimum Ninja version.
+  if (cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+                                    CurrentNinjaVersion().c_str(),
+                                    RequiredNinjaVersion().c_str()))
+    {
+    std::ostringstream msg;
+    msg << "The detected version of Ninja (" << this->CurrentNinjaVersion();
+    msg << ") is less than the version of Ninja required by CMake (";
+    msg << this->RequiredNinjaVersion() << ").";
+    this->GetCMakeInstance()->IssueMessage(cmake::FATAL_ERROR, msg.str());
+    return;
+    }
   this->OpenBuildFileStream();
   this->OpenRulesFileStream();
 
@@ -807,6 +818,17 @@ void cmGlobalNinjaGenerator::CloseRulesFileStream()
    }
 }
 
+std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
+{
+  cmLocalNinjaGenerator *ng =
+    static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]);
+  std::string convPath = ng->Convert(path, cmOutputConverter::HOME_OUTPUT);
+#ifdef _WIN32
+  cmSystemTools::ReplaceString(convPath, "/", "\\");
+#endif
+  return convPath;
+}
+
 void cmGlobalNinjaGenerator::AddCXXCompileCommand(
                                       const std::string &commandLine,
                                       const std::string &sourceFile)
@@ -896,8 +918,6 @@ cmGlobalNinjaGenerator
 {
   std::string configName =
     target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
-  cmLocalNinjaGenerator *ng =
-    static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]);
 
   // for frameworks, we want the real name, not smple name
   // frameworks always appear versioned, and the build.ninja
@@ -910,13 +930,15 @@ cmGlobalNinjaGenerator
   case cmTarget::SHARED_LIBRARY:
   case cmTarget::STATIC_LIBRARY:
   case cmTarget::MODULE_LIBRARY:
-    outputs.push_back(ng->ConvertToNinjaPath(
-      target->GetFullPath(configName, false, realname)));
+    {
+    cmGeneratorTarget *gtgt = this->GetGeneratorTarget(target);
+    outputs.push_back(this->ConvertToNinjaPath(
+      gtgt->GetFullPath(configName, false, realname)));
     break;
-
+    }
   case cmTarget::OBJECT_LIBRARY:
   case cmTarget::UTILITY: {
-    std::string path = ng->ConvertToNinjaPath(
+    std::string path = this->ConvertToNinjaPath(
       target->GetMakefile()->GetCurrentBinaryDirectory());
     if (path.empty() || path == ".")
       outputs.push_back(target->GetName());
@@ -949,8 +971,8 @@ cmGlobalNinjaGenerator
     std::set<std::string> const& utils = target->GetUtilities();
     std::copy(utils.begin(), utils.end(), std::back_inserter(outputs));
   } else {
-    cmTargetDependSet const& targetDeps =
-      this->GetTargetDirectDepends(*target);
+    cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
+    cmTargetDependSet const& targetDeps = this->GetTargetDirectDepends(gt);
     for (cmTargetDependSet::const_iterator i = targetDeps.begin();
          i != targetDeps.end(); ++i)
       {
@@ -958,7 +980,7 @@ cmGlobalNinjaGenerator
         {
         continue;
         }
-      this->AppendTargetOutputs(*i, outputs);
+      this->AppendTargetOutputs((*i)->Target, outputs);
     }
   }
 }
@@ -1028,8 +1050,6 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
 
   //get the list of files that cmake itself has generated as a
   //product of configuration.
-  cmLocalNinjaGenerator *ng =
-    static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]);
 
   for (std::vector<cmLocalGenerator *>::const_iterator i =
        this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i)
@@ -1041,7 +1061,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
     typedef std::vector<std::string>::const_iterator vect_it;
     for(vect_it j = files.begin(); j != files.end(); ++j)
       {
-      knownDependencies.insert( ng->ConvertToNinjaPath( *j ) );
+      knownDependencies.insert( this->ConvertToNinjaPath( *j ) );
       }
     //get list files which are implicit dependencies as well and will be phony
     //for rebuild manifest
@@ -1049,31 +1069,29 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
     typedef std::vector<std::string>::const_iterator vect_it;
     for(vect_it j = lf.begin(); j != lf.end(); ++j)
       {
-      knownDependencies.insert( ng->ConvertToNinjaPath( *j ) );
+      knownDependencies.insert( this->ConvertToNinjaPath( *j ) );
       }
-    }
-  knownDependencies.insert( "CMakeCache.txt" );
-
-  for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
-      li = this->EvaluationFiles.begin();
-      li != this->EvaluationFiles.end();
-      ++li)
-    {
-    //get all the files created by generator expressions and convert them
-    //to ninja paths
-    std::vector<std::string> files = (*li)->GetFiles();
-    typedef std::vector<std::string>::const_iterator vect_it;
-    for(vect_it j = files.begin(); j != files.end(); ++j)
+    std::vector<cmGeneratorExpressionEvaluationFile*> const& ef =
+        (*i)->GetMakefile()->GetEvaluationFiles();
+    for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
+        li = ef.begin(); li != ef.end(); ++li)
       {
-      knownDependencies.insert( ng->ConvertToNinjaPath( *j ) );
+      //get all the files created by generator expressions and convert them
+      //to ninja paths
+      std::vector<std::string> evaluationFiles = (*li)->GetFiles();
+      for(vect_it j = evaluationFiles.begin(); j != evaluationFiles.end(); ++j)
+        {
+        knownDependencies.insert( this->ConvertToNinjaPath( *j ) );
+        }
       }
     }
+  knownDependencies.insert( "CMakeCache.txt" );
 
   for(TargetAliasMap::const_iterator i= this->TargetAliases.begin();
       i != this->TargetAliases.end();
       ++i)
     {
-    knownDependencies.insert( ng->ConvertToNinjaPath(i->first) );
+    knownDependencies.insert( this->ConvertToNinjaPath(i->first) );
     }
 
   //remove all source files we know will exist.
@@ -1082,7 +1100,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
       i != this->AssumedSourceDependencies.end();
       ++i)
     {
-    knownDependencies.insert( ng->ConvertToNinjaPath(i->first) );
+    knownDependencies.insert( this->ConvertToNinjaPath(i->first) );
     }
 
   //now we difference with CombinedCustomCommandExplicitDependencies to find
@@ -1203,8 +1221,6 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
             /*restat=*/ "",
             /*generator=*/ true);
 
-  cmLocalNinjaGenerator *ng = static_cast<cmLocalNinjaGenerator *>(lg);
-
   cmNinjaDeps implicitDeps;
   for(std::vector<cmLocalGenerator*>::const_iterator i =
         this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i)
@@ -1213,7 +1229,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
     for(std::vector<std::string>::const_iterator fi = lf.begin();
         fi != lf.end(); ++fi)
       {
-      implicitDeps.push_back(ng->ConvertToNinjaPath(*fi));
+      implicitDeps.push_back(this->ConvertToNinjaPath(*fi));
       }
     }
   implicitDeps.push_back("CMakeCache.txt");
@@ -1256,7 +1272,7 @@ std::string cmGlobalNinjaGenerator::ninjaCmd() const
   return "ninja";
 }
 
-std::string cmGlobalNinjaGenerator::ninjaVersion() const
+std::string cmGlobalNinjaGenerator::CurrentNinjaVersion() const
 {
   std::string version;
   std::string command = ninjaCmd() + " --version";
@@ -1264,13 +1280,14 @@ std::string cmGlobalNinjaGenerator::ninjaVersion() const
                                   &version, 0, 0, 0,
                                   cmSystemTools::OUTPUT_NONE);
 
-  return version;
+  return cmSystemTools::TrimWhitespace(version);
 }
 
 bool cmGlobalNinjaGenerator::SupportsConsolePool() const
 {
   return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
-                                       ninjaVersion().c_str(), "1.5") == false;
+    CurrentNinjaVersion().c_str(),
+    RequiredNinjaVersionForConsolePool().c_str()) == false;
 }
 
 void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index ffd1cdc..292f7c7 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -13,7 +13,7 @@
 #ifndef cmGlobalNinjaGenerator_h
 #  define cmGlobalNinjaGenerator_h
 
-#  include "cmGlobalGenerator.h"
+#  include "cmGlobalCommonGenerator.h"
 #  include "cmGlobalGeneratorFactory.h"
 #  include "cmNinjaTypes.h"
 
@@ -42,7 +42,7 @@ class cmGeneratorTarget;
  * - We extensively use Ninja variable overloading system to minimize the
  *   number of generated rules.
  */
-class cmGlobalNinjaGenerator : public cmGlobalGenerator
+class cmGlobalNinjaGenerator : public cmGlobalCommonGenerator
 {
 public:
   /// The default name of Ninja's build file. Typically: build.ninja.
@@ -162,33 +162,24 @@ public:
 public:
   cmGlobalNinjaGenerator(cmake* cm);
 
-  /// Convenience method for creating an instance of this class.
   static cmGlobalGeneratorFactory* NewFactory() {
     return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>(); }
 
-  /// Destructor.
   virtual ~cmGlobalNinjaGenerator() { }
 
-  /// Overloaded methods. @see cmGlobalGenerator::CreateLocalGenerator()
-  virtual cmLocalGenerator* CreateLocalGenerator(cmLocalGenerator* parent,
-                                                 cmState::Snapshot snapshot);
+  virtual cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf);
 
-  /// Overloaded methods. @see cmGlobalGenerator::GetName().
   virtual std::string GetName() const {
     return cmGlobalNinjaGenerator::GetActualName(); }
 
-  /// @return the name of this generator.
   static std::string GetActualName() { return "Ninja"; }
 
-  /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
   static void GetDocumentation(cmDocumentationEntry& entry);
 
-  /// Overloaded methods. @see cmGlobalGenerator::EnableLanguage()
   virtual void EnableLanguage(std::vector<std::string>const& languages,
                               cmMakefile* mf,
                               bool optional);
 
-  /// Overloaded methods. @see cmGlobalGenerator::GenerateBuildCommand()
   virtual void GenerateBuildCommand(
     std::vector<std::string>& makeCommand,
     const std::string& makeProgram,
@@ -229,6 +220,19 @@ public:
   cmGeneratedFileStream* GetRulesFileStream() const {
     return this->RulesFileStream; }
 
+  std::string ConvertToNinjaPath(const std::string& path);
+
+  struct MapToNinjaPathImpl {
+    cmGlobalNinjaGenerator* GG;
+    MapToNinjaPathImpl(cmGlobalNinjaGenerator* gg): GG(gg) {}
+    std::string operator()(std::string const& path) {
+      return this->GG->ConvertToNinjaPath(path);
+    }
+  };
+  MapToNinjaPathImpl MapToNinjaPath() {
+    return MapToNinjaPathImpl(this);
+  }
+
   void AddCXXCompileCommand(const std::string &commandLine,
                             const std::string &sourceFile);
 
@@ -289,7 +293,7 @@ public:
   const std::vector<cmLocalGenerator*>& GetLocalGenerators() const {
     return LocalGenerators; }
 
-  bool IsExcluded(cmLocalGenerator* root, cmTarget& target) {
+  bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) {
     return cmGlobalGenerator::IsExcluded(root, target); }
 
   int GetRuleCmdLength(const std::string& name) {
@@ -299,17 +303,16 @@ public:
 
   virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
 
-  std::string ninjaVersion() const;
-
+  std::string CurrentNinjaVersion() const;
+  // Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3
+  static std::string RequiredNinjaVersion() { return "1.3"; }
+  static std::string RequiredNinjaVersionForConsolePool() { return "1.5"; }
   bool SupportsConsolePool() const;
 
 protected:
 
-  /// Overloaded methods. @see cmGlobalGenerator::Generate()
   virtual void Generate();
 
-  /// Overloaded methods.
-  /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
   virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const { return true; }
 
 
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 4fe52dd..0064713 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -21,7 +21,7 @@
 #include "cmAlgorithms.h"
 
 cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
-  : cmGlobalGenerator(cm)
+  : cmGlobalCommonGenerator(cm)
 {
   // This type of makefile always requires unix style paths
   this->ForceUnixPaths = true;
@@ -59,11 +59,10 @@ void cmGlobalUnixMakefileGenerator3
 }
 
 ///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *
-cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(cmLocalGenerator* parent,
-                                                   cmState::Snapshot snapshot)
+cmLocalGenerator* cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(
+    cmMakefile* mf)
 {
-  return new cmLocalUnixMakefileGenerator3(this, parent, snapshot);
+  return new cmLocalUnixMakefileGenerator3(this, mf);
 }
 
 //----------------------------------------------------------------------------
@@ -482,8 +481,8 @@ cmGlobalUnixMakefileGenerator3
       // Add this to the list of depends rules in this directory.
       if((!check_all || !gtarget->GetPropertyAsBool("EXCLUDE_FROM_ALL")) &&
          (!check_relink ||
-          gtarget->Target
-                   ->NeedRelinkBeforeInstall(lg->ConfigurationName)))
+          gtarget
+            ->NeedRelinkBeforeInstall(lg->GetConfigName())))
         {
         std::string tname = lg->GetRelativeTargetDirectory(*gtarget->Target);
         tname += "/";
@@ -495,12 +494,12 @@ cmGlobalUnixMakefileGenerator3
 
   // The directory-level rule should depend on the directory-level
   // rules of the subdirectories.
-  for(std::vector<cmLocalGenerator*>::iterator sdi =
-        lg->GetChildren().begin(); sdi != lg->GetChildren().end(); ++sdi)
+  std::vector<cmState::Snapshot> children
+      = lg->GetMakefile()->GetStateSnapshot().GetChildren();
+  for(std::vector<cmState::Snapshot>::const_iterator
+        ci = children.begin(); ci != children.end(); ++ci)
     {
-    cmLocalUnixMakefileGenerator3* slg =
-      static_cast<cmLocalUnixMakefileGenerator3*>(*sdi);
-    std::string subdir = slg->GetMakefile()->GetCurrentBinaryDirectory();
+    std::string subdir = ci->GetDirectory().GetCurrentBinary();
     subdir += "/";
     subdir += pass;
     depends.push_back(subdir);
@@ -529,7 +528,7 @@ cmGlobalUnixMakefileGenerator3
                        cmLocalUnixMakefileGenerator3* lg)
 {
   // Only subdirectories need these rules.
-  if(lg->IsRootMakefile())
+  if(lg->GetMakefile()->IsRootMakefile())
     {
     return;
     }
@@ -578,20 +577,19 @@ void cmGlobalUnixMakefileGenerator3
                      makeOptions.begin(), makeOptions.end());
   if (!targetName.empty())
     {
-    cmLocalUnixMakefileGenerator3 *lg;
-    if (!this->LocalGenerators.empty())
+    cmMakefile* mf;
+    if (!this->Makefiles.empty())
       {
-      lg = static_cast<cmLocalUnixMakefileGenerator3 *>
-        (this->LocalGenerators[0]);
+      mf = this->Makefiles[0];
       }
     else
       {
-      lg = static_cast<cmLocalUnixMakefileGenerator3 *>
-        (this->MakeLocalGenerator());
+      cmState::Snapshot snapshot = this->CMakeInstance->GetCurrentSnapshot();
+      mf = new cmMakefile(this, snapshot);
       // set the Start directories
-      lg->GetMakefile()->SetCurrentSourceDirectory
+      mf->SetCurrentSourceDirectory
         (this->CMakeInstance->GetHomeDirectory());
-      lg->GetMakefile()->SetCurrentBinaryDirectory
+      mf->SetCurrentBinaryDirectory
         (this->CMakeInstance->GetHomeOutputDirectory());
       }
 
@@ -600,12 +598,13 @@ void cmGlobalUnixMakefileGenerator3
       {
       tname += "/fast";
       }
-    tname = lg->Convert(tname,cmLocalGenerator::HOME_OUTPUT);
+    cmOutputConverter conv(mf->GetStateSnapshot());
+    tname = conv.Convert(tname,cmOutputConverter::HOME_OUTPUT);
     cmSystemTools::ConvertToOutputSlashes(tname);
     makeCommand.push_back(tname);
-    if (this->LocalGenerators.empty())
+    if (this->Makefiles.empty())
       {
-      delete lg;
+      delete mf;
       }
     }
 }
@@ -691,8 +690,8 @@ cmGlobalUnixMakefileGenerator3
 
         // Add a local name for the rule to relink the target before
         // installation.
-        if(gtarget->Target
-                    ->NeedRelinkBeforeInstall(lg->ConfigurationName))
+        if(gtarget
+             ->NeedRelinkBeforeInstall(lg->GetConfigName()))
           {
           makeTargetName = lg->GetRelativeTargetDirectory(*gtarget->Target);
           makeTargetName += "/preinstall";
@@ -801,15 +800,27 @@ cmGlobalUnixMakefileGenerator3
         }
       progress.Arg = progressArg.str();
       }
-      lg->AppendEcho(commands, "Built target " + name,
-        cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
 
-      this->AppendGlobalTargetDepends(depends,*gtarget->Target);
+      bool targetMessages = true;
+      if (const char* tgtMsg = this->GetCMakeInstance()
+                                   ->GetState()
+                                   ->GetGlobalProperty("TARGET_MESSAGES"))
+        {
+        targetMessages = cmSystemTools::IsOn(tgtMsg);
+        }
+
+      if (targetMessages)
+        {
+        lg->AppendEcho(commands, "Built target " + name,
+          cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
+        }
+
+      this->AppendGlobalTargetDepends(depends, gtarget);
       lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
                         localName, depends, commands, true);
 
       // add the all/all dependency
-      if(!this->IsExcluded(this->LocalGenerators[0], *gtarget->Target))
+      if(!this->IsExcluded(this->LocalGenerators[0], gtarget))
         {
         depends.clear();
         depends.push_back(localName);
@@ -830,9 +841,9 @@ cmGlobalUnixMakefileGenerator3
                               cmLocalGenerator::FULL,
                               cmLocalGenerator::SHELL);
       //
-      std::set<cmTarget const*> emitted;
+      std::set<cmGeneratorTarget const*> emitted;
       progCmd << " "
-              << this->CountProgressMarksInTarget(gtarget->Target, emitted);
+              << this->CountProgressMarksInTarget(gtarget, emitted);
       commands.push_back(progCmd.str());
       }
       std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
@@ -864,8 +875,8 @@ cmGlobalUnixMakefileGenerator3
                         name, depends, commands, true);
 
       // Add rules to prepare the target for installation.
-      if(gtarget->Target
-                  ->NeedRelinkBeforeInstall(lg->ConfigurationName))
+      if(gtarget
+           ->NeedRelinkBeforeInstall(lg->GetConfigName()))
         {
         localName = lg->GetRelativeTargetDirectory(*gtarget->Target);
         localName += "/preinstall";
@@ -877,7 +888,7 @@ cmGlobalUnixMakefileGenerator3
                           "Pre-install relink rule for target.",
                           localName, depends, commands, true);
 
-        if(!this->IsExcluded(this->LocalGenerators[0], *gtarget->Target))
+        if(!this->IsExcluded(this->LocalGenerators[0], gtarget))
           {
           depends.clear();
           depends.push_back(localName);
@@ -905,17 +916,71 @@ cmGlobalUnixMakefileGenerator3
     }
 }
 
+// Build a map that contains a the set of targets used by each local
+// generator directory level.
+void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
+{
+  this->DirectoryTargetsMap.clear();
+  // Loop over all targets in all local generators.
+  for(std::vector<cmLocalGenerator*>::const_iterator
+        lgi = this->LocalGenerators.begin();
+      lgi != this->LocalGenerators.end(); ++lgi)
+    {
+    cmLocalGenerator* lg = *lgi;
+    cmMakefile* mf = lg->GetMakefile();
+    cmTargets const& targets = mf->GetTargets();
+    for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
+      {
+      cmTarget const& target = t->second;
+
+      cmGeneratorTarget* gt = this->GetGeneratorTarget(&target);
+
+      cmLocalGenerator* tlg = gt->GetLocalGenerator();
+
+      if(gt->GetType() == cmTarget::INTERFACE_LIBRARY
+          || gt->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+        {
+        continue;
+        }
+
+      cmState::Snapshot csnp = lg->GetStateSnapshot();
+      cmState::Snapshot tsnp = tlg->GetStateSnapshot();
+
+      // Consider the directory containing the target and all its
+      // parents until something excludes the target.
+      for( ; csnp.IsValid() && !this->IsExcluded(csnp, tsnp);
+          csnp = csnp.GetBuildsystemDirectoryParent())
+        {
+        // This local generator includes the target.
+        std::set<cmGeneratorTarget const*>& targetSet =
+          this->DirectoryTargetsMap[csnp];
+        targetSet.insert(gt);
+
+        // Add dependencies of the included target.  An excluded
+        // target may still be included if it is a dependency of a
+        // non-excluded target.
+        TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(gt);
+        for(TargetDependSet::const_iterator ti = tgtdeps.begin();
+            ti != tgtdeps.end(); ++ti)
+          {
+          targetSet.insert(*ti);
+          }
+        }
+      }
+    }
+}
+
 //----------------------------------------------------------------------------
 size_t
 cmGlobalUnixMakefileGenerator3
-::CountProgressMarksInTarget(cmTarget const* target,
-                             std::set<cmTarget const*>& emitted)
+::CountProgressMarksInTarget(cmGeneratorTarget const* target,
+                             std::set<cmGeneratorTarget const*>& emitted)
 {
   size_t count = 0;
   if(emitted.insert(target).second)
     {
-    count = this->ProgressMap[target].Marks.size();
-    TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+    count = this->ProgressMap[target->Target].Marks.size();
+    TargetDependSet const& depends = this->GetTargetDirectDepends(target);
     for(TargetDependSet::const_iterator di = depends.begin();
         di != depends.end(); ++di)
       {
@@ -935,10 +1000,10 @@ cmGlobalUnixMakefileGenerator3
 ::CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg)
 {
   size_t count = 0;
-  std::set<cmTarget const*> emitted;
-  std::set<cmTarget const*> const& targets
-                                        = this->LocalGeneratorToTargetMap[lg];
-  for(std::set<cmTarget const*>::const_iterator t = targets.begin();
+  std::set<cmGeneratorTarget const*> emitted;
+  std::set<cmGeneratorTarget const*> const& targets
+      = this->DirectoryTargetsMap[lg->GetStateSnapshot()];
+  for(std::set<cmGeneratorTarget const*>::const_iterator t = targets.begin();
       t != targets.end(); ++t)
     {
     count += this->CountProgressMarksInTarget(*t, emitted);
@@ -987,22 +1052,21 @@ cmGlobalUnixMakefileGenerator3::TargetProgress
 void
 cmGlobalUnixMakefileGenerator3
 ::AppendGlobalTargetDepends(std::vector<std::string>& depends,
-                            cmTarget& target)
+                            cmGeneratorTarget* target)
 {
   TargetDependSet const& depends_set = this->GetTargetDirectDepends(target);
   for(TargetDependSet::const_iterator i = depends_set.begin();
       i != depends_set.end(); ++i)
     {
     // Create the target-level dependency.
-    cmTarget const* dep = *i;
+    cmGeneratorTarget const* dep = *i;
     if (dep->GetType() == cmTarget::INTERFACE_LIBRARY)
       {
       continue;
       }
     cmLocalUnixMakefileGenerator3* lg3 =
-      static_cast<cmLocalUnixMakefileGenerator3*>
-      (dep->GetMakefile()->GetLocalGenerator());
-    std::string tgtName = lg3->GetRelativeTargetDirectory(*dep);
+      static_cast<cmLocalUnixMakefileGenerator3*>(dep->GetLocalGenerator());
+    std::string tgtName = lg3->GetRelativeTargetDirectory(*(*dep).Target);
     tgtName += "/all";
     depends.push_back(tgtName);
     }
@@ -1034,7 +1098,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule
       static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
     // for the passed in makefile or if this is the top Makefile wripte out
     // the targets
-    if (lg2 == lg || lg->IsRootMakefile())
+    if (lg2 == lg || lg->GetMakefile()->IsRootMakefile())
       {
       // for each target Generate the rule files for each target.
       cmTargets& targets = lg2->GetMakefile()->GetTargets();
@@ -1080,7 +1144,8 @@ bool cmGlobalUnixMakefileGenerator3
 ::NeedRequiresStep(cmTarget const& target)
 {
   std::set<std::string> languages;
-  target.GetLanguages(languages,
+  cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&target);
+  gtgt->GetLanguages(languages,
                 target.GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   for(std::set<std::string>::const_iterator l = languages.begin();
       l != languages.end(); ++l)
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index a639ff0..5f39c79 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -12,7 +12,7 @@
 #ifndef cmGlobalUnixMakefileGenerator3_h
 #define cmGlobalUnixMakefileGenerator3_h
 
-#include "cmGlobalGenerator.h"
+#include "cmGlobalCommonGenerator.h"
 #include "cmGlobalGeneratorFactory.h"
 
 class cmGeneratedFileStream;
@@ -51,7 +51,7 @@ class cmLocalUnixMakefileGenerator3;
 
  */
 
-class cmGlobalUnixMakefileGenerator3 : public cmGlobalGenerator
+class cmGlobalUnixMakefileGenerator3 : public cmGlobalCommonGenerator
 {
 public:
   cmGlobalUnixMakefileGenerator3(cmake* cm);
@@ -67,9 +67,7 @@ public:
   /** Get the documentation entry for this generator.  */
   static void GetDocumentation(cmDocumentationEntry& entry);
 
-  ///! Create a local generator appropriate to this Global Generator3
-  virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
-                                                 cmState::Snapshot snapshot);
+  virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
 
   /**
    * Try to determine system information such as shared library
@@ -153,7 +151,7 @@ protected:
                             cmLocalUnixMakefileGenerator3* lg);
 
   void AppendGlobalTargetDepends(std::vector<std::string>& depends,
-                                 cmTarget& target);
+                                 cmGeneratorTarget* target);
 
   // does this generator need a requires step for any of its targets
   bool NeedRequiresStep(cmTarget const&);
@@ -198,14 +196,19 @@ protected:
                    cmStrictTargetComparison> ProgressMapType;
   ProgressMapType ProgressMap;
 
-  size_t CountProgressMarksInTarget(cmTarget const* target,
-                                    std::set<cmTarget const*>& emitted);
+  size_t CountProgressMarksInTarget(cmGeneratorTarget const* target,
+                                 std::set<cmGeneratorTarget const*>& emitted);
   size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
 
   cmGeneratedFileStream *CommandDatabase;
 private:
   virtual const char* GetBuildIgnoreErrorsFlag() const { return "-i"; }
   virtual std::string GetEditCacheCommand() const;
+
+  std::map<cmState::Snapshot,
+           std::set<cmGeneratorTarget const*>,
+           cmState::Snapshot::StrictWeakOrder> DirectoryTargetsMap;
+  virtual void InitializeProgressMarks();
 };
 
 #endif
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 4e8ada4..59e8f8c 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -176,7 +176,14 @@ cmGlobalVisualStudio10Generator::SetGeneratorToolset(std::string const& ts,
 //----------------------------------------------------------------------------
 bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
 {
-  if (this->SystemName == "WindowsCE")
+  if (this->SystemName == "Windows")
+    {
+    if (!this->InitializeWindows(mf))
+      {
+      return false;
+      }
+    }
+  else if (this->SystemName == "WindowsCE")
     {
     this->SystemIsWindowsCE = true;
     if (!this->InitializeWindowsCE(mf))
@@ -184,7 +191,7 @@ bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
       return false;
       }
     }
-  else if(this->SystemName == "WindowsPhone")
+  else if (this->SystemName == "WindowsPhone")
     {
     this->SystemIsWindowsPhone = true;
     if(!this->InitializeWindowsPhone(mf))
@@ -192,7 +199,7 @@ bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
       return false;
       }
     }
-  else if(this->SystemName == "WindowsStore")
+  else if (this->SystemName == "WindowsStore")
     {
     this->SystemIsWindowsStore = true;
     if(!this->InitializeWindowsStore(mf))
@@ -229,6 +236,12 @@ bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
 }
 
 //----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::InitializeWindows(cmMakefile*)
+{
+  return true;
+}
+
+//----------------------------------------------------------------------------
 bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf)
 {
   if (this->DefaultPlatformName != "Win32")
@@ -306,17 +319,25 @@ void cmGlobalVisualStudio10Generator::WriteSLNHeader(std::ostream& fout)
 }
 
 ///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *
-cmGlobalVisualStudio10Generator::CreateLocalGenerator(cmLocalGenerator* parent,
-                                                    cmState::Snapshot snapshot)
+cmLocalGenerator* cmGlobalVisualStudio10Generator::CreateLocalGenerator(
+    cmMakefile* mf)
 {
-  return new cmLocalVisualStudio10Generator(this, parent, snapshot);
+  return new cmLocalVisualStudio10Generator(this, mf);
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalVisualStudio10Generator::Generate()
+bool cmGlobalVisualStudio10Generator::Compute()
 {
+  if (!cmGlobalVisualStudio8Generator::Compute())
+    {
+    return false;
+    }
   this->LongestSource = LongestSourcePath();
+  return true;
+}
+
+void cmGlobalVisualStudio10Generator::Generate()
+{
   this->cmGlobalVisualStudio8Generator::Generate();
   if(this->LongestSource.Length > 0)
     {
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 74d5022..f4861dc 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -45,9 +45,10 @@ public:
     std::vector<std::string> const& makeOptions = std::vector<std::string>()
     );
 
+  virtual bool Compute();
+
   ///! create the correct local generator
-  virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
-                                                 cmState::Snapshot snapshot);
+  virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
 
   /**
    * Try to determine system information such as shared library
@@ -73,6 +74,10 @@ public:
   /** Return the CMAKE_SYSTEM_VERSION.  */
   std::string const& GetSystemVersion() const { return this->SystemVersion; }
 
+  /** Return the Windows version targeted on VS 2015 and above.  */
+  std::string const& GetWindowsTargetPlatformVersion() const
+    { return this->WindowsTargetPlatformVersion; }
+
   /** Return true if building for WindowsCE */
   bool TargetsWindowsCE() const
     { return this->SystemIsWindowsCE; }
@@ -104,6 +109,7 @@ public:
 protected:
   virtual void Generate();
   virtual bool InitializeSystem(cmMakefile* mf);
+  virtual bool InitializeWindows(cmMakefile* mf);
   virtual bool InitializeWindowsCE(cmMakefile* mf);
   virtual bool InitializeWindowsPhone(cmMakefile* mf);
   virtual bool InitializeWindowsStore(cmMakefile* mf);
@@ -118,6 +124,7 @@ protected:
 
   std::string GeneratorToolset;
   std::string DefaultPlatformToolset;
+  std::string WindowsTargetPlatformVersion;
   std::string SystemName;
   std::string SystemVersion;
   std::string NsightTegraVersion;
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index b50f4c9..9499d80 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -34,9 +34,12 @@ protected:
   virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
   virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
 
+  // Used to verify that the Desktop toolset for the current generator is
+  // installed on the machine.
+  virtual bool IsWindowsDesktopToolsetInstalled() const;
+
   // These aren't virtual because we need to check if the selected version
   // of the toolset is installed
-  bool IsWindowsDesktopToolsetInstalled() const;
   bool IsWindowsPhoneToolsetInstalled() const;
   bool IsWindowsStoreToolsetInstalled() const;
 
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
index bce9e0c..a7939aa 100644
--- a/Source/cmGlobalVisualStudio12Generator.h
+++ b/Source/cmGlobalVisualStudio12Generator.h
@@ -38,9 +38,12 @@ protected:
   virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
   virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
 
+  // Used to verify that the Desktop toolset for the current generator is
+  // installed on the machine.
+  virtual bool IsWindowsDesktopToolsetInstalled() const;
+
   // These aren't virtual because we need to check if the selected version
   // of the toolset is installed
-  bool IsWindowsDesktopToolsetInstalled() const;
   bool IsWindowsPhoneToolsetInstalled() const;
   bool IsWindowsStoreToolsetInstalled() const;
   virtual const char* GetIDEVersion() { return "12.0"; }
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 2cf55d4..41825fb 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -111,6 +111,84 @@ cmGlobalVisualStudio14Generator::MatchesGeneratorName(
 }
 
 //----------------------------------------------------------------------------
+bool cmGlobalVisualStudio14Generator::InitializeWindows(cmMakefile* mf)
+{
+  if (cmHasLiteralPrefix(this->SystemVersion, "10.0"))
+    {
+    return this->SelectWindows10SDK(mf);
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio14Generator::InitializeWindowsStore(cmMakefile* mf)
+{
+  std::ostringstream  e;
+  if(!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset))
+    {
+    if(this->DefaultPlatformToolset.empty())
+      {
+      e << this->GetName() << " supports Windows Store '8.0', '8.1' and "
+        "'10.0', but not '" << this->SystemVersion <<
+        "'.  Check CMAKE_SYSTEM_VERSION.";
+      }
+    else
+      {
+      e << "A Windows Store component with CMake requires both the Windows "
+        << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
+        << "' SDK. Please make sure that you have both installed";
+      }
+    mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+    return false;
+    }
+  if (cmHasLiteralPrefix(this->SystemVersion, "10.0"))
+    {
+    return this->SelectWindows10SDK(mf);
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf)
+{
+  // Find the default version of the Windows 10 SDK.
+  this->WindowsTargetPlatformVersion = this->GetWindows10SDKVersion();
+  if (this->WindowsTargetPlatformVersion.empty())
+    {
+    std::ostringstream  e;
+    e << "Could not find an appropriate version of the Windows 10 SDK"
+      << " installed on this machine";
+    mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+    return false;
+    }
+  mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION",
+                    this->WindowsTargetPlatformVersion.c_str());
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
+  std::string& toolset) const
+{
+  if (cmHasLiteralPrefix(this->SystemVersion, "10.0"))
+    {
+    if (this->IsWindowsStoreToolsetInstalled() &&
+        this->IsWindowsDesktopToolsetInstalled())
+      {
+      toolset = "v140";
+      return true;
+      }
+    else
+      {
+      return false;
+      }
+    }
+  return
+    this->cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset(toolset);
+}
+
+//----------------------------------------------------------------------------
 void cmGlobalVisualStudio14Generator::WriteSLNHeader(std::ostream& fout)
 {
   // Visual Studio 14 writes .sln format 12.00
@@ -124,3 +202,90 @@ void cmGlobalVisualStudio14Generator::WriteSLNHeader(std::ostream& fout)
     fout << "# Visual Studio 14\n";
     }
 }
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio14Generator::IsWindowsDesktopToolsetInstalled() const
+{
+  const char desktop10Key[] =
+    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+    "VisualStudio\\14.0\\VC\\Runtimes";
+
+  std::vector<std::string> vc14;
+  return cmSystemTools::GetRegistrySubKeys(desktop10Key,
+    vc14, cmSystemTools::KeyWOW64_32);
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio14Generator::IsWindowsStoreToolsetInstalled() const
+{
+  const char universal10Key[] =
+    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+    "VisualStudio\\14.0\\Setup\\Build Tools for Windows 10;SrcPath";
+
+  std::string win10SDK;
+  return cmSystemTools::ReadRegistryValue(universal10Key,
+    win10SDK, cmSystemTools::KeyWOW64_32);
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  // This logic is taken from the vcvarsqueryregistry.bat file from VS2015
+  // Try HKLM and then HKCU.
+  std::string win10Root;
+  if (!cmSystemTools::ReadRegistryValue(
+        "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+        "Windows Kits\\Installed Roots;KitsRoot10", win10Root,
+        cmSystemTools::KeyWOW64_32) &&
+      !cmSystemTools::ReadRegistryValue(
+        "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\"
+        "Windows Kits\\Installed Roots;KitsRoot10", win10Root,
+        cmSystemTools::KeyWOW64_32))
+    {
+    return std::string();
+    }
+
+  std::vector<std::string> sdks;
+  std::string path = win10Root + "Include/*";
+  // Grab the paths of the different SDKs that are installed
+  cmSystemTools::GlobDirs(path, sdks);
+  if (!sdks.empty())
+    {
+    // Only use the filename, which will be the SDK version.
+    for (std::vector<std::string>::iterator i = sdks.begin();
+         i != sdks.end(); ++i)
+      {
+      *i = cmSystemTools::GetFilenameName(*i);
+      }
+
+    // Sort the results to make sure we select the most recent one that
+    // has a version less or equal to our version of the operating system
+    std::sort(sdks.begin(), sdks.end(), cmSystemTools::VersionCompareGreater);
+
+    // Select a suitable SDK version.
+    if (this->SystemVersion == "10.0")
+      {
+      // Use the latest Windows 10 SDK since no build version was given.
+      return sdks.at(0);
+      }
+    else
+      {
+      // Find the SDK less or equal to our specified version
+      for (std::vector<std::string>::iterator i = sdks.begin();
+           i != sdks.end(); ++i)
+        {
+        if (!cmSystemTools::VersionCompareGreater(*i, this->SystemVersion))
+          {
+          // This is the most recent SDK that we can run safely
+          return *i;
+          }
+        }
+      }
+    }
+#endif
+  // Return an empty string
+  return std::string();
+}
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index aa817be..76c15d9 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -30,7 +30,23 @@ public:
 
   virtual const char* GetToolsVersion() { return "14.0"; }
 protected:
+  virtual bool InitializeWindows(cmMakefile* mf);
+  virtual bool InitializeWindowsStore(cmMakefile* mf);
+  virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
+
+  // These aren't virtual because we need to check if the selected version
+  // of the toolset is installed
+  bool IsWindowsStoreToolsetInstalled() const;
+
   virtual const char* GetIDEVersion() { return "14.0"; }
+  virtual bool SelectWindows10SDK(cmMakefile* mf);
+
+  // Used to verify that the Desktop toolset for the current generator is
+  // installed on the machine.
+  virtual bool IsWindowsDesktopToolsetInstalled() const;
+
+  std::string GetWindows10SDKVersion();
+
 private:
   class Factory;
 };
diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx
index 632141a..14de698 100644
--- a/Source/cmGlobalVisualStudio6Generator.cxx
+++ b/Source/cmGlobalVisualStudio6Generator.cxx
@@ -173,10 +173,9 @@ cmGlobalVisualStudio6Generator::GenerateBuildCommand(
 
 ///! Create a local generator appropriate to this Global Generator
 cmLocalGenerator *
-cmGlobalVisualStudio6Generator::CreateLocalGenerator(cmLocalGenerator* parent,
-                                                   cmState::Snapshot snapshot)
+cmGlobalVisualStudio6Generator::CreateLocalGenerator(cmMakefile* mf)
 {
-  return new cmLocalVisualStudio6Generator(this, parent, snapshot);
+  return new cmLocalVisualStudio6Generator(this, mf);
 }
 
 
@@ -218,13 +217,13 @@ void cmGlobalVisualStudio6Generator
   TargetDependSet projectTargets;
   TargetDependSet originalTargets;
   this->GetTargetSets(projectTargets, originalTargets, root, generators);
-  OrderedTargetDependSet orderedProjectTargets(projectTargets);
+  OrderedTargetDependSet orderedProjectTargets(projectTargets, "ALL_BUILD");
 
   for(OrderedTargetDependSet::const_iterator
         tt = orderedProjectTargets.begin();
       tt != orderedProjectTargets.end(); ++tt)
     {
-    cmTarget const* target = *tt;
+    cmTarget const* target = (*tt)->Target;
     if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
       {
       continue;
@@ -255,7 +254,7 @@ void cmGlobalVisualStudio6Generator
 ::OutputDSWFile(cmLocalGenerator* root,
                 std::vector<cmLocalGenerator*>& generators)
 {
-  if(generators.size() == 0)
+  if(generators.empty())
     {
     return;
     }
diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h
index 2460158..e9b24ea 100644
--- a/Source/cmGlobalVisualStudio6Generator.h
+++ b/Source/cmGlobalVisualStudio6Generator.h
@@ -39,8 +39,7 @@ public:
   static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
-  virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
-                                                 cmState::Snapshot snapshot);
+  virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
 
   /**
    * Try to determine system information such as shared library
@@ -85,8 +84,6 @@ public:
 
   virtual void FindMakeProgram(cmMakefile*);
 
-  virtual bool IsForVS6() const { return true; }
-
 protected:
   virtual void Generate();
   virtual const char* GetIDEVersion() { return "6.0"; }
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 1ab4c9c..b913afc 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -94,7 +94,7 @@ void cmGlobalVisualStudio71Generator
   TargetDependSet projectTargets;
   TargetDependSet originalTargets;
   this->GetTargetSets(projectTargets, originalTargets, root, generators);
-  OrderedTargetDependSet orderedProjectTargets(projectTargets);
+  OrderedTargetDependSet orderedProjectTargets(projectTargets, "ALL_BUILD");
 
   this->WriteTargetsToSolution(fout, root, orderedProjectTargets);
 
@@ -212,7 +212,7 @@ cmGlobalVisualStudio71Generator
     {
     const char* name = di->c_str();
     std::string guid = this->GetGUID(name);
-    if(guid.size() == 0)
+    if(guid.empty())
       {
       std::string m = "Target: ";
       m += target.GetName();
@@ -250,7 +250,7 @@ void cmGlobalVisualStudio71Generator
     std::set<std::string>::const_iterator it;
     for(it = depends.begin(); it != depends.end(); ++it)
       {
-      if(it->size() > 0)
+      if(!it->empty())
         {
         fout << "\t\t{"
              << this->GetGUID(it->c_str())
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 4dd54d0..05da022 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -15,6 +15,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmLocalVisualStudio7Generator.h"
 #include "cmMakefile.h"
+#include "cmUuid.h"
 #include "cmake.h"
 #include <cmsys/Encoding.hxx>
 
@@ -278,12 +279,11 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
 }
 
 ///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *
-cmGlobalVisualStudio7Generator::CreateLocalGenerator(cmLocalGenerator* parent,
-                                                   cmState::Snapshot snapshot)
+cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator(
+    cmMakefile* mf)
 {
   cmLocalVisualStudio7Generator *lg =
-    new cmLocalVisualStudio7Generator(this, parent, snapshot);
+    new cmLocalVisualStudio7Generator(this, mf);
   return lg;
 }
 
@@ -358,7 +358,7 @@ void cmGlobalVisualStudio7Generator
 ::OutputSLNFile(cmLocalGenerator* root,
                 std::vector<cmLocalGenerator*>& generators)
 {
-  if(generators.size() == 0)
+  if(generators.empty())
     {
     return;
     }
@@ -401,7 +401,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
   for(OrderedTargetDependSet::const_iterator tt =
         projectTargets.begin(); tt != projectTargets.end(); ++tt)
     {
-    cmTarget const* target = *tt;
+    cmTarget const* target = (*tt)->Target;
     if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
       {
       continue;
@@ -441,7 +441,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
   for(OrderedTargetDependSet::const_iterator tt =
         projectTargets.begin(); tt != projectTargets.end(); ++tt)
     {
-    cmTarget const* target = *tt;
+    cmTarget const* target = (*tt)->Target;
     if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
       {
       continue;
@@ -513,8 +513,6 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
 
             cumulativePath = cumulativePath + "/" + *iter;
             }
-
-          this->CreateGUID(cumulativePath.c_str());
           }
 
         if (!cumulativePath.empty())
@@ -535,7 +533,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends(
   for(OrderedTargetDependSet::const_iterator tt =
         projectTargets.begin(); tt != projectTargets.end(); ++tt)
     {
-    cmTarget const* target = *tt;
+    cmTarget const* target = (*tt)->Target;
     if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
       {
       continue;
@@ -570,7 +568,7 @@ void cmGlobalVisualStudio7Generator
   TargetDependSet projectTargets;
   TargetDependSet originalTargets;
   this->GetTargetSets(projectTargets, originalTargets, root, generators);
-  OrderedTargetDependSet orderedProjectTargets(projectTargets);
+  OrderedTargetDependSet orderedProjectTargets(projectTargets, "ALL_BUILD");
 
   this->WriteTargetsToSolution(fout, root, orderedProjectTargets);
 
@@ -737,7 +735,7 @@ cmGlobalVisualStudio7Generator
     {
     const char* name = di->c_str();
     std::string guid = this->GetGUID(name);
-    if(guid.size() == 0)
+    if(guid.empty())
       {
       std::string m = "Target: ";
       m += target.GetName();
@@ -815,14 +813,15 @@ void cmGlobalVisualStudio7Generator
 {
   bool extensibilityGlobalsOverridden = false;
   bool extensibilityAddInsOverridden = false;
-  const cmPropertyMap& props = root->GetMakefile()->GetProperties();
-  for(cmPropertyMap::const_iterator itProp = props.begin();
-      itProp != props.end(); ++itProp)
+  const std::vector<std::string> propKeys =
+      root->GetMakefile()->GetPropertyKeys();
+  for(std::vector<std::string>::const_iterator it = propKeys.begin();
+      it != propKeys.end(); ++it)
     {
-    if(itProp->first.find("VS_GLOBAL_SECTION_") == 0)
+    if(it->find("VS_GLOBAL_SECTION_") == 0)
       {
       std::string sectionType;
-      std::string name = itProp->first.substr(18);
+      std::string name = it->substr(18);
       if(name.find("PRE_") == 0)
         {
         name = name.substr(4);
@@ -843,8 +842,9 @@ void cmGlobalVisualStudio7Generator
           extensibilityAddInsOverridden = true;
         fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
         std::vector<std::string> keyValuePairs;
-        cmSystemTools::ExpandListArgument(itProp->second.GetValue(),
-                                          keyValuePairs);
+        cmSystemTools::ExpandListArgument(
+              root->GetMakefile()->GetProperty(it->c_str()),
+              keyValuePairs);
         for(std::vector<std::string>::const_iterator itPair =
             keyValuePairs.begin(); itPair != keyValuePairs.end(); ++itPair)
           {
@@ -899,7 +899,6 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target)
   fname += ".vcproj";
   cmGeneratedFileStream fout(fname.c_str());
   fout.SetCopyIfDifferent(true);
-  this->CreateGUID(pname.c_str());
   std::string guid = this->GetGUID(pname.c_str());
 
   fout <<
@@ -943,41 +942,29 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target)
   return pname;
 }
 
-std::string cmGlobalVisualStudio7Generator::GetGUID(const std::string& name)
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name)
 {
-  std::string guidStoreName = name;
-  guidStoreName += "_GUID_CMAKE";
-  const char* storedGUID =
-    this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str());
-  if(storedGUID)
+  std::string const& guidStoreName = name + "_GUID_CMAKE";
+  if (const char* storedGUID =
+      this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()))
     {
     return std::string(storedGUID);
     }
-  cmSystemTools::Error("Unknown Target referenced : ",
-                       name.c_str());
-  return "";
-}
+  // Compute a GUID that is deterministic but unique to the build tree.
+  std::string input = this->CMakeInstance->GetState()->GetBinaryDirectory();
+  input += "|";
+  input += name;
 
+  cmUuid uuidGenerator;
 
-void cmGlobalVisualStudio7Generator::CreateGUID(const std::string& name)
-{
-  std::string guidStoreName = name;
-  guidStoreName += "_GUID_CMAKE";
-  if(this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()))
-    {
-    return;
-    }
-  std::string ret;
-  UUID uid;
-  unsigned short *uidstr;
-  UuidCreate(&uid);
-  UuidToStringW(&uid,&uidstr);
-  ret = cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(uidstr));
-  RpcStringFreeW(&uidstr);
-  ret = cmSystemTools::UpperCase(ret);
-  this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(),
-                                     ret.c_str(), "Stored GUID",
-                                     cmState::INTERNAL);
+  std::vector<unsigned char> uuidNamespace;
+  uuidGenerator.StringToBinary(
+    "ee30c4be-5192-4fb0-b335-722a2dffe760", uuidNamespace);
+
+  std::string guid = uuidGenerator.FromMd5(uuidNamespace, input);
+
+  return cmSystemTools::UpperCase(guid);
 }
 
 //----------------------------------------------------------------------------
@@ -1039,12 +1026,13 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
     {
     return activeConfigs;
     }
+  cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
   // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
   for(std::vector<std::string>::const_iterator i = configs.begin();
       i != configs.end(); ++i)
     {
     const char* propertyValue =
-      target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str());
+      gt->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str());
     if(cmSystemTools::IsOff(propertyValue))
       {
       activeConfigs.insert(*i);
@@ -1058,12 +1046,12 @@ cmGlobalVisualStudio7Generator
 ::IsDependedOn(OrderedTargetDependSet const& projectTargets,
                cmTarget const* targetIn)
 {
+  cmGeneratorTarget* gtIn = this->GetGeneratorTarget(targetIn);
   for (OrderedTargetDependSet::const_iterator l = projectTargets.begin();
        l != projectTargets.end(); ++l)
     {
-    cmTarget const& target = **l;
-    TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
-    if(tgtdeps.count(targetIn))
+    TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(*l);
+    if(tgtdeps.count(gtIn))
       {
       return true;
       }
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index c98d269..35575d1 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -43,8 +43,7 @@ public:
   std::string const& GetPlatformName() const;
 
   ///! Create a local generator appropriate to this Global Generator
-  virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
-                                                 cmState::Snapshot snapshot);
+  virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
 
   virtual bool SetSystemName(std::string const& s, cmMakefile* mf);
 
@@ -80,9 +79,8 @@ public:
    */
   virtual void OutputSLNFile();
 
-  ///! Create a GUID or get an existing one.
-  void CreateGUID(const std::string& name);
-  std::string GetGUID(const std::string& name);
+  ///! Lookup a stored GUID or compute one deterministically.
+  std::string GetGUID(std::string const& name);
 
   /** Append the subdirectory for the given configuration.  */
   virtual void AppendDirectoryForConfig(const std::string& prefix,
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index a3ebc61..70c00e9 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -185,7 +185,6 @@ void cmGlobalVisualStudio8Generator
 void cmGlobalVisualStudio8Generator::Configure()
 {
   this->cmGlobalVisualStudio7Generator::Configure();
-  this->CreateGUID(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
 }
 
 //----------------------------------------------------------------------------
@@ -256,6 +255,9 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
                           no_working_directory, no_depends,
                           noCommandLines);
 
+  cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg);
+  mf->AddGeneratorTarget(tgt, gt);
+
   // Organize in the "predefined targets" folder:
   //
   if (this->UseFolderProperty())
@@ -310,14 +312,10 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
   cmCustomCommandLine commandLine;
   commandLine.push_back(cmSystemTools::GetCMakeCommand());
   std::string argH = "-H";
-  argH += lg->Convert(mf->GetHomeDirectory(),
-                      cmLocalGenerator::START_OUTPUT,
-                      cmLocalGenerator::UNCHANGED, true);
+  argH += mf->GetHomeDirectory();
   commandLine.push_back(argH);
   std::string argB = "-B";
-  argB += lg->Convert(mf->GetHomeOutputDirectory(),
-                      cmLocalGenerator::START_OUTPUT,
-                      cmLocalGenerator::UNCHANGED, true);
+  argB += mf->GetHomeOutputDirectory();
   commandLine.push_back(argB);
   commandLine.push_back("--check-stamp-list");
   commandLine.push_back(stampList.c_str());
@@ -350,8 +348,13 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalVisualStudio8Generator::Generate()
+bool cmGlobalVisualStudio8Generator::Compute()
 {
+  if (!cmGlobalVisualStudio7Generator::Compute())
+    {
+    return false;
+    }
+
   if(this->AddCheckTarget())
     {
     // All targets depend on the build-system check target.
@@ -365,9 +368,7 @@ void cmGlobalVisualStudio8Generator::Generate()
         }
       }
     }
-
-  // Now perform the main generation.
-  this->cmGlobalVisualStudio7Generator::Generate();
+  return true;
 }
 
 //----------------------------------------------------------------------------
@@ -446,8 +447,9 @@ bool cmGlobalVisualStudio8Generator::ComputeTargetDepends()
 void cmGlobalVisualStudio8Generator::WriteProjectDepends(
   std::ostream& fout, const std::string&, const char*, cmTarget const& t)
 {
-  TargetDependSet const& unordered = this->GetTargetDirectDepends(t);
-  OrderedTargetDependSet depends(unordered);
+  cmGeneratorTarget* gt = this->GetGeneratorTarget(&t);
+  TargetDependSet const& unordered = this->GetTargetDirectDepends(gt);
+  OrderedTargetDependSet depends(unordered, std::string());
   for(OrderedTargetDependSet::const_iterator i = depends.begin();
       i != depends.end(); ++i)
     {
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index cc02b78..1c61103 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -67,7 +67,7 @@ public:
     return !this->WindowsCEVersion.empty(); }
 
 protected:
-  virtual void Generate();
+  virtual bool Compute();
   virtual const char* GetIDEVersion() { return "8.0"; }
 
   virtual std::string FindDevEnvCommand();
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 585d19a..7552d67 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -13,12 +13,14 @@
 #include "cmGlobalVisualStudioGenerator.h"
 
 #include "cmCallVisualStudioMacro.h"
+#include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmLocalVisualStudioGenerator.h"
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
 #include "cmTarget.h"
 #include <cmsys/Encoding.hxx>
+#include "cmAlgorithms.h"
 
 //----------------------------------------------------------------------------
 cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator(cmake* cm)
@@ -62,8 +64,13 @@ std::string cmGlobalVisualStudioGenerator::GetRegistryBase(
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalVisualStudioGenerator::Generate()
+bool cmGlobalVisualStudioGenerator::Compute()
 {
+  if (!cmGlobalGenerator::Compute())
+    {
+    return false;
+    }
+
   // Add a special target that depends on ALL projects for easy build
   // of one configuration only.
   const char* no_working_dir = 0;
@@ -74,7 +81,7 @@ void cmGlobalVisualStudioGenerator::Generate()
     {
     std::vector<cmLocalGenerator*>& gen = it->second;
     // add the ALL_BUILD to the first local generator of each project
-    if(gen.size())
+    if(!gen.empty())
       {
       // Use no actual command lines so that the target itself is not
       // considered always out of date.
@@ -84,6 +91,9 @@ void cmGlobalVisualStudioGenerator::Generate()
                           no_depends, no_commands, false,
                           "Build all projects");
 
+      cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]);
+      allBuild->GetMakefile()->AddGeneratorTarget(allBuild, gt);
+
 #if 0
       // Can't activate this code because we want ALL_BUILD
       // selected as the default "startup project" when first
@@ -102,13 +112,19 @@ void cmGlobalVisualStudioGenerator::Generate()
       for(std::vector<cmLocalGenerator*>::iterator i = gen.begin();
           i != gen.end(); ++i)
         {
-        cmTargets& targets = (*i)->GetMakefile()->GetTargets();
-        for(cmTargets::iterator t = targets.begin();
+        cmGeneratorTargetsType targets =
+            (*i)->GetMakefile()->GetGeneratorTargets();
+        for(cmGeneratorTargetsType::iterator t = targets.begin();
             t != targets.end(); ++t)
           {
+          if (t->second->GetType() == cmTarget::GLOBAL_TARGET
+              || t->first->IsImported())
+            {
+            continue;
+            }
           if(!this->IsExcluded(gen[0], t->second))
             {
-            allBuild->AddUtility(t->second.GetName());
+            allBuild->AddUtility(t->second->GetName());
             }
           }
         }
@@ -128,9 +144,7 @@ void cmGlobalVisualStudioGenerator::Generate()
       static_cast<cmLocalVisualStudioGenerator*>(*lgi);
     lg->AddCMakeListsRules();
     }
-
-  // Run all the local generators.
-  this->cmGlobalGenerator::Generate();
+  return true;
 }
 
 //----------------------------------------------------------------------------
@@ -178,7 +192,7 @@ void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros()
   cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
   std::string dir = this->GetUserMacrosDirectory();
 
-  if (mf != 0 && dir != "")
+  if (dir != "")
     {
     std::string src = mf->GetRequiredDefinition("CMAKE_ROOT");
     src += "/Templates/" CMAKE_VSMACROS_FILENAME;
@@ -219,13 +233,12 @@ cmGlobalVisualStudioGenerator
   std::string dir = this->GetUserMacrosDirectory();
 
   // Only really try to call the macro if:
-  //  - mf is non-NULL
   //  - there is a UserMacrosDirectory
   //  - the CMake vsmacros file exists
   //  - the CMake vsmacros file is registered
   //  - there were .sln/.vcproj files changed during generation
   //
-  if (mf != 0 && dir != "")
+  if (dir != "")
     {
     std::string macrosFile = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
     std::string nextSubkeyName;
@@ -251,7 +264,7 @@ cmGlobalVisualStudioGenerator
         {
         std::vector<std::string> filenames;
         this->GetFilesReplacedDuringGenerate(filenames);
-        if (filenames.size() > 0)
+        if (!filenames.empty())
           {
           // Convert vector to semi-colon delimited string of filenames:
           std::string projects;
@@ -299,13 +312,14 @@ void cmGlobalVisualStudioGenerator::FillLinkClosure(cmTarget const* target,
 {
   if(linked.insert(target).second)
     {
-    TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+    cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
+    TargetDependSet const& depends = this->GetTargetDirectDepends(gt);
     for(TargetDependSet::const_iterator di = depends.begin();
         di != depends.end(); ++di)
       {
       if(di->IsLink())
         {
-        this->FillLinkClosure(*di, linked);
+        this->FillLinkClosure((*di)->Target, linked);
         }
       }
     }
@@ -338,13 +352,14 @@ void cmGlobalVisualStudioGenerator::FollowLinkDepends(
     {
     // Static library targets do not list their link dependencies so
     // we must follow them transitively now.
-    TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+    cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
+    TargetDependSet const& depends = this->GetTargetDirectDepends(gt);
     for(TargetDependSet::const_iterator di = depends.begin();
         di != depends.end(); ++di)
       {
       if(di->IsLink())
         {
-        this->FollowLinkDepends(*di, linked);
+        this->FollowLinkDepends((*di)->Target, linked);
         }
       }
     }
@@ -413,7 +428,8 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
                         target.GetType() != cmTarget::MODULE_LIBRARY &&
                         target.GetType() != cmTarget::EXECUTABLE);
 
-  TargetDependSet const& depends = this->GetTargetDirectDepends(target);
+  cmGeneratorTarget* gt = this->GetGeneratorTarget(&target);
+  TargetDependSet const& depends = this->GetTargetDirectDepends(gt);
 
   // Collect implicit link dependencies (target_link_libraries).
   // Static libraries cannot depend on their link implementation
@@ -427,7 +443,7 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
       cmTargetDepend dep = *di;
       if(dep.IsLink())
         {
-        this->FollowLinkDepends(dep, linkDepends);
+        this->FollowLinkDepends(dep->Target, linkDepends);
         }
       }
     }
@@ -440,7 +456,7 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
     cmTargetDepend dep = *di;
     if(dep.IsUtil())
       {
-      this->FollowLinkDepends(dep, utilDepends);
+      this->FollowLinkDepends(dep->Target, utilDepends);
       }
     }
 
@@ -819,17 +835,19 @@ void RegisterVisualStudioMacros(const std::string& macrosFile,
 bool
 cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget const& target)
 {
+  cmGeneratorTarget* gt = this->GetGeneratorTarget(&target);
+
   // check to see if this is a fortran build
   std::set<std::string> languages;
   {
   // Issue diagnostic if the source files depend on the config.
   std::vector<cmSourceFile*> sources;
-  if (!target.GetConfigCommonSourceFiles(sources))
+  if (!gt->GetConfigCommonSourceFiles(sources))
     {
     return false;
     }
   }
-  target.GetLanguages(languages, "");
+  gt->GetLanguages(languages, "");
   if(languages.size() == 1)
     {
     if(*languages.begin() == "Fortran")
@@ -843,32 +861,44 @@ cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget const& target)
 //----------------------------------------------------------------------------
 bool
 cmGlobalVisualStudioGenerator::TargetCompare
-::operator()(cmTarget const* l, cmTarget const* r) const
+::operator()(cmGeneratorTarget const* l, cmGeneratorTarget const* r) const
 {
-  // Make sure ALL_BUILD is first so it is the default active project.
-  if(r->GetName() == "ALL_BUILD")
+  // Make sure a given named target is ordered first,
+  // e.g. to set ALL_BUILD as the default active project.
+  // When the empty string is named this is a no-op.
+  if (r->GetName() == this->First)
     {
     return false;
     }
-  if(l->GetName() == "ALL_BUILD")
+  if (l->GetName() == this->First)
     {
     return true;
     }
-  return strcmp(l->GetName().c_str(), r->GetName().c_str()) < 0;
+  return l->GetName() < r->GetName();
 }
 
 //----------------------------------------------------------------------------
 cmGlobalVisualStudioGenerator::OrderedTargetDependSet
-::OrderedTargetDependSet(TargetDependSet const& targets)
+::OrderedTargetDependSet(TargetDependSet const& targets,
+                         std::string const& first):
+  derived(TargetCompare(first))
 {
   this->insert(targets.begin(), targets.end());
 }
 
 //----------------------------------------------------------------------------
 cmGlobalVisualStudioGenerator::OrderedTargetDependSet
-::OrderedTargetDependSet(TargetSet const& targets)
+::OrderedTargetDependSet(TargetSet const& targets,
+                         std::string const& first):
+  derived(TargetCompare(first))
 {
-  this->insert(targets.begin(), targets.end());
+  for (TargetSet::const_iterator it = targets.begin();
+       it != targets.end(); ++it)
+    {
+    cmGeneratorTarget* gt =
+        (*it)->GetMakefile()->GetGlobalGenerator()->GetGeneratorTarget(*it);
+    this->insert(gt);
+    }
 }
 
 std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir(
@@ -887,3 +917,71 @@ std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir(
     }
   return tmp;
 }
+
+void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
+  cmGeneratorTarget* gt, std::vector<cmCustomCommand>& commands,
+  std::string const& configName)
+{
+  std::vector<std::string> outputs;
+  std::string deffile = gt->ObjectDirectory;
+  deffile += "/exportall.def";
+  outputs.push_back(deffile);
+  std::vector<std::string> empty;
+  std::vector<cmSourceFile const*> objectSources;
+  gt->GetObjectSources(objectSources, configName);
+  std::map<cmSourceFile const*, std::string> mapping;
+  for(std::vector<cmSourceFile const*>::const_iterator it
+        = objectSources.begin(); it != objectSources.end(); ++it)
+    {
+    mapping[*it];
+    }
+  gt->LocalGenerator->
+    ComputeObjectFilenames(mapping, gt);
+  std::string obj_dir = gt->ObjectDirectory;
+  std::string cmakeCommand = cmSystemTools::GetCMakeCommand();
+  cmSystemTools::ConvertToWindowsExtendedPath(cmakeCommand);
+  cmCustomCommandLine cmdl;
+  cmdl.push_back(cmakeCommand);
+  cmdl.push_back("-E");
+  cmdl.push_back("__create_def");
+  cmdl.push_back(deffile);
+  std::string obj_dir_expanded = obj_dir;
+  cmSystemTools::ReplaceString(obj_dir_expanded,
+                               this->GetCMakeCFGIntDir(),
+                               configName.c_str());
+  std::string objs_file = obj_dir_expanded;
+  cmSystemTools::MakeDirectory(objs_file.c_str());
+  objs_file += "/objects.txt";
+  cmdl.push_back(objs_file);
+  cmGeneratedFileStream fout(objs_file.c_str());
+  if(!fout)
+    {
+    cmSystemTools::Error("could not open ", objs_file.c_str());
+    return;
+    }
+  for(std::vector<cmSourceFile const*>::const_iterator it
+        = objectSources.begin(); it != objectSources.end(); ++it)
+    {
+    // Find the object file name corresponding to this source file.
+    std::map<cmSourceFile const*, std::string>::const_iterator
+      map_it = mapping.find(*it);
+    // It must exist because we populated the mapping just above.
+    assert(!map_it->second.empty());
+    std::string objFile = obj_dir + map_it->second;
+    // replace $(ConfigurationName) in the object names
+    cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(),
+                                 configName.c_str());
+    if(cmHasLiteralSuffix(objFile, ".obj"))
+      {
+      fout << objFile << "\n";
+      }
+    }
+  cmCustomCommandLines commandLines;
+  commandLines.push_back(cmdl);
+  cmCustomCommand command(gt->Target->GetMakefile(),
+                          outputs, empty, empty,
+                          commandLines,
+                          "Auto build dll exports",
+                          ".");
+  commands.push_back(command);
+}
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 69b4564..c940eb3 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -89,9 +89,13 @@ public:
   virtual bool TargetsWindowsCE() const { return false; }
 
   class TargetSet: public std::set<cmTarget const*> {};
-  struct TargetCompare
+  class TargetCompare
   {
-    bool operator()(cmTarget const* l, cmTarget const* r) const;
+    std::string First;
+  public:
+    TargetCompare(std::string const& first): First(first) {}
+    bool operator()(cmGeneratorTarget const* l,
+                    cmGeneratorTarget const* r) const;
   };
   class OrderedTargetDependSet;
 
@@ -102,8 +106,12 @@ public:
                                       const std::string& config) const;
 
   void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+
+  void AddSymbolExportCommand(
+    cmGeneratorTarget*, std::vector<cmCustomCommand>& commands,
+    std::string const& configName);
 protected:
-  virtual void Generate();
+  virtual bool Compute();
 
   // Does this VS version link targets to each other if there are
   // dependencies in the SLN file?  This was done for VS versions
@@ -146,11 +154,14 @@ class cmGlobalVisualStudioGenerator::OrderedTargetDependSet:
   public std::multiset<cmTargetDepend,
                        cmGlobalVisualStudioGenerator::TargetCompare>
 {
+  typedef std::multiset<cmTargetDepend,
+                        cmGlobalVisualStudioGenerator::TargetCompare>
+    derived;
 public:
   typedef cmGlobalGenerator::TargetDependSet TargetDependSet;
   typedef cmGlobalVisualStudioGenerator::TargetSet TargetSet;
-  OrderedTargetDependSet(TargetDependSet const&);
-  OrderedTargetDependSet(TargetSet const&);
+  OrderedTargetDependSet(TargetDependSet const&, std::string const& first);
+  OrderedTargetDependSet(TargetSet const&, std::string const& first);
 };
 
 #endif
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 7464e90..33babec 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -371,15 +371,19 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
 //----------------------------------------------------------------------------
 ///! Create a local generator appropriate to this Global Generator
 cmLocalGenerator *
-cmGlobalXCodeGenerator::CreateLocalGenerator(cmLocalGenerator* parent,
-                                             cmState::Snapshot snapshot)
+cmGlobalXCodeGenerator::CreateLocalGenerator(cmMakefile* mf)
 {
-  return new cmLocalXCodeGenerator(this, parent, snapshot);
+  return new cmLocalXCodeGenerator(this, mf);
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalXCodeGenerator::Generate()
+bool cmGlobalXCodeGenerator::Compute()
 {
+  if (!cmGlobalGenerator::Compute())
+    {
+      return false;
+    }
+
   std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
   // make sure extra targets are added before calling
   // the parent generate which will call trace depends
@@ -390,11 +394,17 @@ void cmGlobalXCodeGenerator::Generate()
     // add ALL_BUILD, INSTALL, etc
     this->AddExtraTargets(root, it->second);
     }
+  return true;
+}
+
+void cmGlobalXCodeGenerator::Generate()
+{
   this->cmGlobalGenerator::Generate();
   if(cmSystemTools::GetErrorOccuredFlag())
     {
     return;
     }
+  std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
   for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
     {
     cmLocalGenerator* root = it->second[0];
@@ -449,10 +459,12 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
   // Add ALL_BUILD
   const char* no_working_directory = 0;
   std::vector<std::string> no_depends;
-  mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
+  cmTarget* allbuild = mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
                         no_working_directory,
                         "echo", "Build all projects");
-  cmTarget* allbuild = mf->FindTarget("ALL_BUILD");
+
+  cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root);
+  mf->AddGeneratorTarget(allbuild, allBuildGt);
 
   // Refer to the main build configuration file for easy editing.
   std::string listfile = mf->GetCurrentSourceDirectory();
@@ -481,9 +493,13 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
     std::string file = this->ConvertToRelativeForMake(
       this->CurrentReRunCMakeMakefile.c_str());
     cmSystemTools::ReplaceString(file, "\\ ", " ");
-    mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, true, no_depends,
+    cmTarget* check = mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET,
+                          true, no_depends,
                           no_working_directory,
                           "make", "-f", file.c_str());
+
+    cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root);
+    mf->AddGeneratorTarget(check, checkGt);
     }
 
   // now make the allbuild depend on all the non-utility targets
@@ -502,6 +518,11 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
       {
       cmTarget& target = l->second;
 
+      if (target.GetType() == cmTarget::GLOBAL_TARGET)
+        {
+        continue;
+        }
+
       if (regenerate && (l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET))
         {
         target.AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
@@ -750,7 +771,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
                       sf->GetProperty("COMPILE_DEFINITIONS"), true);
   if (!flagsBuild.IsEmpty())
     {
-    if (flags.size())
+    if (!flags.empty())
       {
       flags += ' ';
       }
@@ -843,6 +864,10 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext,
     {
     sourcecode += ".c.objc";
     }
+  else if (ext == "swift")
+    {
+    sourcecode += ".swift";
+    }
   else if(ext == "plist")
     {
     sourcecode += ".text.plist";
@@ -1098,7 +1123,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
 
     // organize the sources
     std::vector<cmSourceFile*> classes;
-    if (!cmtarget.GetConfigCommonSourceFiles(classes))
+    if (!gtgt->GetConfigCommonSourceFiles(classes))
       {
       return false;
       }
@@ -1352,12 +1377,13 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
     return;
     }
 
-  std::string llang = cmtarget.GetLinkerLanguage("NOCONFIG");
+  cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&cmtarget);
+  std::string llang = gtgt->GetLinkerLanguage("NOCONFIG");
   if(llang.empty()) { return; }
 
   // If the language is compiled as a source trust Xcode to link with it.
-  cmTarget::LinkImplementation const* impl =
-    cmtarget.GetLinkImplementation("NOCONFIG");
+  cmLinkImplementation const* impl =
+    gtgt->GetLinkImplementation("NOCONFIG");
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
     {
@@ -1478,7 +1504,8 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
     }
 
   std::vector<cmSourceFile*> classes;
-  if (!cmtarget.GetConfigCommonSourceFiles(classes))
+  cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
+  if (!gtgt->GetConfigCommonSourceFiles(classes))
     {
     return;
     }
@@ -1664,7 +1691,7 @@ void  cmGlobalXCodeGenerator
   for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
       i != commands.end(); ++i)
     {
-    cmCustomCommandGenerator ccg(*i, configName, this->CurrentMakefile);
+    cmCustomCommandGenerator ccg(*i, configName, this->CurrentLocalGenerator);
     if(ccg.GetNumberOfCommands() > 0)
       {
       const std::vector<std::string>& outputs = ccg.GetOutputs();
@@ -1690,7 +1717,7 @@ void  cmGlobalXCodeGenerator
   for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
       i != commands.end(); ++i)
     {
-    cmCustomCommandGenerator ccg(*i, configName, this->CurrentMakefile);
+    cmCustomCommandGenerator ccg(*i, configName, this->CurrentLocalGenerator);
     if(ccg.GetNumberOfCommands() > 0)
       {
       makefileStream << "\n";
@@ -1778,7 +1805,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
 
   // Compute the compilation flags for each language.
   std::set<std::string> languages;
-  target.GetLanguages(languages, configName);
+  cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
+  gtgt->GetLanguages(languages, configName);
   std::map<std::string, std::string> cflags;
   for (std::set<std::string>::iterator li = languages.begin();
        li != languages.end(); ++li)
@@ -1800,7 +1828,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
       AddCompileOptions(flags, &target, lang, configName);
     }
 
-  std::string llang = target.GetLinkerLanguage(configName);
+  std::string llang = gtgt->GetLinkerLanguage(configName);
   if(binary && llang.empty())
     {
     cmSystemTools::Error
@@ -1826,9 +1854,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     // Add the export symbol definition for shared library objects.
     this->AppendDefines(ppDefs, exportMacro);
     }
-  cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
   std::vector<std::string> targetDefines;
-  target.GetCompileDefinitions(targetDefines, configName, "C");
+  gtgt->GetCompileDefinitions(targetDefines, configName, "C");
   this->AppendDefines(ppDefs, targetDefines);
   buildSettings->AddAttribute
     ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
@@ -1847,7 +1874,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     {
     extraLinkOptionsVar = "CMAKE_MODULE_LINKER_FLAGS";
     }
-  if(extraLinkOptionsVar.size())
+  if(!extraLinkOptionsVar.empty())
     {
     this->CurrentLocalGenerator
       ->AddConfigVariableFlags(extraLinkOptions,
@@ -1916,11 +1943,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
   std::string pnprefix;
   std::string pnbase;
   std::string pnsuffix;
-  target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
+  gtgt->GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
 
   const char* version = target.GetProperty("VERSION");
   const char* soversion = target.GetProperty("SOVERSION");
-  if(!target.HasSOName(configName) || target.IsFrameworkOnApple())
+  if(!gtgt->HasSOName(configName) || target.IsFrameworkOnApple())
     {
     version = 0;
     soversion = 0;
@@ -2178,7 +2205,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
       }
     }
   // Add framework search paths needed for linking.
-  if(cmComputeLinkInformation* cli = target.GetLinkInformation(configName))
+  if(cmComputeLinkInformation* cli = gtgt->GetLinkInformation(configName))
     {
     std::vector<std::string> const& fwDirs = cli->GetFrameworkPaths();
     for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
@@ -2307,7 +2334,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
   if(target.GetType() == cmTarget::SHARED_LIBRARY)
     {
     // Get the install_name directory for the build tree.
-    install_name_dir = target.GetInstallNameDirForBuildTree(configName);
+    install_name_dir = gtgt->GetInstallNameDirForBuildTree(configName);
     // Xcode doesn't create the correct install_name in some cases.
     // That is, if the INSTALL_PATH is empty, or if we have versioning
     // of dylib libraries, we want to specify the install_name.
@@ -2321,7 +2348,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
       install_name += install_name_dir;
       install_name += "/";
       }
-    install_name += target.GetSOName(configName);
+    install_name += gtgt->GetSOName(configName);
 
     if((realName != soName) || install_name_dir.empty())
       {
@@ -2334,7 +2361,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
                               this->CreateString(install_name_dir.c_str()));
 
   // Create the LD_RUNPATH_SEARCH_PATHS
-  cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+  cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName);
   if(pcli)
     {
     std::string search_paths;
@@ -2530,7 +2557,8 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
   if(cmtarget.GetType() == cmTarget::UTILITY)
     {
     std::vector<cmSourceFile*> sources;
-    if (!cmtarget.GetConfigCommonSourceFiles(sources))
+    cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
+    if (!gtgt->GetConfigCommonSourceFiles(sources))
       {
       return 0;
       }
@@ -2587,7 +2615,7 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
     config->SetComment(configVector[i].c_str());
     config->AddAttribute("buildSettings", buildSettings);
     }
-  if(configVector.size())
+  if(!configVector.empty())
     {
     configlist->AddAttribute("defaultConfigurationName",
                              this->CreateString(configVector[0].c_str()));
@@ -2718,7 +2746,8 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
     }
   else
     {
-    fullName = cmtarget.GetFullName(defConfig.c_str());
+    cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&cmtarget);
+    fullName = gtgt->GetFullName(defConfig.c_str());
     }
   fileRef->AddAttribute("path", this->CreateString(fullName.c_str()));
   fileRef->AddAttribute("refType", this->CreateString("0"));
@@ -2895,10 +2924,11 @@ void cmGlobalXCodeGenerator
     }
 
   // Add dependencies on other CMake targets.
-  TargetDependSet const& deps = this->GetTargetDirectDepends(*cmtarget);
+  cmGeneratorTarget* gt = this->GetGeneratorTarget(cmtarget);
+  TargetDependSet const& deps = this->GetTargetDirectDepends(gt);
   for(TargetDependSet::const_iterator i = deps.begin(); i != deps.end(); ++i)
     {
-    if(cmXCodeObject* dptarget = this->FindXCodeTarget(*i))
+    if(cmXCodeObject* dptarget = this->FindXCodeTarget((*i)->Target))
       {
       this->AddDependTarget(target, dptarget);
       }
@@ -2939,7 +2969,8 @@ void cmGlobalXCodeGenerator
       }
 
     // Compute the link library and directory information.
-    cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName);
+    cmGeneratorTarget* gtgt = this->GetGeneratorTarget(cmtarget);
+    cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName);
     if(!pcli)
       {
       continue;
@@ -3055,7 +3086,8 @@ bool cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
         }
 
       std::vector<cmSourceFile*> classes;
-      if (!cmtarget.GetConfigCommonSourceFiles(classes))
+      cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
+      if (!gtgt->GetConfigCommonSourceFiles(classes))
         {
         return false;
         }
@@ -3593,6 +3625,7 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
       {
       cmXCodeObject* target = *i;
       cmTarget* t =target->GetTarget();
+      cmGeneratorTarget *gt = this->GetGeneratorTarget(t);
 
       if(t->GetType() == cmTarget::EXECUTABLE ||
 // Nope - no post-build for OBJECT_LIRBRARY
@@ -3610,7 +3643,7 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
          t->GetType() == cmTarget::SHARED_LIBRARY ||
          t->GetType() == cmTarget::MODULE_LIBRARY)
         {
-        std::string tfull = t->GetFullPath(configName);
+        std::string tfull = gt->GetFullPath(configName);
         std::string trel = this->ConvertToRelativeForMake(tfull.c_str());
 
         // Add this target to the post-build phases of its dependencies.
@@ -3661,7 +3694,7 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
             std::string universalFile = universal;
             universalFile += *arch;
             universalFile += "/";
-            universalFile += t->GetFullName(configName);
+            universalFile += gt->GetFullName(configName);
             makefileStream << "\t/bin/rm -f "
                            <<
               this->ConvertToRelativeForMake(universalFile.c_str())
@@ -3804,33 +3837,13 @@ void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
 //----------------------------------------------------------------------------
 std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p)
 {
-  if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
-    {
-    return cmSystemTools::ConvertToOutputPath(p);
-    }
-  else
-    {
-    std::string ret =
-      this->CurrentLocalGenerator->
-        ConvertToRelativePath(this->CurrentOutputDirectoryComponents, p);
-    return cmSystemTools::ConvertToOutputPath(ret.c_str());
-    }
+  return cmSystemTools::ConvertToOutputPath(p);
 }
 
 //----------------------------------------------------------------------------
 std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p)
 {
-  if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
-    {
-    return cmSystemTools::ConvertToOutputPath(p);
-    }
-  else
-    {
-    std::string ret =
-      this->CurrentLocalGenerator->
-        ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p);
-    return cmSystemTools::ConvertToOutputPath(ret.c_str());
-    }
+  return cmSystemTools::ConvertToOutputPath(p);
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index c36e4af..102c036 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -41,8 +41,7 @@ public:
   static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
-  virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
-                                                 cmState::Snapshot snapshot);
+  virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile *mf);
 
   /**
    * Try to determine system information such as shared library
@@ -88,6 +87,7 @@ public:
   virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
   void AppendFlag(std::string& flags, std::string const& flag);
 protected:
+  virtual bool Compute();
   virtual void Generate();
 private:
   cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 7f4c4c9..2023697 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -48,6 +48,7 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
 ,GraphName("GG")
 ,GraphHeader("node [\n  fontsize = \"12\"\n];")
 ,GraphNodePrefix("node")
+,LocalGenerators(localGenerators)
 ,GenerateForExecutables(true)
 ,GenerateForStaticLibs(true)
 ,GenerateForSharedLibs(true)
@@ -55,7 +56,6 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
 ,GenerateForExternals(true)
 ,GeneratePerTarget(true)
 ,GenerateDependers(true)
-,LocalGenerators(localGenerators)
 ,HaveTargetsAndLibs(false)
 {
 }
@@ -68,8 +68,9 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
   cm.SetHomeDirectory("");
   cm.SetHomeOutputDirectory("");
   cmGlobalGenerator ggi(&cm);
-  cmsys::auto_ptr<cmLocalGenerator> lg(ggi.MakeLocalGenerator());
-  cmMakefile *mf = lg->GetMakefile();
+  cmsys::auto_ptr<cmMakefile> mf(
+        new cmMakefile(&ggi, cm.GetCurrentSnapshot()));
+  cmsys::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator(mf.get()));
 
   const char* inFileName = settingsFileName;
 
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index a7acd0e..64de684 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -69,14 +69,6 @@ protected:
   std::string GraphHeader;
   std::string GraphNodePrefix;
 
-  bool GenerateForExecutables;
-  bool GenerateForStaticLibs;
-  bool GenerateForSharedLibs;
-  bool GenerateForModuleLibs;
-  bool GenerateForExternals;
-  bool GeneratePerTarget;
-  bool GenerateDependers;
-
   std::vector<cmsys::RegularExpression> TargetsToIgnoreRegex;
 
   const std::vector<cmLocalGenerator*>& LocalGenerators;
@@ -85,6 +77,13 @@ protected:
   // maps from the actual target names to node names in dot:
   std::map<std::string, std::string> TargetNamesNodes;
 
+  bool GenerateForExecutables;
+  bool GenerateForStaticLibs;
+  bool GenerateForSharedLibs;
+  bool GenerateForModuleLibs;
+  bool GenerateForExternals;
+  bool GeneratePerTarget;
+  bool GenerateDependers;
   bool HaveTargetsAndLibs;
 };
 
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 3551f83..9e71d37 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -27,7 +27,7 @@ static std::string cmIfCommandError(
       i != args.end(); ++i)
     {
     err += " ";
-    err += cmLocalGenerator::EscapeForCMake(i->GetValue());
+    err += cmOutputConverter::EscapeForCMake(i->GetValue());
     }
   err += "\n";
   return err;
@@ -92,10 +92,6 @@ IsFunctionBlocked(const cmListFileFunction& lff,
             }
           else
             {
-            // Place this call on the call stack.
-            cmMakefileCall stack_manager(&mf, this->Functions[c], status);
-            static_cast<void>(stack_manager);
-
             // if trace is enabled, print the evaluated "elseif" statement
             if(mf.GetCMakeInstance()->GetTrace())
               {
@@ -110,7 +106,14 @@ IsFunctionBlocked(const cmListFileFunction& lff,
 
             cmake::MessageType messType;
 
-            cmConditionEvaluator conditionEvaluator(mf);
+            cmListFileContext conditionContext =
+                cmConditionEvaluator::GetConditionContext(
+                  &mf, this->Functions[c],
+                  this->GetStartingContext().FilePath);
+
+            cmConditionEvaluator conditionEvaluator(
+                  mf, conditionContext,
+                  mf.GetBacktrace(this->Functions[c]));
 
             bool isTrue = conditionEvaluator.IsTrue(
               expandedArguments, errorString, messType);
@@ -119,7 +122,8 @@ IsFunctionBlocked(const cmListFileFunction& lff,
               {
               std::string err = cmIfCommandError(expandedArguments);
               err += errorString;
-              mf.IssueMessage(messType, err);
+              cmListFileBacktrace bt = mf.GetBacktrace(this->Functions[c]);
+              mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
               if (messType == cmake::FATAL_ERROR)
                 {
                 cmSystemTools::SetFatalErrorOccured();
@@ -198,7 +202,16 @@ bool cmIfCommand
 
   cmake::MessageType status;
 
-  cmConditionEvaluator conditionEvaluator(*(this->Makefile));
+  cmListFileContext execContext = this->Makefile->GetExecutionContext();
+
+  cmCommandContext commandContext;
+  commandContext.Line = execContext.Line;
+  commandContext.Name = execContext.Name;
+
+  cmConditionEvaluator conditionEvaluator(
+        *(this->Makefile), cmConditionEvaluator::GetConditionContext(
+          this->Makefile, commandContext, execContext.FilePath),
+        this->Makefile->GetBacktrace());
 
   bool isTrue = conditionEvaluator.IsTrue(
     expandedArguments, errorString, status);
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index b94ad25..8890e2b 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -125,6 +125,7 @@ bool cmIncludeCommand
         return false;
         }
       }
+    gg->CreateGenerationObjects();
     gg->GenerateImportFile(fname_abs);
     }
 
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 899b088..d3c2e26 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -27,7 +27,9 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target,
 {
   cmInstallGenerator::MessageLevel message =
     cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
-  return new cmInstallTargetGenerator(target, args.GetDestination().c_str(),
+  target.SetHaveInstallRule(true);
+  return new cmInstallTargetGenerator(target.GetName(),
+                        args.GetDestination().c_str(),
                         impLib, args.GetPermissions().c_str(),
                         args.GetConfigurations(), args.GetComponent().c_str(),
                         message,
@@ -41,7 +43,7 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator(
 {
   cmInstallGenerator::MessageLevel message =
     cmInstallGenerator::SelectMessageLevel(mf);
-  return new cmInstallFilesGenerator(mf,
+  return new cmInstallFilesGenerator(
                         absFiles, args.GetDestination().c_str(),
                         programs, args.GetPermissions().c_str(),
                         args.GetConfigurations(), args.GetComponent().c_str(),
@@ -1399,7 +1401,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
       ica.GetDestination().c_str(),
       ica.GetPermissions().c_str(), ica.GetConfigurations(),
       ica.GetComponent().c_str(), message, fname.c_str(),
-      name_space.GetCString(), exportOld.IsEnabled(), this->Makefile);
+      name_space.GetCString(), exportOld.IsEnabled());
   this->Makefile->AddInstallGenerator(exportGenerator);
 
   return true;
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index 7593380..78cb5f0 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -12,6 +12,8 @@
 #include "cmInstallDirectoryGenerator.h"
 
 #include "cmTarget.h"
+#include "cmGeneratorExpression.h"
+#include "cmLocalGenerator.h"
 
 //----------------------------------------------------------------------------
 cmInstallDirectoryGenerator
@@ -25,10 +27,16 @@ cmInstallDirectoryGenerator
                               const char* literal_args,
                               bool optional):
   cmInstallGenerator(dest, configurations, component, message),
+  LocalGenerator(0),
   Directories(dirs),
   FilePermissions(file_permissions), DirPermissions(dir_permissions),
   LiteralArguments(literal_args), Optional(optional)
 {
+  // We need per-config actions if destination have generator expressions.
+  if(cmGeneratorExpression::Find(Destination) != std::string::npos)
+    {
+    this->ActionsPerConfig = true;
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -37,15 +45,43 @@ cmInstallDirectoryGenerator
 {
 }
 
+void cmInstallDirectoryGenerator::Compute(cmLocalGenerator* lg)
+{
+  LocalGenerator = lg;
+}
+
 //----------------------------------------------------------------------------
 void
 cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
                                                    Indent const& indent)
 {
+  if(this->ActionsPerConfig)
+    {
+    this->cmInstallGenerator::GenerateScriptActions(os, indent);
+    }
+  else
+    {
+    this->AddDirectoryInstallRule(os, "", indent);
+    }
+}
+
+void cmInstallDirectoryGenerator::GenerateScriptForConfig(
+  std::ostream& os,
+  const std::string& config,
+  Indent const& indent)
+{
+  this->AddDirectoryInstallRule(os, config, indent);
+}
+
+void cmInstallDirectoryGenerator::AddDirectoryInstallRule(
+  std::ostream& os,
+  const std::string& config,
+  Indent const& indent)
+{
   // Write code to install the directories.
   const char* no_rename = 0;
   this->AddInstallRule(os,
-                       this->Destination,
+                       this->GetDestination(config),
                        cmInstallType_DIRECTORY,
                        this->Directories,
                        this->Optional,
@@ -54,3 +90,12 @@ cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
                        no_rename, this->LiteralArguments.c_str(),
                        indent);
 }
+
+//----------------------------------------------------------------------------
+std::string
+cmInstallDirectoryGenerator::GetDestination(std::string const& config) const
+{
+  cmGeneratorExpression ge;
+  return ge.Parse(this->Destination)
+    ->Evaluate(this->LocalGenerator->GetMakefile(), config);
+}
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index 165ab91..04107e1 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -31,8 +31,19 @@ public:
                               bool optional = false);
   virtual ~cmInstallDirectoryGenerator();
 
+  void Compute(cmLocalGenerator* lg);
+
+  std::string GetDestination(std::string const& config) const;
+
 protected:
   virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
+  virtual void GenerateScriptForConfig(std::ostream& os,
+                                       const std::string& config,
+                                       Indent const& indent);
+  void AddDirectoryInstallRule(std::ostream& os,
+                               const std::string& config,
+                               Indent const& indent);
+  cmLocalGenerator* LocalGenerator;
   std::vector<std::string> Directories;
   std::string FilePermissions;
   std::string DirPermissions;
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 7f6aa4d..97b9405 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -34,15 +34,14 @@ cmInstallExportGenerator::cmInstallExportGenerator(
   const char* component,
   MessageLevel message,
   const char* filename, const char* name_space,
-  bool exportOld,
-  cmMakefile* mf)
+  bool exportOld)
   :cmInstallGenerator(destination, configurations, component, message)
   ,ExportSet(exportSet)
   ,FilePermissions(file_permissions)
   ,FileName(filename)
   ,Namespace(name_space)
   ,ExportOld(exportOld)
-  ,Makefile(mf)
+  ,LocalGenerator(0)
 {
   this->EFGen = new cmExportInstallFileGenerator(this);
   exportSet->AddInstallation(this);
@@ -54,12 +53,18 @@ cmInstallExportGenerator::~cmInstallExportGenerator()
   delete this->EFGen;
 }
 
+void cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
+{
+  this->LocalGenerator = lg;
+}
+
 //----------------------------------------------------------------------------
 void cmInstallExportGenerator::ComputeTempDir()
 {
   // Choose a temporary directory in which to generate the import
   // files to be installed.
-  this->TempDir = this->Makefile->GetCurrentBinaryDirectory();
+  this->TempDir =
+      this->LocalGenerator->GetMakefile()->GetCurrentBinaryDirectory();
   this->TempDir += cmake::GetCMakeFilesDirectory();
   this->TempDir += "/Export";
   if(this->Destination.empty())
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index 3e078f2..885ed05 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -32,12 +32,14 @@ public:
                            const char* component,
                            MessageLevel message,
                            const char* filename, const char* name_space,
-                           bool exportOld, cmMakefile* mf);
+                           bool exportOld);
   ~cmInstallExportGenerator();
 
   cmExportSet* GetExportSet() {return this->ExportSet;}
 
-  cmMakefile* GetMakefile() const { return this->Makefile; }
+  void Compute(cmLocalGenerator* lg);
+
+  cmLocalGenerator* GetLocalGenerator() const { return this->LocalGenerator; }
 
   const std::string& GetNamespace() const { return this->Namespace; }
 
@@ -57,7 +59,7 @@ protected:
   std::string FileName;
   std::string Namespace;
   bool ExportOld;
-  cmMakefile* Makefile;
+  cmLocalGenerator* LocalGenerator;
 
   std::string TempDir;
   std::string MainImportFile;
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index 508c373..68557bd 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -128,7 +128,7 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
   cmInstallGenerator::MessageLevel message =
     cmInstallGenerator::SelectMessageLevel(this->Makefile);
   this->Makefile->AddInstallGenerator(
-    new cmInstallFilesGenerator(this->Makefile, this->Files,
+    new cmInstallFilesGenerator(this->Files,
                                 destination.c_str(), false,
                                 no_permissions, no_configurations,
                                 no_component.c_str(), message, no_rename));
diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h
index 4551ab1..8062d11 100644
--- a/Source/cmInstallFilesCommand.h
+++ b/Source/cmInstallFilesCommand.h
@@ -52,12 +52,6 @@ public:
   virtual void FinalPass();
   virtual bool HasFinalPass() const { return !this->IsFilesForm; }
 
-  /** This command is kept for compatibility with older CMake versions. */
-  virtual bool IsDiscouraged() const
-    {
-    return true;
-    }
-
   cmTypeMacro(cmInstallFilesCommand, cmCommand);
 
 protected:
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 28c27c2..e2c16c8 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -14,11 +14,11 @@
 #include "cmGeneratorExpression.h"
 #include "cmMakefile.h"
 #include "cmSystemTools.h"
+#include "cmLocalGenerator.h"
 
 //----------------------------------------------------------------------------
 cmInstallFilesGenerator
-::cmInstallFilesGenerator(cmMakefile* mf,
-                          std::vector<std::string> const& files,
+::cmInstallFilesGenerator(std::vector<std::string> const& files,
                           const char* dest, bool programs,
                           const char* file_permissions,
                           std::vector<std::string> const& configurations,
@@ -27,11 +27,19 @@ cmInstallFilesGenerator
                           const char* rename,
                           bool optional):
   cmInstallGenerator(dest, configurations, component, message),
-  Makefile(mf),
-  Files(files), Programs(programs),
+  LocalGenerator(0),
+  Files(files),
   FilePermissions(file_permissions),
-  Rename(rename), Optional(optional)
+  Rename(rename),
+  Programs(programs),
+  Optional(optional)
 {
+  // We need per-config actions if the destination has generator expressions.
+  if(cmGeneratorExpression::Find(Destination) != std::string::npos)
+    {
+    this->ActionsPerConfig = true;
+    }
+
   // We need per-config actions if any files have generator expressions.
   for(std::vector<std::string>::const_iterator i = files.begin();
       !this->ActionsPerConfig && i != files.end(); ++i)
@@ -49,15 +57,31 @@ cmInstallFilesGenerator
 {
 }
 
+void cmInstallFilesGenerator::Compute(cmLocalGenerator* lg)
+{
+  this->LocalGenerator = lg;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmInstallFilesGenerator::GetDestination(std::string const& config) const
+{
+  cmGeneratorExpression ge;
+  return ge.Parse(this->Destination)
+    ->Evaluate(this->LocalGenerator->GetMakefile(), config);
+}
+
 //----------------------------------------------------------------------------
 void cmInstallFilesGenerator::AddFilesInstallRule(
-  std::ostream& os, Indent const& indent,
+  std::ostream& os,
+  const std::string config,
+  Indent const& indent,
   std::vector<std::string> const& files)
 {
   // Write code to install the files.
   const char* no_dir_permissions = 0;
   this->AddInstallRule(os,
-                       this->Destination,
+                       this->GetDestination(config),
                        (this->Programs
                         ? cmInstallType_PROGRAMS
                         : cmInstallType_FILES),
@@ -77,7 +101,7 @@ void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os,
     }
   else
     {
-    this->AddFilesInstallRule(os, indent, this->Files);
+    this->AddFilesInstallRule(os, "", indent, this->Files);
     }
 }
 
@@ -92,8 +116,8 @@ void cmInstallFilesGenerator::GenerateScriptForConfig(std::ostream& os,
       i != this->Files.end(); ++i)
     {
     cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*i);
-    cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, config),
-                                      files);
+    cmSystemTools::ExpandListArgument(cge->Evaluate(
+        this->LocalGenerator->GetMakefile(), config), files);
     }
-  this->AddFilesInstallRule(os, indent, files);
+  this->AddFilesInstallRule(os, config, indent, files);
 }
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index 0dbd712..bfe4039 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -14,16 +14,13 @@
 
 #include "cmInstallGenerator.h"
 
-class cmMakefile;
-
 /** \class cmInstallFilesGenerator
  * \brief Generate file installation rules.
  */
 class cmInstallFilesGenerator: public cmInstallGenerator
 {
 public:
-  cmInstallFilesGenerator(cmMakefile* mf,
-                          std::vector<std::string> const& files,
+  cmInstallFilesGenerator(std::vector<std::string> const& files,
                           const char* dest, bool programs,
                           const char* file_permissions,
                           std::vector<std::string> const& configurations,
@@ -33,19 +30,25 @@ public:
                           bool optional = false);
   virtual ~cmInstallFilesGenerator();
 
+  void Compute(cmLocalGenerator* lg);
+
+  std::string GetDestination(std::string const& config) const;
+
 protected:
   virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
   virtual void GenerateScriptForConfig(std::ostream& os,
                                        const std::string& config,
                                        Indent const& indent);
-  void AddFilesInstallRule(std::ostream& os, Indent const& indent,
+  void AddFilesInstallRule(std::ostream& os,
+                           const std::string config,
+                           Indent const& indent,
                            std::vector<std::string> const& files);
 
-  cmMakefile* Makefile;
+  cmLocalGenerator* LocalGenerator;
   std::vector<std::string> Files;
-  bool Programs;
   std::string FilePermissions;
   std::string Rename;
+  bool Programs;
   bool Optional;
 };
 
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index c4191e4..b8e5b53 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -62,6 +62,8 @@ public:
   /** Select message level from CMAKE_INSTALL_MESSAGE or 'never'.  */
   static MessageLevel SelectMessageLevel(cmMakefile* mf, bool never = false);
 
+  virtual void Compute(cmLocalGenerator*) {}
+
 protected:
   virtual void GenerateScript(std::ostream& os);
 
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index be8096c..e6fbe88 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -91,7 +91,7 @@ void cmInstallProgramsCommand::FinalPass()
   cmInstallGenerator::MessageLevel message =
     cmInstallGenerator::SelectMessageLevel(this->Makefile);
   this->Makefile->AddInstallGenerator(
-    new cmInstallFilesGenerator(this->Makefile, this->Files,
+    new cmInstallFilesGenerator(this->Files,
                                 destination.c_str(), true,
                                 no_permissions, no_configurations,
                                 no_component.c_str(), message, no_rename));
diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h
index 90c7ba3..524debf 100644
--- a/Source/cmInstallProgramsCommand.h
+++ b/Source/cmInstallProgramsCommand.h
@@ -53,12 +53,6 @@ public:
 
   virtual bool HasFinalPass() const { return true; }
 
-  /** This command is kept for compatibility with older CMake versions. */
-  virtual bool IsDiscouraged() const
-    {
-    return true;
-    }
-
   cmTypeMacro(cmInstallProgramsCommand, cmCommand);
 
 protected:
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 082a78c..30cf175 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -16,24 +16,30 @@
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmGeneratorTarget.h"
 #include "cmake.h"
+#include "cmGeneratorTarget.h"
 
 #include <assert.h>
 
 //----------------------------------------------------------------------------
 cmInstallTargetGenerator
-::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib,
+::cmInstallTargetGenerator(const std::string& targetName,
+                           const char* dest, bool implib,
                            const char* file_permissions,
                            std::vector<std::string> const& configurations,
                            const char* component,
                            MessageLevel message,
                            bool optional):
-  cmInstallGenerator(dest, configurations, component, message), Target(&t),
-  ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional)
+  cmInstallGenerator(dest, configurations, component, message),
+  TargetName(targetName),
+  Target(0),
+  FilePermissions(file_permissions),
+  ImportLibrary(implib),
+  Optional(optional)
 {
   this->ActionsPerConfig = true;
   this->NamelinkMode = NamelinkModeNone;
-  this->Target->SetHaveInstallRule(true);
 }
 
 //----------------------------------------------------------------------------
@@ -69,13 +75,15 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
   std::string fromDirConfig;
   if(this->Target->NeedRelinkBeforeInstall(config))
     {
-    fromDirConfig = this->Target->GetMakefile()->GetCurrentBinaryDirectory();
+    fromDirConfig =
+        this->Target->Target->GetMakefile()->GetCurrentBinaryDirectory();
     fromDirConfig += cmake::GetCMakeFilesDirectory();
     fromDirConfig += "/CMakeRelink.dir/";
     }
   else
     {
-    fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
+    fromDirConfig =
+        this->Target->Target->GetDirectory(config, this->ImportLibrary);
     fromDirConfig += "/";
     }
   std::string toDir =
@@ -86,7 +94,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
   std::vector<std::string> filesFrom;
   std::vector<std::string> filesTo;
   std::string literal_args;
-  cmTarget::TargetType targetType = this->Target->GetType();
+  cmTarget::TargetType targetType =
+      static_cast<cmTarget::TargetType>(this->Target->GetType());
   cmInstallType type = cmInstallType();
   switch(targetType)
     {
@@ -103,7 +112,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
     case cmTarget::UTILITY:
     case cmTarget::GLOBAL_TARGET:
     case cmTarget::UNKNOWN_LIBRARY:
-      this->Target->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
+      this->Target->Target->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
         "cmInstallTargetGenerator created with non-installable target.");
       return;
     }
@@ -126,7 +135,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
       filesFrom.push_back(from1);
       filesTo.push_back(to1);
       std::string targetNameImportLib;
-      if(this->Target->GetImplibGNUtoMS(targetNameImport,
+      if(this->Target->Target->GetImplibGNUtoMS(targetNameImport,
                                         targetNameImportLib))
         {
         filesFrom.push_back(fromDirConfig + targetNameImportLib);
@@ -142,7 +151,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
       std::string to1 = toDir + targetName;
 
       // Handle OSX Bundles.
-      if(this->Target->IsAppBundleOnApple())
+      if(this->Target->Target->IsAppBundleOnApple())
         {
         // Install the whole app bundle directory.
         type = cmInstallType_DIRECTORY;
@@ -176,7 +185,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
     std::string targetNameReal;
     std::string targetNameImport;
     std::string targetNamePDB;
-    this->Target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
+    this->Target->GetLibraryNames(targetName, targetNameSO,
+                                          targetNameReal,
                                   targetNameImport, targetNamePDB,
                                   config);
     if(this->ImportLibrary)
@@ -189,7 +199,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
       filesFrom.push_back(from1);
       filesTo.push_back(to1);
       std::string targetNameImportLib;
-      if(this->Target->GetImplibGNUtoMS(targetNameImport,
+      if(this->Target->Target->GetImplibGNUtoMS(targetNameImport,
                                         targetNameImportLib))
         {
         filesFrom.push_back(fromDirConfig + targetNameImportLib);
@@ -199,7 +209,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
       // An import library looks like a static library.
       type = cmInstallType_STATIC_LIBRARY;
       }
-    else if(this->Target->IsFrameworkOnApple())
+    else if(this->Target->Target->IsFrameworkOnApple())
       {
       // There is a bug in cmInstallCommand if this fails.
       assert(this->NamelinkMode == NamelinkModeNone);
@@ -217,7 +227,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
       filesFrom.push_back(from1);
       filesTo.push_back(to1);
       }
-    else if(this->Target->IsCFBundleOnApple())
+    else if(this->Target->Target->IsCFBundleOnApple())
       {
       // Install the whole app bundle directory.
       type = cmInstallType_DIRECTORY;
@@ -341,7 +351,7 @@ cmInstallTargetGenerator::GetDestination(std::string const& config) const
 {
   cmGeneratorExpression ge;
   return ge.Parse(this->Destination)
-    ->Evaluate(this->Target->GetMakefile(), config);
+    ->Evaluate(this->Target->Target->GetMakefile(), config);
 }
 
 //----------------------------------------------------------------------------
@@ -350,7 +360,7 @@ cmInstallTargetGenerator::GetInstallFilename(const std::string& config) const
 {
   NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
   return
-    cmInstallTargetGenerator::GetInstallFilename(this->Target, config,
+    cmInstallTargetGenerator::GetInstallFilename(this->Target->Target, config,
                                                  nameType);
 }
 
@@ -362,13 +372,16 @@ cmInstallTargetGenerator::GetInstallFilename(cmTarget const* target,
 {
   std::string fname;
   // Compute the name of the library.
+  cmGeneratorTarget *gtgt = target->GetMakefile()
+                                  ->GetGlobalGenerator()
+                                  ->GetGeneratorTarget(target);
   if(target->GetType() == cmTarget::EXECUTABLE)
     {
     std::string targetName;
     std::string targetNameReal;
     std::string targetNameImport;
     std::string targetNamePDB;
-    target->GetExecutableNames(targetName, targetNameReal,
+    gtgt->GetExecutableNames(targetName, targetNameReal,
                                targetNameImport, targetNamePDB,
                                config);
     if(nameType == NameImplib)
@@ -398,7 +411,7 @@ cmInstallTargetGenerator::GetInstallFilename(cmTarget const* target,
     std::string targetNameReal;
     std::string targetNameImport;
     std::string targetNamePDB;
-    target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
+    gtgt->GetLibraryNames(targetName, targetNameSO, targetNameReal,
                             targetNameImport, targetNamePDB, config);
     if(nameType == NameImplib)
       {
@@ -429,6 +442,12 @@ cmInstallTargetGenerator::GetInstallFilename(cmTarget const* target,
   return fname;
 }
 
+void cmInstallTargetGenerator::Compute(cmLocalGenerator* lg)
+{
+  this->Target = lg->GetGlobalGenerator()->GetGeneratorTarget(
+        lg->GetMakefile()->FindTarget(this->TargetName));
+}
+
 //----------------------------------------------------------------------------
 void
 cmInstallTargetGenerator
@@ -531,8 +550,8 @@ cmInstallTargetGenerator
     }
 
   // Fix the install_name settings in installed binaries.
-  std::string installNameTool =
-    this->Target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
+  std::string installNameTool = this->Target->Target->GetMakefile()
+      ->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
 
   if(installNameTool.empty())
     {
@@ -557,11 +576,14 @@ cmInstallTargetGenerator
         continue;
         }
 
+      cmGeneratorTarget *gtgt = tgt->GetMakefile()
+                                          ->GetGlobalGenerator()
+                                          ->GetGeneratorTarget(tgt);
       // If the build tree and install tree use different path
       // components of the install_name field then we need to create a
       // mapping to be applied after installation.
-      std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
-      std::string for_install = tgt->GetInstallNameDirForInstallTree();
+      std::string for_build = gtgt->GetInstallNameDirForBuildTree(config);
+      std::string for_install = gtgt->GetInstallNameDirForInstallTree();
       if(for_build != for_install)
         {
         // The directory portions differ.  Append the filename to
@@ -590,7 +612,7 @@ cmInstallTargetGenerator
     std::string for_install =
       this->Target->GetInstallNameDirForInstallTree();
 
-    if(this->Target->IsFrameworkOnApple() && for_install.empty())
+    if(this->Target->Target->IsFrameworkOnApple() && for_install.empty())
       {
       // Frameworks seem to have an id corresponding to their own full
       // path.
@@ -604,7 +626,7 @@ cmInstallTargetGenerator
       {
       // Prepare to refer to the install-tree install_name.
       new_id = for_install;
-      new_id += this->GetInstallFilename(this->Target, config, NameSO);
+      new_id += this->GetInstallFilename(this->Target->Target, config, NameSO);
       }
     }
 
@@ -641,9 +663,9 @@ cmInstallTargetGenerator
     {
     return;
     }
-
   // Skip if on Apple
-  if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+  if(this->Target->Target->GetMakefile()
+     ->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
     {
     return;
     }
@@ -688,7 +710,7 @@ cmInstallTargetGenerator
     return;
     }
 
-  cmMakefile* mf = this->Target->GetMakefile();
+  cmMakefile* mf = this->Target->Target->GetMakefile();
 
   if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
     {
@@ -800,20 +822,20 @@ cmInstallTargetGenerator::AddStripRule(std::ostream& os,
     }
 
   // Don't handle OSX Bundles.
-  if(this->Target->GetMakefile()->IsOn("APPLE") &&
-     this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
+  if(this->Target->Target->GetMakefile()->IsOn("APPLE") &&
+     this->Target->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
     {
     return;
     }
 
-  if(! this->Target->GetMakefile()->IsSet("CMAKE_STRIP"))
+  if(! this->Target->Target->GetMakefile()->IsSet("CMAKE_STRIP"))
     {
     return;
     }
 
   os << indent << "if(CMAKE_INSTALL_DO_STRIP)\n";
   os << indent << "  execute_process(COMMAND \""
-     << this->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
+     << this->Target->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
      << "\" \"" << toDestDirPath << "\")\n";
   os << indent << "endif()\n";
 }
@@ -832,13 +854,13 @@ cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
 
   // Perform post-installation processing on the file depending
   // on its type.
-  if(!this->Target->GetMakefile()->IsOn("APPLE"))
+  if(!this->Target->Target->GetMakefile()->IsOn("APPLE"))
     {
     return;
     }
 
   std::string ranlib =
-    this->Target->GetMakefile()->GetRequiredDefinition("CMAKE_RANLIB");
+    this->Target->Target->GetMakefile()->GetRequiredDefinition("CMAKE_RANLIB");
   if(ranlib.empty())
     {
     return;
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 075c8a4..a8f4a75 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -13,8 +13,9 @@
 #define cmInstallTargetGenerator_h
 
 #include "cmInstallGenerator.h"
-#include "cmTarget.h"
-#include "cmGeneratorTarget.h"
+
+class cmTarget;
+class cmGeneratorTarget;
 
 /** \class cmInstallTargetGenerator
  * \brief Generate target installation rules.
@@ -23,7 +24,7 @@ class cmInstallTargetGenerator: public cmInstallGenerator
 {
 public:
   cmInstallTargetGenerator(
-    cmTarget& t, const char* dest, bool implib,
+    std::string const& targetName, const char* dest, bool implib,
     const char* file_permissions,
     std::vector<std::string> const& configurations,
     const char* component,
@@ -57,7 +58,10 @@ public:
                                         const std::string& config,
                                         NameType nameType = NameNormal);
 
-  cmTarget* GetTarget() const { return this->Target; }
+  void Compute(cmLocalGenerator* lg);
+
+  cmGeneratorTarget* GetTarget() const { return this->Target; }
+
   bool IsImportLibrary() const { return this->ImportLibrary; }
 
   std::string GetDestination(std::string const& config) const;
@@ -99,12 +103,12 @@ protected:
   void AddRanlibRule(std::ostream& os, Indent const& indent,
                      const std::string& toDestDirPath);
 
-  cmTarget* Target;
-  bool ImportLibrary;
+  std::string TargetName;
+  cmGeneratorTarget* Target;
   std::string FilePermissions;
-  bool Optional;
   NamelinkModeType NamelinkMode;
-  cmGeneratorTarget* GeneratorTarget;
+  bool ImportLibrary;
+  bool Optional;
 };
 
 #endif
diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h
index e6cbe6e..05160eb 100644
--- a/Source/cmInstallTargetsCommand.h
+++ b/Source/cmInstallTargetsCommand.h
@@ -44,12 +44,6 @@ public:
    */
   virtual std::string GetName() const { return "install_targets";}
 
-  /** This command is kept for compatibility with older CMake versions. */
-  virtual bool IsDiscouraged() const
-    {
-    return true;
-    }
-
   cmTypeMacro(cmInstallTargetsCommand, cmCommand);
 };
 
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index 8c52b48..fa5e815 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -44,7 +44,7 @@ cmInstalledFile::Property::~Property()
 void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name)
 {
   cmListFileBacktrace backtrace = mf->GetBacktrace();
-  cmGeneratorExpression ge(&backtrace);
+  cmGeneratorExpression ge(backtrace);
 
   this->Name = name;
   this->NameExpression = ge.Parse(name).release();
@@ -81,7 +81,7 @@ void cmInstalledFile::AppendProperty(cmMakefile const* mf,
   const std::string& prop, const char* value, bool /*asString*/)
 {
   cmListFileBacktrace backtrace = mf->GetBacktrace();
-  cmGeneratorExpression ge(&backtrace);
+  cmGeneratorExpression ge(backtrace);
 
   Property& property = this->Properties[prop];
   property.ValueExpressions.push_back(ge.Parse(value).release());
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
index f486bf7..b6c0072 100644
--- a/Source/cmLinkDirectoriesCommand.cxx
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -65,5 +65,5 @@ void cmLinkDirectoriesCommand::AddLinkDir(std::string const& dir)
       unixPath = tmp;
       }
     }
-  this->Makefile->AddLinkDirectory(unixPath);
+  this->Makefile->AppendProperty("LINK_DIRECTORIES", unixPath.c_str());
 }
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
new file mode 100644
index 0000000..10dd465
--- /dev/null
+++ b/Source/cmLinkItem.h
@@ -0,0 +1,121 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2004-2015 Kitware, Inc.
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+
+#ifndef cmLinkItem_h
+#define cmLinkItem_h
+
+#include "cmListFileCache.h"
+
+class cmTarget;
+
+// Basic information about each link item.
+class cmLinkItem: public std::string
+{
+  typedef std::string std_string;
+public:
+  cmLinkItem(): std_string(), Target(0) {}
+  cmLinkItem(const std_string& n,
+             cmTarget const* t): std_string(n), Target(t) {}
+  cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {}
+  cmTarget const* Target;
+};
+
+class cmLinkImplItem: public cmLinkItem
+{
+public:
+  cmLinkImplItem(): cmLinkItem(), Backtrace(), FromGenex(false) {}
+  cmLinkImplItem(std::string const& n,
+                 cmTarget const* t,
+                 cmListFileBacktrace const& bt,
+                 bool fromGenex):
+    cmLinkItem(n, t), Backtrace(bt), FromGenex(fromGenex) {}
+  cmLinkImplItem(cmLinkImplItem const& r):
+    cmLinkItem(r), Backtrace(r.Backtrace), FromGenex(r.FromGenex) {}
+  cmListFileBacktrace Backtrace;
+  bool FromGenex;
+};
+
+/** The link implementation specifies the direct library
+    dependencies needed by the object files of the target.  */
+struct cmLinkImplementationLibraries
+{
+  // Libraries linked directly in this configuration.
+  std::vector<cmLinkImplItem> Libraries;
+
+  // Libraries linked directly in other configurations.
+  // Needed only for OLD behavior of CMP0003.
+  std::vector<cmLinkItem> WrongConfigLibraries;
+};
+
+struct cmLinkInterfaceLibraries
+{
+  // Libraries listed in the interface.
+  std::vector<cmLinkItem> Libraries;
+};
+
+struct cmLinkInterface: public cmLinkInterfaceLibraries
+{
+  // Languages whose runtime libraries must be linked.
+  std::vector<std::string> Languages;
+
+  // Shared library dependencies needed for linking on some platforms.
+  std::vector<cmLinkItem> SharedDeps;
+
+  // Number of repetitions of a strongly connected component of two
+  // or more static libraries.
+  int Multiplicity;
+
+  // Libraries listed for other configurations.
+  // Needed only for OLD behavior of CMP0003.
+  std::vector<cmLinkItem> WrongConfigLibraries;
+
+  bool ImplementationIsInterface;
+
+  cmLinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
+};
+
+struct cmOptionalLinkInterface: public cmLinkInterface
+{
+  cmOptionalLinkInterface():
+    LibrariesDone(false), AllDone(false),
+    Exists(false), HadHeadSensitiveCondition(false),
+    ExplicitLibraries(0) {}
+  bool LibrariesDone;
+  bool AllDone;
+  bool Exists;
+  bool HadHeadSensitiveCondition;
+  const char* ExplicitLibraries;
+};
+
+struct cmHeadToLinkInterfaceMap:
+    public std::map<cmTarget const*, cmOptionalLinkInterface>
+{
+};
+
+struct cmLinkImplementation: public cmLinkImplementationLibraries
+{
+  // Languages whose runtime libraries must be linked.
+  std::vector<std::string> Languages;
+};
+
+// Cache link implementation computation from each configuration.
+struct cmOptionalLinkImplementation: public cmLinkImplementation
+{
+  cmOptionalLinkImplementation():
+    LibrariesDone(false), LanguagesDone(false),
+    HadHeadSensitiveCondition(false) {}
+  bool LibrariesDone;
+  bool LanguagesDone;
+  bool HadHeadSensitiveCondition;
+};
+
+#endif
diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h
index c572439..1ddefc4 100644
--- a/Source/cmLinkLibrariesCommand.h
+++ b/Source/cmLinkLibrariesCommand.h
@@ -44,12 +44,6 @@ public:
    */
   virtual std::string GetName() const { return "link_libraries";}
 
-  /** This command is kept for compatibility with older CMake versions. */
-  virtual bool IsDiscouraged() const
-    {
-    return true;
-    }
-
   cmTypeMacro(cmLinkLibrariesCommand, cmCommand);
 };
 
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
new file mode 100644
index 0000000..721a246
--- /dev/null
+++ b/Source/cmLinkedTree.h
@@ -0,0 +1,195 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Stephen Kelly <steveire at gmail.com>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmLinkedTree_h
+#define cmLinkedTree_h
+
+#include "cmStandardIncludes.h"
+
+#include <assert.h>
+
+/**
+  @brief A adaptor for traversing a tree structure in a vector
+
+  This class is not intended to be wholly generic like a standard library
+  container adaptor.  Mostly it exists to facilitate code sharing for the
+  needs of the cmState.  For example, the Truncate() method is a specific
+  requirement of the cmState.
+
+  An empty cmLinkedTree provides a Root() method, and an Extend() method,
+  each of which return iterators.  A Tree can be built up by extending
+  from the root, and then extending from any other iterator.
+
+  An iterator resulting from this tree construction can be
+  forward-only-iterated toward the root.  Extending the tree never
+  invalidates existing iterators.
+ */
+template<typename T>
+class cmLinkedTree
+{
+  typedef typename std::vector<T>::size_type PositionType;
+  typedef T* PointerType;
+  typedef T& ReferenceType;
+public:
+  class iterator : public std::iterator<std::forward_iterator_tag, T>
+  {
+    friend class cmLinkedTree;
+    cmLinkedTree* Tree;
+
+    // The Position is always 'one past the end'.
+    PositionType Position;
+
+    iterator(cmLinkedTree* tree, PositionType pos)
+      : Tree(tree), Position(pos)
+    {
+
+    }
+
+  public:
+    iterator()
+      : Tree(0), Position(0)
+    {
+
+    }
+
+    void operator++()
+    {
+      assert(this->Tree);
+      assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+      assert(this->Position <= this->Tree->Data.size());
+      assert(this->Position > 0);
+      this->Position = this->Tree->UpPositions[this->Position - 1];
+    }
+
+    PointerType operator->() const
+    {
+      assert(this->Tree);
+      assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+      assert(this->Position <= this->Tree->Data.size());
+      assert(this->Position > 0);
+      return this->Tree->GetPointer(this->Position - 1);
+    }
+
+    PointerType operator->()
+    {
+      assert(this->Tree);
+      assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+      assert(this->Position <= this->Tree->Data.size());
+      assert(this->Position > 0);
+      return this->Tree->GetPointer(this->Position - 1);
+    }
+
+    ReferenceType operator*() const
+    {
+      assert(this->Tree);
+      assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+      assert(this->Position <= this->Tree->Data.size());
+      assert(this->Position > 0);
+      return this->Tree->GetReference(this->Position - 1);
+    }
+
+    ReferenceType operator*()
+    {
+      assert(this->Tree);
+      assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+      assert(this->Position <= this->Tree->Data.size());
+      assert(this->Position > 0);
+      return this->Tree->GetReference(this->Position - 1);
+    }
+
+    bool operator==(iterator other) const
+    {
+      assert(this->Tree);
+      assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+      assert(this->Tree == other.Tree);
+      return this->Position == other.Position;
+    }
+
+    bool operator!=(iterator other) const
+    {
+      assert(this->Tree);
+      assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+      return !(*this == other);
+    }
+
+    bool IsValid() const
+    {
+      if (!this->Tree)
+        {
+        return false;
+        }
+      return this->Position <= this->Tree->Data.size();
+    }
+
+    bool StrictWeakOrdered(iterator other) const
+    {
+      assert(this->Tree);
+      assert(this->Tree == other.Tree);
+      return this->Position < other.Position;
+    }
+  };
+
+  iterator Root() const
+  {
+    return iterator(const_cast<cmLinkedTree*>(this), 0);
+  }
+
+  iterator Extend(iterator it)
+  {
+    return Extend_impl(it, T());
+  }
+
+  iterator Extend(iterator it, T t)
+  {
+    return Extend_impl(it, t);
+  }
+
+  iterator Truncate()
+  {
+    assert(this->UpPositions.size() > 0);
+    this->UpPositions.erase(this->UpPositions.begin() + 1,
+                            this->UpPositions.end());
+    assert(this->Data.size() > 0);
+    this->Data.erase(this->Data.begin() + 1, this->Data.end());
+    return iterator(this, 1);
+  }
+
+  void Clear()
+  {
+    this->UpPositions.clear();
+    this->Data.clear();
+  }
+
+private:
+  T& GetReference(PositionType pos)
+  {
+    return this->Data[pos];
+  }
+
+  T* GetPointer(PositionType pos)
+  {
+    return &this->Data[pos];
+  }
+
+  iterator Extend_impl(iterator it, T t)
+  {
+    assert(this->UpPositions.size() == this->Data.size());
+    assert(it.Position <= this->UpPositions.size());
+    this->UpPositions.push_back(it.Position);
+    this->Data.push_back(t);
+    return iterator(this, this->UpPositions.size());
+  }
+
+  std::vector<T> Data;
+  std::vector<PositionType> UpPositions;
+};
+
+#endif
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index f96b4a8..6041fb7 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -247,7 +247,7 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
     {
     listString += ";";
     }
-  listString += cmJoin(cmRange(args).advance(2), ";");
+  listString += cmJoin(cmMakeRange(args).advance(2), ";");
 
   this->Makefile->AddDefinition(listName, listString.c_str());
   return true;
@@ -361,9 +361,9 @@ bool cmListCommand
   std::vector<std::string>::const_iterator remBegin = remove.begin();
 
   std::vector<std::string>::const_iterator argsEnd =
-      cmRemoveMatching(varArgsExpanded, cmRange(remBegin, remEnd));
+      cmRemoveMatching(varArgsExpanded, cmMakeRange(remBegin, remEnd));
   std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
-  std::string value = cmJoin(cmRange(argsBegin, argsEnd), ";");
+  std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
   this->Makefile->AddDefinition(listName, value.c_str());
   return true;
 }
@@ -421,7 +421,7 @@ bool cmListCommand
       cmRemoveDuplicates(varArgsExpanded);
   std::vector<std::string>::const_iterator argsBegin =
       varArgsExpanded.begin();
-  std::string value = cmJoin(cmRange(argsBegin, argsEnd), ";");
+  std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
 
   this->Makefile->AddDefinition(listName, value.c_str());
   return true;
@@ -509,9 +509,9 @@ bool cmListCommand::HandleRemoveAtCommand(
   std::vector<size_t>::const_iterator remBegin = removed.begin();
 
   std::vector<std::string>::const_iterator argsEnd =
-      cmRemoveIndices(varArgsExpanded, cmRange(remBegin, remEnd));
+      cmRemoveIndices(varArgsExpanded, cmMakeRange(remBegin, remEnd));
   std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
-  std::string value = cmJoin(cmRange(argsBegin, argsEnd), ";");
+  std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
 
   this->Makefile->AddDefinition(listName, value.c_str());
   return true;
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 2756cd2..bff2986 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -234,8 +234,7 @@ bool cmListFile::ParseFile(const char* filename,
       {
       cmListFileFunction project;
       project.Name = "PROJECT";
-      cmListFileArgument prj("Project", cmListFileArgument::Unquoted,
-                             filename, 0);
+      cmListFileArgument prj("Project", cmListFileArgument::Unquoted, 0);
       project.Arguments.push_back(prj);
       this->Functions.insert(this->Functions.begin(),project);
       }
@@ -252,7 +251,6 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
 {
   // Inintialize a new function call.
   this->Function = cmListFileFunction();
-  this->Function.FilePath = this->FileName;
   this->Function.Name = name;
   this->Function.Line = line;
 
@@ -375,7 +373,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
 bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
                                    cmListFileArgument::Delimiter delim)
 {
-  cmListFileArgument a(token->text, delim, this->FileName, token->line);
+  cmListFileArgument a(token->text, delim, token->line);
   this->Function.Arguments.push_back(a);
   if(this->Separation == SeparationOkay)
     {
@@ -400,50 +398,50 @@ bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
     }
 }
 
-void cmListFileBacktrace::Append(cmListFileContext const& context)
+void cmListFileBacktrace::PrintTitle(std::ostream& out) const
 {
-  this->push_back(context);
-}
-
-//----------------------------------------------------------------------------
-void cmListFileBacktrace::MakeRelative()
-{
-  if (this->Relative)
+  if (!this->Snapshot.IsValid())
     {
     return;
     }
-  for (cmListFileBacktrace::iterator i = this->begin();
-       i != this->end(); ++i)
-    {
-    i->FilePath = this->LocalGenerator->Convert(i->FilePath,
-                                                cmLocalGenerator::HOME);
-    }
-  this->Relative = true;
+  cmOutputConverter converter(this->Snapshot);
+  cmListFileContext lfc =
+      cmListFileContext::FromCommandContext(
+        this->Context, this->Snapshot.GetExecutionListFile());
+  lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
+  out << (lfc.Line ? " at " : " in ") << lfc;
 }
 
-void cmListFileBacktrace::PrintTitle(std::ostream& out)
+void cmListFileBacktrace::PrintCallStack(std::ostream& out) const
 {
-  if (this->empty())
+  if (!this->Snapshot.IsValid())
     {
     return;
     }
-  out << (this->front().Line ? " at " : " in ") << this->front();
-}
-
-void cmListFileBacktrace::PrintCallStack(std::ostream& out)
-{
-  if (size() <= 1)
+  cmState::Snapshot parent = this->Snapshot.GetCallStackParent();
+  if (!parent.IsValid() || parent.GetExecutionListFile().empty())
     {
     return;
     }
 
-  const_iterator i = this->begin() + 1;
+  cmOutputConverter converter(this->Snapshot);
+  std::string commandName = this->Snapshot.GetEntryPointCommand();
+  long commandLine = this->Snapshot.GetEntryPointLine();
+
   out << "Call Stack (most recent call first):\n";
-  while(i != this->end())
+  while(parent.IsValid())
     {
-    cmListFileContext const& lfc = *i;
+    cmListFileContext lfc;
+    lfc.Name = commandName;
+    lfc.Line = commandLine;
+
+    lfc.FilePath = converter.Convert(parent.GetExecutionListFile(),
+                                     cmOutputConverter::HOME);
     out << "  " << lfc << "\n";
-    ++i;
+
+    commandName = parent.GetEntryPointCommand();
+    commandLine = parent.GetEntryPointLine();
+    parent = parent.GetCallStackParent();
     }
 }
 
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 4a1d181..0afd7f5 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -14,7 +14,7 @@
 
 #include "cmStandardIncludes.h"
 
-class cmLocalGenerator;
+#include "cmState.h"
 
 /** \class cmListFileCache
  * \brief A class to cache list file contents.
@@ -25,6 +25,13 @@ class cmLocalGenerator;
 
 class cmMakefile;
 
+struct cmCommandContext
+{
+  std::string Name;
+  long Line;
+  cmCommandContext(): Name(), Line(0) {}
+};
+
 struct cmListFileArgument
 {
   enum Delimiter
@@ -33,12 +40,11 @@ struct cmListFileArgument
     Quoted,
     Bracket
     };
-  cmListFileArgument(): Value(), Delim(Unquoted), FilePath(0), Line(0) {}
-  cmListFileArgument(const cmListFileArgument& r):
-    Value(r.Value), Delim(r.Delim), FilePath(r.FilePath), Line(r.Line) {}
-  cmListFileArgument(const std::string& v, Delimiter d, const char* file,
-                     long line): Value(v), Delim(d),
-                                 FilePath(file), Line(line) {}
+  cmListFileArgument(): Value(), Delim(Unquoted), Line(0) {}
+  cmListFileArgument(const cmListFileArgument& r)
+    : Value(r.Value), Delim(r.Delim), Line(r.Line) {}
+  cmListFileArgument(const std::string& v, Delimiter d, long line)
+    : Value(v), Delim(d), Line(line) {}
   bool operator == (const cmListFileArgument& r) const
     {
     return (this->Value == r.Value) && (this->Delim == r.Delim);
@@ -49,7 +55,6 @@ struct cmListFileArgument
     }
   std::string Value;
   Delimiter Delim;
-  const char* FilePath;
   long Line;
 };
 
@@ -59,6 +64,16 @@ struct cmListFileContext
   std::string FilePath;
   long Line;
   cmListFileContext(): Name(), FilePath(), Line(0) {}
+
+  static cmListFileContext FromCommandContext(cmCommandContext const& lfcc,
+                                              std::string const& fileName)
+  {
+    cmListFileContext lfc;
+    lfc.FilePath = fileName;
+    lfc.Line = lfcc.Line;
+    lfc.Name = lfcc.Name;
+    return lfc;
+  }
 };
 
 std::ostream& operator<<(std::ostream&, cmListFileContext const&);
@@ -66,29 +81,25 @@ bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs);
 bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs);
 bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs);
 
-struct cmListFileFunction: public cmListFileContext
+struct cmListFileFunction: public cmCommandContext
 {
   std::vector<cmListFileArgument> Arguments;
 };
 
-class cmListFileBacktrace: private std::vector<cmListFileContext>
+class cmListFileBacktrace
 {
   public:
-    cmListFileBacktrace(cmLocalGenerator* localGen)
-      : LocalGenerator(localGen)
-      , Relative(localGen ? false : true)
+    cmListFileBacktrace(cmState::Snapshot snapshot = cmState::Snapshot(),
+                        cmCommandContext const& cc = cmCommandContext())
+      : Context(cc), Snapshot(snapshot)
     {
     }
 
-    void Append(cmListFileContext const& context);
-
-    void MakeRelative();
-
-    void PrintTitle(std::ostream& out);
-    void PrintCallStack(std::ostream& out);
+    void PrintTitle(std::ostream& out) const;
+    void PrintCallStack(std::ostream& out) const;
   private:
-    cmLocalGenerator* LocalGenerator;
-    bool Relative;
+    cmCommandContext Context;
+    cmState::Snapshot Snapshot;
 };
 
 struct cmListFile
diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h
index 4581269..445e167 100644
--- a/Source/cmLoadCommandCommand.h
+++ b/Source/cmLoadCommandCommand.h
@@ -21,7 +21,6 @@ public:
   virtual bool InitialPass(std::vector<std::string> const& args,
                            cmExecutionStatus &status);
   virtual std::string GetName() const {return "load_command";}
-  virtual bool IsDiscouraged() const { return true; }
   cmTypeMacro(cmLoadCommandCommand, cmCommand);
 };
 
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
new file mode 100644
index 0000000..5a18e2f
--- /dev/null
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -0,0 +1,39 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmLocalCommonGenerator.h"
+
+#include "cmMakefile.h"
+
+cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
+                                               cmMakefile* mf):
+  cmLocalGenerator(gg, mf)
+{
+}
+
+cmLocalCommonGenerator::~cmLocalCommonGenerator()
+{
+}
+
+void cmLocalCommonGenerator::SetConfigName()
+{
+  // Store the configuration name that will be generated.
+  if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
+    {
+    // Use the build type given by the user.
+    this->ConfigName = config;
+    }
+  else
+    {
+    // No configuration type given.
+    this->ConfigName = "";
+    }
+}
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
new file mode 100644
index 0000000..6b4b1cd
--- /dev/null
+++ b/Source/cmLocalCommonGenerator.h
@@ -0,0 +1,37 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmLocalCommonGenerator_h
+#define cmLocalCommonGenerator_h
+
+#include "cmLocalGenerator.h"
+
+class cmCommonTargetGenerator;
+
+/** \class cmLocalCommonGenerator
+ * \brief Common infrastructure for Makefile and Ninja local generators.
+ */
+class cmLocalCommonGenerator: public cmLocalGenerator
+{
+public:
+  cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
+  ~cmLocalCommonGenerator();
+
+  std::string const& GetConfigName() { return this->ConfigName; }
+
+protected:
+  void SetConfigName();
+  std::string ConfigName;
+
+  friend class cmCommonTargetGenerator;
+};
+
+#endif
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index eb6b871..3230403 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -16,6 +16,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmInstallGenerator.h"
 #include "cmInstallFilesGenerator.h"
+#include "cmGeneratorExpressionEvaluationFile.h"
 #include "cmInstallScriptGenerator.h"
 #include "cmInstallTargetGenerator.h"
 #include "cmMakefile.h"
@@ -32,8 +33,6 @@
 # include <cmsys/MD5.h>
 #endif
 
-#include <cmsys/System.h>
-
 #include <ctype.h> // for isalpha
 
 #include <assert.h>
@@ -44,106 +43,39 @@
 #endif
 
 cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg,
-                                   cmLocalGenerator* parent,
-                                   cmState::Snapshot snapshot)
-  : StateSnapshot(snapshot)
+                                   cmMakefile* makefile)
+  : cmOutputConverter(makefile->GetStateSnapshot()),
+    StateSnapshot(makefile->GetStateSnapshot())
 {
-  assert(snapshot.IsValid());
   this->GlobalGenerator = gg;
-  this->Parent = parent;
-  if (parent)
-    {
-    parent->AddChild(this);
-    }
 
-  this->Makefile = new cmMakefile(this);
+  this->Makefile = makefile;
 
-  this->LinkScriptShell = false;
-  this->UseRelativePaths = false;
-  this->Configured = false;
   this->EmitUniversalBinaryFlags = true;
   this->BackwardsCompatibility = 0;
   this->BackwardsCompatibilityFinal = false;
+
+  this->ComputeObjectMaxPath();
 }
 
 cmLocalGenerator::~cmLocalGenerator()
 {
-  delete this->Makefile;
 }
 
-bool cmLocalGenerator::IsRootMakefile() const
+void cmLocalGenerator::IssueMessage(cmake::MessageType t,
+                                    std::string const& text) const
 {
-  return !this->StateSnapshot.GetParent().IsValid();
-}
+  cmListFileContext lfc;
+  lfc.FilePath = this->StateSnapshot.GetDirectory().GetCurrentSource();
+  lfc.FilePath += "/CMakeLists.txt";
 
-//----------------------------------------------------------------------------
-class cmLocalGeneratorCurrent
-{
-  cmGlobalGenerator* GG;
-  cmLocalGenerator* LG;
-  cmState::Snapshot Snapshot;
-public:
-  cmLocalGeneratorCurrent(cmLocalGenerator* lg)
+  if(!this->GlobalGenerator->GetCMakeInstance()->GetIsInTryCompile())
     {
-    this->GG = lg->GetGlobalGenerator();
-    this->LG = this->GG->GetCurrentLocalGenerator();
-    this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot();
-    this->GG->GetCMakeInstance()->SetCurrentSnapshot(lg->GetStateSnapshot());
-    this->GG->SetCurrentLocalGenerator(lg);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-    this->GG->GetFileLockPool().PushFileScope();
-#endif
-    }
-  ~cmLocalGeneratorCurrent()
-    {
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-    this->GG->GetFileLockPool().PopFileScope();
-#endif
-    this->GG->SetCurrentLocalGenerator(this->LG);
-    this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
+    cmOutputConverter converter(this->StateSnapshot);
+    lfc.FilePath = converter.Convert(lfc.FilePath, cmLocalGenerator::HOME);
     }
-};
-
-//----------------------------------------------------------------------------
-void cmLocalGenerator::Configure()
-{
-  // Manage the global generator's current local generator.
-  cmLocalGeneratorCurrent clg(this);
-  static_cast<void>(clg);
-
-  // make sure the CMakeFiles dir is there
-  std::string filesDir = this->StateSnapshot.GetCurrentBinaryDirectory();
-  filesDir += cmake::GetCMakeFilesDirectory();
-  cmSystemTools::MakeDirectory(filesDir.c_str());
-
-  std::string currentStart = this->StateSnapshot.GetCurrentSourceDirectory();
-  currentStart += "/CMakeLists.txt";
-  assert(cmSystemTools::FileExists(currentStart.c_str(), true));
-  this->Makefile->ProcessBuildsystemFile(currentStart.c_str());
-
-  // at the end of the ReadListFile handle any old style subdirs
-  // first get all the subdirectories
-  std::vector<cmLocalGenerator *> subdirs = this->GetChildren();
-
-  // for each subdir recurse
-  std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
-  for (; sdi != subdirs.end(); ++sdi)
-    {
-    if (!(*sdi)->Configured)
-      {
-      this->Makefile->ConfigureSubDirectory(*sdi);
-      }
-    }
-
-  this->Makefile->AddCMakeDependFilesFromUser();
-
-  // Check whether relative paths should be used for optionally
-  // relative paths.
-  this->UseRelativePaths = this->Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
-
-  this->ComputeObjectMaxPath();
-
-  this->Configured = true;
+  lfc.Line = 0;
+  this->GlobalGenerator->GetCMakeInstance()->IssueMessage(t, text, lfc);
 }
 
 //----------------------------------------------------------------------------
@@ -171,7 +103,7 @@ void cmLocalGenerator::ComputeObjectMaxPath()
         w << "CMAKE_OBJECT_PATH_MAX is set to " << pmax
           << ", which is less than the minimum of 128.  "
           << "The value will be ignored.";
-        this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+        this->IssueMessage(cmake::AUTHOR_WARNING, w.str());
         }
       }
     else
@@ -180,17 +112,12 @@ void cmLocalGenerator::ComputeObjectMaxPath()
       w << "CMAKE_OBJECT_PATH_MAX is set to \"" << plen
         << "\", which fails to parse as a positive integer.  "
         << "The value will be ignored.";
-      this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+      this->IssueMessage(cmake::AUTHOR_WARNING, w.str());
       }
     }
   this->ObjectMaxPathViolations.clear();
 }
 
-void cmLocalGenerator::ConfigureFinalPass()
-{
-  this->Makefile->ConfigureFinalPass();
-}
-
 void cmLocalGenerator::TraceDependencies()
 {
   std::vector<std::string> configs;
@@ -230,7 +157,8 @@ void cmLocalGenerator::GenerateTestFiles()
   const std::string& config =
     this->Makefile->GetConfigurations(configurationTypes, false);
 
-  std::string file = this->StateSnapshot.GetCurrentBinaryDirectory();
+  std::string file =
+      this->StateSnapshot.GetDirectory().GetCurrentBinary();
   file += "/";
   file += "CTestTestfile.cmake";
 
@@ -239,9 +167,11 @@ void cmLocalGenerator::GenerateTestFiles()
 
   fout << "# CMake generated Testfile for " << std::endl
        << "# Source directory: "
-       << this->StateSnapshot.GetCurrentSourceDirectory() << std::endl
+       << this->StateSnapshot.GetDirectory().GetCurrentSource()
+       << std::endl
        << "# Build directory: "
-       << this->StateSnapshot.GetCurrentBinaryDirectory() << std::endl
+       << this->StateSnapshot.GetDirectory().GetCurrentBinary()
+       << std::endl
        << "# " << std::endl
        << "# This file includes the relevant testing commands "
        << "required for " << std::endl
@@ -261,20 +191,66 @@ void cmLocalGenerator::GenerateTestFiles()
   for(std::vector<cmTestGenerator*>::const_iterator gi = testers.begin();
       gi != testers.end(); ++gi)
     {
+    (*gi)->Compute(this);
     (*gi)->Generate(fout, config, configurationTypes);
     }
-  if (!this->Children.empty())
+  size_t i;
+  std::vector<cmState::Snapshot> children
+      = this->Makefile->GetStateSnapshot().GetChildren();
+  for(i = 0; i < children.size(); ++i)
+    {
+    // TODO: Use add_subdirectory instead?
+    fout << "subdirs(";
+    std::string outP = children[i].GetDirectory().GetCurrentBinary();
+    fout << this->Convert(outP,START_OUTPUT);
+    fout << ")" << std::endl;
+    }
+}
+
+void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config)
+{
+  std::vector<cmGeneratorExpressionEvaluationFile*> ef =
+      this->Makefile->GetEvaluationFiles();
+  for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
+      li = ef.begin(); li != ef.end(); ++li)
+    {
+    (*li)->CreateOutputFile(this, config);
+    }
+}
+
+void cmLocalGenerator::ProcessEvaluationFiles(
+    std::vector<std::string>& generatedFiles)
+{
+  std::vector<cmGeneratorExpressionEvaluationFile*> ef =
+      this->Makefile->GetEvaluationFiles();
+  for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
+      li = ef.begin();
+      li != ef.end();
+      ++li)
     {
-    size_t i;
-    for(i = 0; i < this->Children.size(); ++i)
+    (*li)->Generate(this);
+    if (cmSystemTools::GetFatalErrorOccured())
       {
-      // TODO: Use add_subdirectory instead?
-      fout << "subdirs(";
-      std::string outP =
-        this->Children[i]->GetMakefile()->GetCurrentBinaryDirectory();
-      fout << this->Convert(outP,START_OUTPUT);
-      fout << ")" << std::endl;
+      return;
       }
+    std::vector<std::string> files = (*li)->GetFiles();
+    std::sort(files.begin(), files.end());
+
+    std::vector<std::string> intersection;
+    std::set_intersection(files.begin(), files.end(),
+                          generatedFiles.begin(), generatedFiles.end(),
+                          std::back_inserter(intersection));
+    if (!intersection.empty())
+      {
+      cmSystemTools::Error("Files to be generated by multiple different "
+        "commands: ", cmWrap('"', intersection, '"', " ").c_str());
+      return;
+      }
+
+    generatedFiles.insert(generatedFiles.end(), files.begin(), files.end());
+    std::vector<std::string>::iterator newIt =
+        generatedFiles.end() - files.size();
+    std::inplace_merge(generatedFiles.begin(), newIt, generatedFiles.end());
     }
 }
 
@@ -355,7 +331,8 @@ void cmLocalGenerator::GenerateInstallRules()
     }
 
   // Create the install script file.
-  std::string file = this->StateSnapshot.GetCurrentBinaryDirectory();
+  std::string file =
+      this->StateSnapshot.GetDirectory().GetCurrentBinary();
   std::string homedir = this->GetState()->GetBinaryDirectory();
   int toplevel_install = 0;
   if (file == homedir)
@@ -368,7 +345,7 @@ void cmLocalGenerator::GenerateInstallRules()
 
   // Write the header.
   fout << "# Install script for directory: "
-       << this->StateSnapshot.GetCurrentSourceDirectory()
+       << this->StateSnapshot.GetDirectory().GetCurrentSource()
        << std::endl << std::endl;
   fout << "# Set the install prefix" << std::endl
        << "if(NOT DEFINED CMAKE_INSTALL_PREFIX)" << std::endl
@@ -432,16 +409,18 @@ void cmLocalGenerator::GenerateInstallRules()
   this->GenerateTargetInstallRules(fout, config, configurationTypes);
 
   // Include install scripts from subdirectories.
-  if(!this->Children.empty())
+  std::vector<cmState::Snapshot> children
+      = this->Makefile->GetStateSnapshot().GetChildren();
+  if(!children.empty())
     {
     fout << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n";
     fout << "  # Include the install script for each subdirectory.\n";
-    for(std::vector<cmLocalGenerator*>::const_iterator
-          ci = this->Children.begin(); ci != this->Children.end(); ++ci)
+    for(std::vector<cmState::Snapshot>::const_iterator
+          ci = children.begin(); ci != children.end(); ++ci)
       {
-      if(!(*ci)->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+      if(!ci->GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL"))
         {
-        std::string odir = (*ci)->GetMakefile()->GetCurrentBinaryDirectory();
+        std::string odir = ci->GetDirectory().GetCurrentBinary();
         cmSystemTools::ConvertToUnixSlashes(odir);
         fout << "  include(\"" <<  odir
              << "/cmake_install.cmake\")" << std::endl;
@@ -470,7 +449,7 @@ void cmLocalGenerator::GenerateInstallRules()
 }
 
 //----------------------------------------------------------------------------
-void cmLocalGenerator::GenerateTargetManifest()
+void cmLocalGenerator::ComputeTargetManifest()
 {
   // Collect the set of configuration types.
   std::vector<std::string> configNames;
@@ -498,7 +477,7 @@ void cmLocalGenerator::GenerateTargetManifest()
         ci != configNames.end(); ++ci)
       {
       const char* config = ci->c_str();
-      target.GenerateTargetManifest(config);
+      target.ComputeTargetManifest(config);
       }
     }
 }
@@ -510,226 +489,7 @@ cmState* cmLocalGenerator::GetState() const
 
 cmState::Snapshot cmLocalGenerator::GetStateSnapshot() const
 {
-  return this->StateSnapshot;
-}
-
-void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
-                                                    const std::string& lang,
-                                                    cmSourceFile& source,
-                                                    cmGeneratorTarget& target)
-{
-  std::string objectDir = cmSystemTools::GetFilenamePath(std::string(ofname));
-  objectDir = this->Convert(objectDir,START_OUTPUT,SHELL);
-  std::string objectFile = this->Convert(ofname,START_OUTPUT,SHELL);
-  std::string sourceFile =
-    this->Convert(source.GetFullPath(),START_OUTPUT,SHELL,true);
-  std::string varString = "CMAKE_";
-  varString += lang;
-  varString += "_COMPILE_OBJECT";
-  std::vector<std::string> rules;
-  rules.push_back(this->Makefile->GetRequiredDefinition(varString));
-  varString = "CMAKE_";
-  varString += lang;
-  varString += "_FLAGS";
-  std::string flags;
-  flags += this->Makefile->GetSafeDefinition(varString);
-  flags += " ";
-    {
-    std::vector<std::string> includes;
-    this->GetIncludeDirectories(includes, &target, lang);
-    flags += this->GetIncludeFlags(includes, &target, lang);
-    }
-  flags += this->Makefile->GetDefineFlags();
-
-  // Construct the command lines.
-  cmCustomCommandLines commandLines;
-  std::vector<std::string> commands;
-  cmSystemTools::ExpandList(rules, commands);
-  cmLocalGenerator::RuleVariables vars;
-  vars.Language = lang.c_str();
-  vars.Source = sourceFile.c_str();
-  vars.Object = objectFile.c_str();
-  vars.ObjectDir = objectDir.c_str();
-  vars.Flags = flags.c_str();
-  for(std::vector<std::string>::iterator i = commands.begin();
-      i != commands.end(); ++i)
-    {
-    // Expand the full command line string.
-    this->ExpandRuleVariables(*i, vars);
-
-    // Parse the string to get the custom command line.
-    cmCustomCommandLine commandLine;
-    std::vector<std::string> cmd = cmSystemTools::ParseArguments(i->c_str());
-    commandLine.insert(commandLine.end(), cmd.begin(), cmd.end());
-
-    // Store this command line.
-    commandLines.push_back(commandLine);
-    }
-
-  // Check for extra object-file dependencies.
-  std::vector<std::string> depends;
-  const char* additionalDeps = source.GetProperty("OBJECT_DEPENDS");
-  if(additionalDeps)
-    {
-    cmSystemTools::ExpandListArgument(additionalDeps, depends);
-    }
-
-  // Generate a meaningful comment for the command.
-  std::string comment = "Building ";
-  comment += lang;
-  comment += " object ";
-  comment += this->Convert(ofname, START_OUTPUT);
-
-  // Add the custom command to build the object file.
-  this->Makefile->AddCustomCommandToOutput(
-    ofname,
-    depends,
-    source.GetFullPath(),
-    commandLines,
-    comment.c_str(),
-    this->StateSnapshot.GetCurrentBinaryDirectory()
-    );
-}
-
-void cmLocalGenerator::AddBuildTargetRule(const std::string& llang,
-                                          cmGeneratorTarget& target)
-{
-  std::string objs;
-  std::vector<std::string> objVector;
-  std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
-  // Add all the sources outputs to the depends of the target
-  std::vector<cmSourceFile*> classes;
-  target.GetSourceFiles(classes, config);
-  for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
-      i != classes.end(); ++i)
-    {
-    cmSourceFile* sf = *i;
-    if(!sf->GetCustomCommand() &&
-       !sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
-       !sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
-      {
-      std::string dir_max;
-      dir_max += this->StateSnapshot.GetCurrentBinaryDirectory();
-      dir_max += "/";
-      std::string obj = this->GetObjectFileNameWithoutTarget(*sf, dir_max);
-      if(!obj.empty())
-        {
-        std::string ofname = this->StateSnapshot.GetCurrentBinaryDirectory();
-        ofname += "/";
-        ofname += obj;
-        objVector.push_back(ofname);
-        this->AddCustomCommandToCreateObject(ofname.c_str(),
-                                             llang, *(*i), target);
-        objs += this->Convert(ofname,START_OUTPUT,SHELL);
-        objs += " ";
-        }
-      }
-    }
-  std::string createRule = target.GetCreateRuleVariable(llang, config);
-  bool useWatcomQuote = this->Makefile->IsOn(createRule+"_USE_WATCOM_QUOTE");
-  std::string targetName = target.Target->GetFullName();
-  // Executable :
-  // Shared Library:
-  // Static Library:
-  // Shared Module:
-  std::string linkLibs; // should be set
-  std::string frameworkPath;
-  std::string linkPath;
-  std::string flags; // should be set
-  std::string linkFlags; // should be set
-  this->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags,
-                       &target, useWatcomQuote);
-  linkLibs = frameworkPath + linkPath + linkLibs;
-  cmLocalGenerator::RuleVariables vars;
-  vars.Language = llang.c_str();
-  vars.Objects = objs.c_str();
-  vars.ObjectDir = ".";
-  vars.Target = targetName.c_str();
-  vars.LinkLibraries = linkLibs.c_str();
-  vars.Flags = flags.c_str();
-  vars.LinkFlags = linkFlags.c_str();
-
-  std::string langFlags;
-  this->AddLanguageFlags(langFlags, llang, "");
-  this->AddArchitectureFlags(langFlags, &target, llang, "");
-  vars.LanguageCompileFlags = langFlags.c_str();
-
-  cmCustomCommandLines commandLines;
-  std::vector<std::string> rules;
-  rules.push_back(this->Makefile->GetRequiredDefinition(createRule));
-  std::vector<std::string> commands;
-  cmSystemTools::ExpandList(rules, commands);
-  for(std::vector<std::string>::iterator i = commands.begin();
-      i != commands.end(); ++i)
-    {
-    // Expand the full command line string.
-    this->ExpandRuleVariables(*i, vars);
-    // Parse the string to get the custom command line.
-    cmCustomCommandLine commandLine;
-    std::vector<std::string> cmd = cmSystemTools::ParseArguments(i->c_str());
-    commandLine.insert(commandLine.end(), cmd.begin(), cmd.end());
-
-    // Store this command line.
-    commandLines.push_back(commandLine);
-    }
-  std::string targetFullPath = target.Target->GetFullPath();
-  // Generate a meaningful comment for the command.
-  std::string comment = "Linking ";
-  comment += llang;
-  comment += " target ";
-  comment += this->Convert(targetFullPath, START_OUTPUT);
-  this->Makefile->AddCustomCommandToOutput(
-    targetFullPath,
-    objVector,
-    "",
-    commandLines,
-    comment.c_str(),
-    this->StateSnapshot.GetCurrentBinaryDirectory()
-    );
-  this->Makefile->GetSource(targetFullPath);
-  target.Target->AddSource(targetFullPath);
-}
-
-
-void cmLocalGenerator
-::CreateCustomTargetsAndCommands(std::set<std::string> const& lang)
-{
-  cmGeneratorTargetsType tgts = this->Makefile->GetGeneratorTargets();
-  for(cmGeneratorTargetsType::iterator l = tgts.begin();
-      l != tgts.end(); l++)
-    {
-    if (l->first->IsImported())
-      {
-      continue;
-      }
-    cmGeneratorTarget& target = *l->second;
-    switch(target.GetType())
-      {
-      case cmTarget::STATIC_LIBRARY:
-      case cmTarget::SHARED_LIBRARY:
-      case cmTarget::MODULE_LIBRARY:
-      case cmTarget::EXECUTABLE:
-        {
-        std::string llang = target.Target->GetLinkerLanguage();
-        if(llang.empty())
-          {
-          cmSystemTools::Error
-            ("CMake can not determine linker language for target: ",
-             target.Target->GetName().c_str());
-          return;
-          }
-        // if the language is not in the set lang then create custom
-        // commands to build the target
-        if(lang.count(llang) == 0)
-          {
-          this->AddBuildTargetRule(llang, target);
-          }
-        }
-        break;
-      default:
-        break;
-      }
-    }
+  return this->Makefile->GetStateSnapshot();
 }
 
 // List of variables that are replaced when
@@ -767,6 +527,13 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
       return replaceValues.LinkFlags;
       }
     }
+  if(replaceValues.Manifests)
+    {
+    if(variable == "MANIFESTS")
+      {
+      return replaceValues.Manifests;
+      }
+    }
   if(replaceValues.Flags)
     {
     if(variable == "FLAGS")
@@ -835,6 +602,10 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
     {
     return replaceValues.Defines;
     }
+  if(replaceValues.Includes && variable == "INCLUDES")
+    {
+    return replaceValues.Includes;
+    }
   if(replaceValues.TargetPDB )
     {
     if(variable == "TARGET_PDB")
@@ -1169,56 +940,6 @@ void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target,
 
 //----------------------------------------------------------------------------
 std::string
-cmLocalGenerator::ConvertToOutputForExistingCommon(const std::string& remote,
-                                                   std::string const& result,
-                                                   OutputFormat format)
-{
-  // If this is a windows shell, the result has a space, and the path
-  // already exists, we can use a short-path to reference it without a
-  // space.
-  if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos &&
-     cmSystemTools::FileExists(remote.c_str()))
-    {
-    std::string tmp;
-    if(cmSystemTools::GetShortPath(remote, tmp))
-      {
-      return this->Convert(tmp, NONE, format, true);
-      }
-    }
-
-  // Otherwise, leave it unchanged.
-  return result;
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToOutputForExisting(const std::string& remote,
-                                             RelativeRoot local,
-                                             OutputFormat format)
-{
-  // Perform standard conversion.
-  std::string result = this->Convert(remote, local, format, true);
-
-  // Consider short-path.
-  return this->ConvertToOutputForExistingCommon(remote, result, format);
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote,
-                                             const std::string& local,
-                                             OutputFormat format)
-{
-  // Perform standard conversion.
-  std::string result = this->Convert(remote, local, format, true);
-
-  // Consider short-path.
-  const char* remotePath = this->GetRelativeRootPath(remote);
-  return this->ConvertToOutputForExistingCommon(remotePath, result, format);
-}
-
-//----------------------------------------------------------------------------
-std::string
 cmLocalGenerator::ConvertToIncludeReference(std::string const& path,
                                             OutputFormat format,
                                             bool forceFullPaths)
@@ -1316,8 +1037,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
           {
           includeFlags << fwSearchFlag;
           }
-        includeFlags << this->Convert(frameworkDir, START_OUTPUT,
-                                      shellFormat, true)
+        includeFlags << this->ConvertToOutputFormat(frameworkDir, shellFormat)
           << " ";
         }
       continue;
@@ -1365,7 +1085,8 @@ void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines,
                                              const std::string& lang)
 {
   std::vector<std::string> targetDefines;
-  target->GetCompileDefinitions(targetDefines, config, lang);
+  cmGeneratorTarget* gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
+  gtgt->GetCompileDefinitions(targetDefines, config, lang);
   this->AppendDefines(defines, targetDefines);
 }
 
@@ -1376,6 +1097,10 @@ void cmLocalGenerator::AddCompileOptions(
   )
 {
   std::string langFlagRegexVar = std::string("CMAKE_")+lang+"_FLAG_REGEX";
+
+  cmGeneratorTarget* gtgt =
+      this->GlobalGenerator->GetGeneratorTarget(target);
+
   if(const char* langFlagRegexStr =
      this->Makefile->GetDefinition(langFlagRegexVar))
     {
@@ -1386,7 +1111,7 @@ void cmLocalGenerator::AddCompileOptions(
       {
       cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
       }
-    target->GetCompileOptions(opts, config, lang);
+    gtgt->GetCompileOptions(opts, config, lang);
     for(std::vector<std::string>::const_iterator i = opts.begin();
         i != opts.end(); ++i)
       {
@@ -1407,7 +1132,7 @@ void cmLocalGenerator::AddCompileOptions(
       this->AppendFlags(flags, targetFlags);
       }
     std::vector<std::string> opts;
-    target->GetCompileOptions(opts, config, lang);
+    gtgt->GetCompileOptions(opts, config, lang);
     for(std::vector<std::string>::const_iterator i = opts.begin();
         i != opts.end(); ++i)
       {
@@ -1416,7 +1141,7 @@ void cmLocalGenerator::AddCompileOptions(
       }
     }
   std::vector<std::string> features;
-  target->GetCompileFeatures(features, config);
+  gtgt->GetCompileFeatures(features, config);
   for(std::vector<std::string>::const_iterator it = features.begin();
       it != features.end(); ++it)
     {
@@ -1446,7 +1171,7 @@ void cmLocalGenerator::AddCompileOptions(
         "higher \"" << it->first << "_STANDARD\" \"" << standard << "\".  "
         "This is not permitted. The COMPILE_FEATURES may not both depend on "
         "and be depended on by the link implementation." << std::endl;
-      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+      this->IssueMessage(cmake::FATAL_ERROR, e.str());
       return;
       }
     }
@@ -1459,7 +1184,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
                                              const std::string& lang,
                                              const std::string& config,
                                              bool stripImplicitInclDirs
-                                            )
+                                            ) const
 {
   // Need to decide whether to automatically include the source and
   // binary directories at the beginning of the include path.
@@ -1485,20 +1210,20 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
   // Store the automatic include paths.
   if(includeBinaryDir)
     {
-    if(emitted.find(
-        this->StateSnapshot.GetCurrentBinaryDirectory()) == emitted.end())
+    std::string binDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
+    if(emitted.find(binDir) == emitted.end())
       {
-      dirs.push_back(this->StateSnapshot.GetCurrentBinaryDirectory());
-      emitted.insert(this->StateSnapshot.GetCurrentBinaryDirectory());
+      dirs.push_back(binDir);
+      emitted.insert(binDir);
       }
     }
   if(includeSourceDir)
     {
-    if(emitted.find(
-        this->StateSnapshot.GetCurrentSourceDirectory()) == emitted.end())
+    std::string srcDir = this->StateSnapshot.GetDirectory().GetCurrentSource();
+    if(emitted.find(srcDir) == emitted.end())
       {
-      dirs.push_back(this->StateSnapshot.GetCurrentSourceDirectory());
-      emitted.insert(this->StateSnapshot.GetCurrentSourceDirectory());
+      dirs.push_back(srcDir);
+      emitted.insert(srcDir);
       }
     }
 
@@ -1684,7 +1409,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
         linkFlags += this->Makefile->GetSafeDefinition(build);
         linkFlags += " ";
         }
-      std::string linkLanguage = target->Target->GetLinkerLanguage(buildType);
+      std::string linkLanguage = target->GetLinkerLanguage(buildType);
       if(linkLanguage.empty())
         {
         cmSystemTools::Error
@@ -1799,7 +1524,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
   bool escapeAllowMakeVars = !forResponseFile;
   std::ostringstream fout;
   std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
-  cmComputeLinkInformation* pcli = tgt.Target->GetLinkInformation(config);
+  cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config);
   if(!pcli)
     {
     return;
@@ -1817,13 +1542,49 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
     this->Makefile->GetSafeDefinition("CMAKE_LIBRARY_PATH_TERMINATOR");
 
   // Flags to link an executable to shared libraries.
-  std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
-  linkFlagsVar += linkLanguage;
-  linkFlagsVar += "_FLAGS";
-  if( tgt.GetType() == cmTarget::EXECUTABLE )
+  if (tgt.GetType() == cmTarget::EXECUTABLE &&
+      this->StateSnapshot.GetState()->
+        GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS"))
     {
-    linkLibs = this->Makefile->GetSafeDefinition(linkFlagsVar);
-    linkLibs += " ";
+    bool add_shlib_flags = false;
+    switch(tgt.Target->GetPolicyStatusCMP0065())
+      {
+      case cmPolicies::WARN:
+        if(!tgt.GetPropertyAsBool("ENABLE_EXPORTS") &&
+           this->Makefile->PolicyOptionalWarningEnabled(
+             "CMAKE_POLICY_WARNING_CMP0065"))
+          {
+          std::ostringstream w;
+          w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0065) << "\n"
+            "For compatibility with older versions of CMake, "
+            "additional flags may be added to export symbols on all "
+            "executables regardless of thier ENABLE_EXPORTS property.";
+          this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+          }
+      case cmPolicies::OLD:
+        // OLD behavior is to always add the flags
+        add_shlib_flags = true;
+        break;
+      case cmPolicies::REQUIRED_IF_USED:
+      case cmPolicies::REQUIRED_ALWAYS:
+        this->Makefile->IssueMessage(
+          cmake::FATAL_ERROR,
+          cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0065)
+          );
+      case cmPolicies::NEW:
+        // NEW behavior is to only add the flags if ENABLE_EXPORTS is on
+        add_shlib_flags = tgt.GetPropertyAsBool("ENABLE_EXPORTS");
+        break;
+      }
+
+    if(add_shlib_flags)
+      {
+      std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
+      linkFlagsVar += linkLanguage;
+      linkFlagsVar += "_FLAGS";
+      linkLibs = this->Makefile->GetSafeDefinition(linkFlagsVar);
+      linkLibs += " ";
+      }
     }
 
   // Append the framework search path flags.
@@ -2030,7 +1791,8 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
     }
 
   // Look for a CMake target with the given name.
-  if(cmTarget* target = this->Makefile->FindTargetToUse(name))
+  if(cmGeneratorTarget* target =
+     this->Makefile->FindGeneratorTargetToUse(name))
     {
     // make sure it is not just a coincidence that the target name
     // found is part of the inName
@@ -2099,7 +1861,7 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
 
   // Treat the name as relative to the source directory in which it
   // was given.
-  dep = this->StateSnapshot.GetCurrentSourceDirectory();
+  dep = this->StateSnapshot.GetDirectory().GetCurrentSource();
   dep += "/";
   dep += inName;
   return true;
@@ -2170,7 +1932,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget const* target,
            "dialect \"" << lang << standardProp << "\" "
         << (ext ? "(with compiler extensions)" : "") << ", but CMake "
            "does not know the compile flags to use to enable it.";
-      this->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
+      this->IssueMessage(cmake::FATAL_ERROR, e.str());
       }
     else
       {
@@ -2214,7 +1976,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget const* target,
     std::string e =
       "CMAKE_" + lang + "_STANDARD_DEFAULT is set to invalid value '" +
       std::string(defaultStd) + "'";
-    this->Makefile->IssueMessage(cmake::INTERNAL_ERROR, e);
+    this->IssueMessage(cmake::INTERNAL_ERROR, e);
     return;
     }
 
@@ -2389,7 +2151,9 @@ void cmLocalGenerator::AddCMP0018Flags(std::string &flags,
       return;
       }
 
-    if (target->GetLinkInterfaceDependentBoolProperty(
+    cmGeneratorTarget* gtgt =
+        this->GlobalGenerator->GetGeneratorTarget(target);
+    if (gtgt->GetLinkInterfaceDependentBoolProperty(
                                                 "POSITION_INDEPENDENT_CODE",
                                                 config))
       {
@@ -2430,7 +2194,7 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared,
             << flagsVar << " was removed.\n"
             << cmPolicies::GetPolicyWarning(cmPolicies::CMP0018);
 
-          this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+          this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
           // fall through to OLD behaviour
         }
         case cmPolicies::OLD:
@@ -2644,6 +2408,30 @@ void cmLocalGenerator::AppendFeatureOptions(
 }
 
 //----------------------------------------------------------------------------
+const char* cmLocalGenerator::GetFeature(const std::string& feature,
+                                         const std::string& config)
+{
+  std::string featureName = feature;
+  // TODO: Define accumulation policy for features (prepend, append, replace).
+  // Currently we always replace.
+  if(!config.empty())
+    {
+    featureName += "_";
+    featureName += cmSystemTools::UpperCase(config);
+    }
+  cmState::Snapshot snp = this->StateSnapshot;
+  while(snp.IsValid())
+    {
+    if(const char* value = snp.GetDirectory().GetProperty(featureName))
+      {
+      return value;
+      }
+    snp = snp.GetBuildsystemDirectoryParent();
+    }
+  return 0;
+}
+
+//----------------------------------------------------------------------------
 std::string
 cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg,
                                    const char* default_comment)
@@ -2675,250 +2463,18 @@ cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg,
 }
 
 //----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToOptionallyRelativeOutputPath(
-                                                    const std::string& remote)
-{
-  return this->Convert(remote, START_OUTPUT, SHELL, true);
-}
-
-//----------------------------------------------------------------------------
-const char* cmLocalGenerator::GetRelativeRootPath(RelativeRoot relroot)
-{
-  switch (relroot)
-    {
-    case HOME:         return this->GetState()->GetSourceDirectory();
-    case START:        return this->StateSnapshot.GetCurrentSourceDirectory();
-    case HOME_OUTPUT:  return this->GetState()->GetBinaryDirectory();
-    case START_OUTPUT: return this->StateSnapshot.GetCurrentBinaryDirectory();
-    default: break;
-    }
-  return 0;
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::Convert(const std::string& source,
-                                      RelativeRoot relative,
-                                      OutputFormat output,
-                                      bool optional)
-{
-  // Convert the path to a relative path.
-  std::string result = source;
-
-  if (!optional || this->UseRelativePaths)
-    {
-    switch (relative)
-      {
-      case HOME:
-        //result = cmSystemTools::CollapseFullPath(result.c_str());
-        result = this->ConvertToRelativePath(
-            this->GetState()->GetSourceDirectoryComponents(), result);
-        break;
-      case START:
-        //result = cmSystemTools::CollapseFullPath(result.c_str());
-        result = this->ConvertToRelativePath(
-            this->StateSnapshot.GetCurrentSourceDirectoryComponents(), result);
-        break;
-      case HOME_OUTPUT:
-        //result = cmSystemTools::CollapseFullPath(result.c_str());
-        result = this->ConvertToRelativePath(
-            this->GetState()->GetBinaryDirectoryComponents(), result);
-        break;
-      case START_OUTPUT:
-        //result = cmSystemTools::CollapseFullPath(result.c_str());
-        result = this->ConvertToRelativePath(
-            this->StateSnapshot.GetCurrentBinaryDirectoryComponents(), result);
-        break;
-      case FULL:
-        result = cmSystemTools::CollapseFullPath(result);
-        break;
-      case NONE:
-        break;
-      }
-    }
-  return this->ConvertToOutputFormat(result, output);
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::ConvertToOutputFormat(const std::string& source,
-                                                    OutputFormat output)
-{
-  std::string result = source;
-  // Convert it to an output path.
-  if (output == MAKERULE)
-    {
-    result = cmSystemTools::ConvertToOutputPath(result.c_str());
-    }
-  else if(output == SHELL || output == WATCOMQUOTE)
-    {
-        // For the MSYS shell convert drive letters to posix paths, so
-    // that c:/some/path becomes /c/some/path.  This is needed to
-    // avoid problems with the shell path translation.
-    if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell)
-      {
-      if(result.size() > 2 && result[1] == ':')
-        {
-        result[1] = result[0];
-        result[0] = '/';
-        }
-      }
-    if(this->GetState()->UseWindowsShell())
-      {
-      std::replace(result.begin(), result.end(), '/', '\\');
-      }
-    result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
-    }
-  else if(output == RESPONSE)
-    {
-    result = this->EscapeForShell(result, false, false, false);
-    }
-  return result;
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::Convert(RelativeRoot remote,
-                                      const std::string& local,
-                                      OutputFormat output,
-                                      bool optional)
-{
-  const char* remotePath = this->GetRelativeRootPath(remote);
-
-  // The relative root must have a path (i.e. not FULL or NONE)
-  assert(remotePath != 0);
-
-  if(!local.empty() && (!optional || this->UseRelativePaths))
-    {
-    std::vector<std::string> components;
-    cmSystemTools::SplitPath(local, components);
-    std::string result = this->ConvertToRelativePath(components, remotePath);
-    return this->ConvertToOutputFormat(result, output);
-    }
-  else
-    {
-    return this->ConvertToOutputFormat(remotePath, output);
-    }
-}
-
-//----------------------------------------------------------------------------
-static bool cmLocalGeneratorNotAbove(const char* a, const char* b)
-{
-  return (cmSystemTools::ComparePath(a, b) ||
-          cmSystemTools::IsSubDirectory(a, b));
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local,
-                                        const std::string& in_remote,
-                                        bool force)
-{
-  // The path should never be quoted.
-  assert(in_remote[0] != '\"');
-
-  // The local path should never have a trailing slash.
-  assert(!local.empty() && !(local[local.size()-1] == ""));
-
-  // If the path is already relative then just return the path.
-  if(!cmSystemTools::FileIsFullPath(in_remote.c_str()))
-    {
-    return in_remote;
-    }
-
-  if(!force)
-    {
-    // Skip conversion if the path and local are not both in the source
-    // or both in the binary tree.
-    std::string local_path = cmSystemTools::JoinPath(local);
-    if(!((cmLocalGeneratorNotAbove(local_path.c_str(),
-              this->StateSnapshot.GetRelativePathTopBinary()) &&
-          cmLocalGeneratorNotAbove(in_remote.c_str(),
-              this->StateSnapshot.GetRelativePathTopBinary())) ||
-         (cmLocalGeneratorNotAbove(local_path.c_str(),
-              this->StateSnapshot.GetRelativePathTopSource()) &&
-          cmLocalGeneratorNotAbove(in_remote.c_str(),
-              this->StateSnapshot.GetRelativePathTopSource()))))
-      {
-      return in_remote;
-      }
-    }
-
-  // Identify the longest shared path component between the remote
-  // path and the local path.
-  std::vector<std::string> remote;
-  cmSystemTools::SplitPath(in_remote, remote);
-  unsigned int common=0;
-  while(common < remote.size() &&
-        common < local.size() &&
-        cmSystemTools::ComparePath(remote[common],
-                                   local[common]))
-    {
-    ++common;
-    }
-
-  // If no part of the path is in common then return the full path.
-  if(common == 0)
-    {
-    return in_remote;
-    }
-
-  // If the entire path is in common then just return a ".".
-  if(common == remote.size() &&
-     common == local.size())
-    {
-    return ".";
-    }
-
-  // If the entire path is in common except for a trailing slash then
-  // just return a "./".
-  if(common+1 == remote.size() &&
-     remote[common].empty() &&
-     common == local.size())
-    {
-    return "./";
-    }
-
-  // Construct the relative path.
-  std::string relative;
-
-  // First add enough ../ to get up to the level of the shared portion
-  // of the path.  Leave off the trailing slash.  Note that the last
-  // component of local will never be empty because local should never
-  // have a trailing slash.
-  for(unsigned int i=common; i < local.size(); ++i)
-    {
-    relative += "..";
-    if(i < local.size()-1)
-      {
-      relative += "/";
-      }
-    }
-
-  // Now add the portion of the destination path that is not included
-  // in the shared portion of the path.  Add a slash the first time
-  // only if there was already something in the path.  If there was a
-  // trailing slash in the input then the last iteration of the loop
-  // will add a slash followed by an empty string which will preserve
-  // the trailing slash in the output.
-
-  if(!relative.empty() && !remote.empty())
-    {
-    relative += "/";
-    }
-  relative += cmJoin(cmRange(remote).advance(common), "/");
-
-  // Finally return the path.
-  return relative;
-}
-
-//----------------------------------------------------------------------------
 class cmInstallTargetGeneratorLocal: public cmInstallTargetGenerator
 {
 public:
-  cmInstallTargetGeneratorLocal(cmTarget& t, const char* dest, bool implib):
+  cmInstallTargetGeneratorLocal(cmLocalGenerator* lg, std::string const& t,
+                                const char* dest, bool implib):
     cmInstallTargetGenerator(
       t, dest, implib, "", std::vector<std::string>(), "Unspecified",
-      cmInstallGenerator::SelectMessageLevel(t.GetMakefile()),
-      false) {}
+      cmInstallGenerator::SelectMessageLevel(lg->GetMakefile()),
+      false)
+  {
+    this->Compute(lg);
+  }
 };
 
 //----------------------------------------------------------------------------
@@ -2967,7 +2523,7 @@ cmLocalGenerator
           {
           // Use a target install generator.
           cmInstallTargetGeneratorLocal
-            g(l->second, destination.c_str(), false);
+            g(this, l->first, destination.c_str(), false);
           g.Generate(os, config, configurationTypes);
           }
           break;
@@ -2978,18 +2534,18 @@ cmLocalGenerator
           // to the normal destination and the DLL to the runtime
           // destination.
           cmInstallTargetGeneratorLocal
-            g1(l->second, destination.c_str(), true);
+            g1(this, l->first, destination.c_str(), true);
           g1.Generate(os, config, configurationTypes);
           // We also skip over the leading slash given by the user.
           destination = l->second.GetRuntimeInstallPath().substr(1);
           cmSystemTools::ConvertToUnixSlashes(destination);
           cmInstallTargetGeneratorLocal
-            g2(l->second, destination.c_str(), false);
+            g2(this, l->first, destination.c_str(), false);
           g2.Generate(os, config, configurationTypes);
 #else
           // Use a target install generator.
           cmInstallTargetGeneratorLocal
-            g(l->second, destination.c_str(), false);
+            g(this, l->first, destination.c_str(), false);
           g.Generate(os, config, configurationTypes);
 #endif
           }
@@ -3151,7 +2707,7 @@ cmLocalGenerator
           << "  " << ssin << "\n"
           << "cannot be safely placed under this directory.  "
           << "The build may not work correctly.";
-        this->Makefile->IssueMessage(cmake::WARNING, m.str());
+        this->IssueMessage(cmake::WARNING, m.str());
         }
       }
 #else
@@ -3195,11 +2751,6 @@ bool cmLocalGenerator::IsNMake() const
   return this->GetState()->UseNMake();
 }
 
-void cmLocalGenerator::SetConfiguredCMP0014(bool configured)
-{
-  this->Configured = configured;
-}
-
 //----------------------------------------------------------------------------
 std::string
 cmLocalGenerator
@@ -3308,150 +2859,6 @@ cmLocalGenerator
 }
 
 //----------------------------------------------------------------------------
-static bool cmLocalGeneratorIsShellOperator(const std::string& str)
-{
-  static std::set<std::string> shellOperators;
-  if(shellOperators.empty())
-    {
-    shellOperators.insert("<");
-    shellOperators.insert(">");
-    shellOperators.insert("<<");
-    shellOperators.insert(">>");
-    shellOperators.insert("|");
-    shellOperators.insert("||");
-    shellOperators.insert("&&");
-    shellOperators.insert("&>");
-    shellOperators.insert("1>");
-    shellOperators.insert("2>");
-    shellOperators.insert("2>&1");
-    shellOperators.insert("1>&2");
-    }
-  return shellOperators.count(str) > 0;
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::EscapeForShell(const std::string& str,
-                                             bool makeVars,
-                                             bool forEcho,
-                                             bool useWatcomQuote)
-{
-  // Do not escape shell operators.
-  if(cmLocalGeneratorIsShellOperator(str))
-    {
-    return str;
-    }
-
-  // Compute the flags for the target shell environment.
-  int flags = 0;
-  if(this->GetState()->UseWindowsVSIDE())
-    {
-    flags |= cmsysSystem_Shell_Flag_VSIDE;
-    }
-  else if(!this->LinkScriptShell)
-    {
-    flags |= cmsysSystem_Shell_Flag_Make;
-    }
-  if(makeVars)
-    {
-    flags |= cmsysSystem_Shell_Flag_AllowMakeVariables;
-    }
-  if(forEcho)
-    {
-    flags |= cmsysSystem_Shell_Flag_EchoWindows;
-    }
-  if(useWatcomQuote)
-    {
-    flags |= cmsysSystem_Shell_Flag_WatcomQuote;
-    }
-  if(this->GetState()->UseWatcomWMake())
-    {
-    flags |= cmsysSystem_Shell_Flag_WatcomWMake;
-    }
-  if(this->GetState()->UseMinGWMake())
-    {
-    flags |= cmsysSystem_Shell_Flag_MinGWMake;
-    }
-  if(this->GetState()->UseNMake())
-    {
-    flags |= cmsysSystem_Shell_Flag_NMake;
-    }
-
-  // Compute the buffer size needed.
-  int size = (this->GetState()->UseWindowsShell() ?
-              cmsysSystem_Shell_GetArgumentSizeForWindows(str.c_str(), flags) :
-              cmsysSystem_Shell_GetArgumentSizeForUnix(str.c_str(), flags));
-
-  // Compute the shell argument itself.
-  std::vector<char> arg(size);
-  if(this->GetState()->UseWindowsShell())
-    {
-    cmsysSystem_Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags);
-    }
-  else
-    {
-    cmsysSystem_Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags);
-    }
-  return std::string(&arg[0]);
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::EscapeForCMake(const std::string& str)
-{
-  // Always double-quote the argument to take care of most escapes.
-  std::string result = "\"";
-  for(const char* c = str.c_str(); *c; ++c)
-    {
-    if(*c == '"')
-      {
-      // Escape the double quote to avoid ending the argument.
-      result += "\\\"";
-      }
-    else if(*c == '$')
-      {
-      // Escape the dollar to avoid expanding variables.
-      result += "\\$";
-      }
-    else if(*c == '\\')
-      {
-      // Escape the backslash to avoid other escapes.
-      result += "\\\\";
-      }
-    else
-      {
-      // Other characters will be parsed correctly.
-      result += *c;
-      }
-    }
-  result += "\"";
-  return result;
-}
-
-//----------------------------------------------------------------------------
-cmLocalGenerator::FortranFormat
-cmLocalGenerator::GetFortranFormat(const char* value)
-{
-  FortranFormat format = FortranFormatNone;
-  if(value && *value)
-    {
-    std::vector<std::string> fmt;
-    cmSystemTools::ExpandListArgument(value, fmt);
-    for(std::vector<std::string>::iterator fi = fmt.begin();
-        fi != fmt.end(); ++fi)
-      {
-      if(*fi == "FIXED")
-        {
-        format = FortranFormatFixed;
-        }
-      if(*fi == "FREE")
-        {
-        format = FortranFormatFree;
-        }
-      }
-    }
-  return format;
-}
-
-//----------------------------------------------------------------------------
 std::string
 cmLocalGenerator::GetTargetDirectory(cmTarget const&) const
 {
@@ -3481,7 +2888,7 @@ cmIML_INT_uint64_t cmLocalGenerator::GetBackwardsCompatibility()
         }
       }
     this->BackwardsCompatibility = CMake_VERSION_ENCODE(major, minor, patch);
-    this->BackwardsCompatibilityFinal = this->Configured;
+    this->BackwardsCompatibilityFinal = true;
     }
 
   return this->BackwardsCompatibility;
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 32b17f5..6ea414a 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -14,6 +14,8 @@
 
 #include "cmStandardIncludes.h"
 #include "cmState.h"
+#include "cmake.h"
+#include "cmOutputConverter.h"
 
 class cmMakefile;
 class cmGlobalGenerator;
@@ -31,26 +33,18 @@ class cmCustomCommandGenerator;
  * platforms. This class should never be constructed directly. A
  * GlobalGenerator will create it and invoke the appropriate commands on it.
  */
-class cmLocalGenerator
+class cmLocalGenerator : public cmOutputConverter
 {
 public:
-  cmLocalGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent,
-                   cmState::Snapshot snapshot);
+  cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
   virtual ~cmLocalGenerator();
 
-  /// @return whether we are processing the top CMakeLists.txt file.
-  bool IsRootMakefile() const;
-
   /**
    * Generate the makefile for this directory.
    */
   virtual void Generate() {}
 
-  /**
-   * Process the CMakeLists files for this directory to fill in the
-   * Makefile ivar
-   */
-  virtual void Configure();
+  virtual void ComputeHomeRelativeOutputPath() {}
 
   /**
    * Calls TraceVSDependencies() on all targets of this generator.
@@ -60,11 +54,6 @@ public:
   virtual void AddHelperCommands() {}
 
   /**
-   * Perform any final calculations prior to generation
-   */
-  void ConfigureFinalPass();
-
-  /**
    * Generate the install rules files in this directory.
    */
   void GenerateInstallRules();
@@ -77,7 +66,7 @@ public:
   /**
    * Generate a manifest of target files that will be built.
    */
-  void GenerateTargetManifest();
+  void ComputeTargetManifest();
 
   ///! Get the makefile for this generator
   cmMakefile *GetMakefile() {
@@ -96,52 +85,6 @@ public:
   cmState* GetState() const;
   cmState::Snapshot GetStateSnapshot() const;
 
-  /**
-   * Convert something to something else. This is a centralized conversion
-   * routine used by the generators to handle relative paths and the like.
-   * The flags determine what is actually done.
-   *
-   * relative: treat the argument as a directory and convert it to make it
-   * relative or full or unchanged. If relative (HOME, START etc) then that
-   * specifies what it should be relative to.
-   *
-   * output: make the result suitable for output to a...
-   *
-   * optional: should any relative path operation be controlled by the rel
-   * path setting
-   */
-  enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT };
-  enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE };
-  std::string ConvertToOutputFormat(const std::string& source,
-                                    OutputFormat output);
-  std::string Convert(const std::string& remote, RelativeRoot local,
-                      OutputFormat output = UNCHANGED,
-                      bool optional = false);
-  std::string Convert(RelativeRoot remote, const std::string& local,
-                      OutputFormat output = UNCHANGED,
-                      bool optional = false);
-
-  /**
-    * Get path for the specified relative root.
-    */
-  const char* GetRelativeRootPath(RelativeRoot relroot);
-
-  /**
-   * Convert the given path to an output path that is optionally
-   * relative based on the cache option CMAKE_USE_RELATIVE_PATHS.  The
-   * remote path must use forward slashes and not already be escaped
-   * or quoted.
-   */
-  std::string ConvertToOptionallyRelativeOutputPath(const std::string& remote);
-
-  ///! set/get the parent generator
-  cmLocalGenerator* GetParent() const {return this->Parent;}
-
-  ///! set/get the children
-  void AddChild(cmLocalGenerator* g) { this->Children.push_back(g); }
-  std::vector<cmLocalGenerator*>& GetChildren() { return this->Children; }
-
-
   void AddArchitectureFlags(std::string& flags,
                             cmGeneratorTarget const* target,
                             const std::string&lang, const std::string& config);
@@ -194,6 +137,9 @@ public:
   void AppendFeatureOptions(std::string& flags, const std::string& lang,
                             const char* feature);
 
+  const char* GetFeature(const std::string& feature,
+                         const std::string& config);
+
   /** \brief Get absolute path to dependency \a name
    *
    * Translate a dependency as given in CMake code to the name to
@@ -209,17 +155,6 @@ public:
   bool GetRealDependency(const std::string& name, const std::string& config,
                          std::string& dep);
 
-  ///! for existing files convert to output path and short path if spaces
-  std::string ConvertToOutputForExisting(const std::string& remote,
-                                         RelativeRoot local = START_OUTPUT,
-                                         OutputFormat format = SHELL);
-
-  /** For existing path identified by RelativeRoot convert to output
-      path and short path if spaces.  */
-  std::string ConvertToOutputForExisting(RelativeRoot remote,
-                                         const std::string& local = "",
-                                         OutputFormat format = SHELL);
-
   virtual std::string ConvertToIncludeReference(std::string const& path,
                                                 OutputFormat format = SHELL,
                                                 bool forceFullPaths = false);
@@ -239,7 +174,7 @@ public:
                              cmGeneratorTarget* target,
                              const std::string& lang = "C",
                              const std::string& config = "",
-                             bool stripImplicitInclDirs = true);
+                             bool stripImplicitInclDirs = true) const;
   void AddCompileOptions(std::string& flags, cmTarget* target,
                          const std::string& lang, const std::string& config);
   void AddCompileDefinitions(std::set<std::string>& defines,
@@ -284,47 +219,15 @@ public:
     const char* TargetSOName;
     const char* TargetInstallNameDir;
     const char* LinkFlags;
+    const char* Manifests;
     const char* LanguageCompileFlags;
     const char* Defines;
+    const char* Includes;
     const char* RuleLauncher;
     const char* DependencyFile;
     const char* FilterPrefix;
   };
 
-  /** Set whether to treat conversions to SHELL as a link script shell.  */
-  void SetLinkScriptShell(bool b) { this->LinkScriptShell = b; }
-
-  /** Escape the given string to be used as a command line argument in
-      the native build system shell.  Optionally allow the build
-      system to replace make variable references.  Optionally adjust
-      escapes for the special case of passing to the native echo
-      command.  */
-  std::string EscapeForShell(const std::string& str, bool makeVars = false,
-                             bool forEcho = false,
-                             bool useWatcomQuote = false);
-
-  /** Escape the given string as an argument in a CMake script.  */
-  static std::string EscapeForCMake(const std::string& str);
-
-  enum FortranFormat
-    {
-    FortranFormatNone,
-    FortranFormatFixed,
-    FortranFormatFree
-    };
-  FortranFormat GetFortranFormat(const char* value);
-
-  /**
-   * Convert the given remote path to a relative path with respect to
-   * the given local path.  The local path must be given in component
-   * form (see SystemTools::SplitPath) without a trailing slash.  The
-   * remote path must use forward slashes and not already be escaped
-   * or quoted.
-   */
-  std::string ConvertToRelativePath(const std::vector<std::string>& local,
-                                    const std::string& remote,
-                                    bool force=false);
-
   /**
    * Get the relative path from the generator output directory to a
    * per-target support directory.
@@ -392,7 +295,10 @@ public:
   bool IsMinGWMake() const;
   bool IsNMake() const;
 
-  void SetConfiguredCMP0014(bool configured);
+  void IssueMessage(cmake::MessageType t, std::string const& text) const;
+
+  void CreateEvaluationFileOutputs(const std::string& config);
+  void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
 
 protected:
   ///! put all the libraries for a target on into the given stream
@@ -415,23 +321,6 @@ protected:
   void InsertRuleLauncher(std::string& s, cmTarget* target,
                           const std::string& prop);
 
-
-  /** Convert a target to a utility target for unsupported
-   *  languages of a generator */
-  void AddBuildTargetRule(const std::string& llang,
-                          cmGeneratorTarget& target);
-  ///! add a custom command to build a .o file that is part of a target
-  void AddCustomCommandToCreateObject(const char* ofname,
-                                      const std::string& lang,
-                                      cmSourceFile& source,
-                                      cmGeneratorTarget& target);
-  // Create Custom Targets and commands for unsupported languages
-  // The set passed in should contain the languages supported by the
-  // generator directly.  Any targets containing files that are not
-  // of the types listed will be compiled as custom commands and added
-  // to a custom target.
-  void CreateCustomTargetsAndCommands(std::set<std::string> const&);
-
   // Handle old-style install rules stored in the targets.
   void GenerateTargetInstallRules(
     std::ostream& os, const std::string& config,
@@ -439,7 +328,6 @@ protected:
 
   std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
                                               std::string const& dir_max);
-  void ComputeObjectMaxPath();
 
   virtual std::string ConvertToLinkReference(std::string const& lib,
                                              OutputFormat format = SHELL);
@@ -451,17 +339,12 @@ protected:
   cmMakefile *Makefile;
   cmState::Snapshot StateSnapshot;
   cmGlobalGenerator *GlobalGenerator;
-  cmLocalGenerator* Parent;
-  std::vector<cmLocalGenerator*> Children;
   std::map<std::string, std::string> UniqueObjectNamesMap;
   std::string::size_type ObjectPathMax;
   std::set<std::string> ObjectMaxPathViolations;
 
   std::set<cmTarget const*> WarnCMP0063;
 
-  bool LinkScriptShell;
-  bool UseRelativePaths;
-  bool Configured;
   bool EmitUniversalBinaryFlags;
 
   // Hack for ExpandRuleVariable until object-oriented version is
@@ -471,15 +354,13 @@ protected:
   cmIML_INT_uint64_t BackwardsCompatibility;
   bool BackwardsCompatibilityFinal;
 private:
-  std::string ConvertToOutputForExistingCommon(const std::string& remote,
-                                               std::string const& result,
-                                               OutputFormat format);
-
   void AddSharedFlags(std::string& flags, const std::string& lang,
                       bool shared);
   bool GetShouldUseOldFlags(bool shared, const std::string &lang) const;
   void AddPositionIndependentFlags(std::string& flags, std::string const& l,
                                    int targetType);
+
+  void ComputeObjectMaxPath();
 };
 
 #endif
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index 870b9b9..bac989f 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -17,9 +17,8 @@
 #include "cmGeneratedFileStream.h"
 
 cmLocalGhsMultiGenerator::cmLocalGhsMultiGenerator(cmGlobalGenerator* gg,
-                                                   cmLocalGenerator* parent,
-                                                   cmState::Snapshot snapshot)
-  : cmLocalGenerator(gg, parent, snapshot)
+                                                   cmMakefile* mf)
+  : cmLocalGenerator(gg, mf)
 {
 }
 
@@ -37,7 +36,7 @@ void cmLocalGhsMultiGenerator::Generate()
       {
       continue;
       }
-    cmGhsMultiTargetGenerator tg(l->second->Target);
+    cmGhsMultiTargetGenerator tg(l->second);
     tg.Generate();
     }
 }
diff --git a/Source/cmLocalGhsMultiGenerator.h b/Source/cmLocalGhsMultiGenerator.h
index f52ef39..b6a9a33 100644
--- a/Source/cmLocalGhsMultiGenerator.h
+++ b/Source/cmLocalGhsMultiGenerator.h
@@ -25,8 +25,7 @@ class cmGeneratedFileStream;
 class cmLocalGhsMultiGenerator : public cmLocalGenerator
 {
 public:
-  cmLocalGhsMultiGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent,
-                           cmState::Snapshot snapshot);
+  cmLocalGhsMultiGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
 
   virtual ~cmLocalGhsMultiGenerator();
 
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index c08c91f..c46adc1 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -23,10 +23,8 @@
 #include <assert.h>
 
 cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
-                                             cmLocalGenerator* parent,
-                                             cmState::Snapshot snapshot)
-  : cmLocalGenerator(gg, parent, snapshot)
-  , ConfigName("")
+                                             cmMakefile* mf)
+  : cmLocalCommonGenerator(gg, mf)
   , HomeRelativeOutputPath("")
 {
   this->TargetImplib = "$TARGET_IMPLIB";
@@ -41,6 +39,15 @@ cmLocalNinjaGenerator::~cmLocalNinjaGenerator()
 
 void cmLocalNinjaGenerator::Generate()
 {
+  // Compute the path to use when referencing the current output
+  // directory from the top output directory.
+  this->HomeRelativeOutputPath =
+    this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT);
+  if(this->HomeRelativeOutputPath == ".")
+    {
+    this->HomeRelativeOutputPath = "";
+    }
+
   this->SetConfigName();
 
   this->WriteProcessedMakefile(this->GetBuildFileStream());
@@ -49,7 +56,7 @@ void cmLocalNinjaGenerator::Generate()
 #endif
 
   // We do that only once for the top CMakeLists.txt file.
-  if(this->IsRootMakefile())
+  if(this->Makefile->IsRootMakefile())
     {
     this->WriteBuildFileTop();
 
@@ -82,7 +89,7 @@ void cmLocalNinjaGenerator::Generate()
       // Add the target to "all" if required.
       if (!this->GetGlobalNinjaGenerator()->IsExcluded(
             this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0],
-            *t->second->Target))
+            t->second))
         this->GetGlobalNinjaGenerator()->AddDependencyToAll(t->second->Target);
       delete tg;
       }
@@ -91,25 +98,6 @@ void cmLocalNinjaGenerator::Generate()
   this->WriteCustomCommandBuildStatements();
 }
 
-// Implemented in:
-//   cmLocalUnixMakefileGenerator3.
-// Used in:
-//   Source/cmMakefile.cxx
-//   Source/cmGlobalGenerator.cxx
-void cmLocalNinjaGenerator::Configure()
-{
-  // Compute the path to use when referencing the current output
-  // directory from the top output directory.
-  this->HomeRelativeOutputPath =
-    this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT);
-  if(this->HomeRelativeOutputPath == ".")
-    {
-    this->HomeRelativeOutputPath = "";
-    }
-  this->cmLocalGenerator::Configure();
-
-}
-
 // TODO: Picked up from cmLocalUnixMakefileGenerator3.  Refactor it.
 std::string cmLocalNinjaGenerator
 ::GetTargetDirectory(cmTarget const& target) const
@@ -204,16 +192,14 @@ void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
 void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
 {
   // Default required version
-  // Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3
-  std::string requiredVersion = "1.3";
+  std::string requiredVersion =
+      this->GetGlobalNinjaGenerator()->RequiredNinjaVersion();
 
   // Ninja generator uses the 'console' pool if available (>= 1.5)
-  std::string usedVersion = this->GetGlobalNinjaGenerator()->ninjaVersion();
-  if(cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
-                                   usedVersion.c_str(),
-                                   "1.5") ==  false)
+  if(this->GetGlobalNinjaGenerator()->SupportsConsolePool())
     {
-      requiredVersion = "1.5";
+    requiredVersion =
+      this->GetGlobalNinjaGenerator()->RequiredNinjaVersionForConsolePool();
     }
 
   cmGlobalNinjaGenerator::WriteComment(os,
@@ -271,22 +257,6 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
   os << "\n";
 }
 
-void cmLocalNinjaGenerator::SetConfigName()
-{
-  // Store the configuration name that will be generated.
-  if(const char* config =
-       this->GetMakefile()->GetDefinition("CMAKE_BUILD_TYPE"))
-    {
-    // Use the build type given by the user.
-    this->ConfigName = config;
-    }
-  else
-    {
-    // No configuration type given.
-    this->ConfigName = "";
-    }
-}
-
 //----------------------------------------------------------------------------
 void cmLocalNinjaGenerator::ComputeObjectFilenames(
                         std::map<cmSourceFile const*, std::string>& mapping,
@@ -308,21 +278,12 @@ void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
     << "# Write statements declared in CMakeLists.txt:" << std::endl
     << "# "
     << this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE") << std::endl;
-  if(this->IsRootMakefile())
+  if(this->Makefile->IsRootMakefile())
     os << "# Which is the root file." << std::endl;
   cmGlobalNinjaGenerator::WriteDivider(os);
   os << std::endl;
 }
 
-std::string cmLocalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
-{
-  std::string convPath = this->Convert(path, cmLocalGenerator::HOME_OUTPUT);
-#ifdef _WIN32
-  cmSystemTools::ReplaceString(convPath, "/", "\\");
-#endif
-  return convPath;
-}
-
 void
 cmLocalNinjaGenerator
 ::AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs)
@@ -346,7 +307,8 @@ void cmLocalNinjaGenerator::AppendCustomCommandDeps(
        i != deps.end(); ++i) {
     std::string dep;
     if (this->GetRealDependency(*i, this->GetConfigName(), dep))
-      ninjaDeps.push_back(ConvertToNinjaPath(dep));
+      ninjaDeps.push_back(
+        this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(dep));
   }
 }
 
@@ -431,7 +393,7 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
   if (this->GetGlobalNinjaGenerator()->SeenCustomCommand(cc))
     return;
 
-  cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this->Makefile);
+  cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this);
 
   const std::vector<std::string> &outputs = ccg.GetOutputs();
   const std::vector<std::string> &byproducts = ccg.GetByproducts();
@@ -443,9 +405,11 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
     at us.  How to know which ExternalProject step actually provides it?
 #endif
   std::transform(outputs.begin(), outputs.end(),
-                 ninjaOutputs.begin(), MapToNinjaPath());
+                 ninjaOutputs.begin(),
+                 this->GetGlobalNinjaGenerator()->MapToNinjaPath());
   std::transform(byproducts.begin(), byproducts.end(),
-                 ninjaOutputs.begin() + outputs.size(), MapToNinjaPath());
+                 ninjaOutputs.begin() + outputs.size(),
+                 this->GetGlobalNinjaGenerator()->MapToNinjaPath());
   this->AppendCustomCommandDeps(ccg, ninjaDeps);
 
   for (cmNinjaDeps::iterator i = ninjaOutputs.begin(); i != ninjaOutputs.end();
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 7ae97de..1645a8d 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -13,7 +13,7 @@
 #ifndef cmLocalNinjaGenerator_h
 #  define cmLocalNinjaGenerator_h
 
-#  include "cmLocalGenerator.h"
+#  include "cmLocalCommonGenerator.h"
 #  include "cmNinjaTypes.h"
 
 class cmCustomCommandGenerator;
@@ -28,18 +28,15 @@ class cmake;
  * cmLocalNinjaGenerator produces a local build.ninja file from its
  * member Makefile.
  */
-class cmLocalNinjaGenerator : public cmLocalGenerator
+class cmLocalNinjaGenerator : public cmLocalCommonGenerator
 {
 public:
-  cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent,
-                        cmState::Snapshot snapshot);
+  cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
 
   virtual ~cmLocalNinjaGenerator();
 
   virtual void Generate();
 
-  virtual void Configure();
-
   virtual std::string GetTargetDirectory(cmTarget const& target) const;
 
   const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const;
@@ -48,29 +45,11 @@ public:
   const cmake* GetCMakeInstance() const;
   cmake* GetCMakeInstance();
 
-  std::string const& GetConfigName() const
-  { return this->ConfigName; }
-
   /// @returns the relative path between the HomeOutputDirectory and this
   /// local generators StartOutputDirectory.
   std::string GetHomeRelativeOutputPath() const
   { return this->HomeRelativeOutputPath; }
 
-  std::string ConvertToNinjaPath(const std::string& path);
-
-  struct map_to_ninja_path {
-    cmLocalNinjaGenerator *LocalGenerator;
-    map_to_ninja_path(cmLocalNinjaGenerator *LocalGen)
-      : LocalGenerator(LocalGen) {}
-    std::string operator()(const std::string &path) {
-      return LocalGenerator->ConvertToNinjaPath(path);
-    }
-  };
-
-  map_to_ninja_path MapToNinjaPath() {
-    return map_to_ninja_path(this);
-  }
-
   void ExpandRuleVariables(std::string& string,
                            const RuleVariables& replaceValues) {
     cmLocalGenerator::ExpandRuleVariables(string, replaceValues);
@@ -112,8 +91,6 @@ private:
   void WriteProcessedMakefile(std::ostream& os);
   void WritePools(std::ostream& os);
 
-  void SetConfigName();
-
   void WriteCustomCommandRule();
   void WriteCustomCommandBuildStatement(cmCustomCommand const *cc,
                                         const cmNinjaDeps& orderOnlyDeps);
@@ -122,7 +99,6 @@ private:
 
   std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
 
-  std::string ConfigName;
   std::string HomeRelativeOutputPath;
 
   typedef std::map<cmCustomCommand const*, std::set<cmTarget*> >
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 3eea59b..b131a63 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -80,9 +80,8 @@ static std::string cmSplitExtension(std::string const& in, std::string& base)
 
 //----------------------------------------------------------------------------
 cmLocalUnixMakefileGenerator3::
-cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmLocalGenerator* parent,
-                              cmState::Snapshot snapshot)
-  : cmLocalGenerator(gg, parent, snapshot)
+cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf)
+  : cmLocalCommonGenerator(gg, mf)
 {
   this->MakefileVariableSize = 0;
   this->ColorMakefile = false;
@@ -98,37 +97,9 @@ cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3()
 }
 
 //----------------------------------------------------------------------------
-void cmLocalUnixMakefileGenerator3::Configure()
-{
-  // Compute the path to use when referencing the current output
-  // directory from the top output directory.
-  this->HomeRelativeOutputPath =
-    this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT);
-  if(this->HomeRelativeOutputPath == ".")
-    {
-    this->HomeRelativeOutputPath = "";
-    }
-  if(!this->HomeRelativeOutputPath.empty())
-    {
-    this->HomeRelativeOutputPath += "/";
-    }
-  this->cmLocalGenerator::Configure();
-}
-
-//----------------------------------------------------------------------------
 void cmLocalUnixMakefileGenerator3::Generate()
 {
-  // Store the configuration name that will be generated.
-  if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
-    {
-    // Use the build type given by the user.
-    this->ConfigurationName = config;
-    }
-  else
-    {
-    // No configuration type given.
-    this->ConfigurationName = "";
-    }
+  this->SetConfigName();
 
   // Record whether some options are enabled to avoid checking many
   // times later.
@@ -169,6 +140,22 @@ void cmLocalUnixMakefileGenerator3::Generate()
   this->WriteDirectoryInformationFile();
 }
 
+void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath()
+{
+  // Compute the path to use when referencing the current output
+  // directory from the top output directory.
+  this->HomeRelativeOutputPath =
+    this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT);
+  if(this->HomeRelativeOutputPath == ".")
+    {
+    this->HomeRelativeOutputPath = "";
+    }
+  if(!this->HomeRelativeOutputPath.empty())
+    {
+    this->HomeRelativeOutputPath += "/";
+    }
+}
+
 //----------------------------------------------------------------------------
 void cmLocalUnixMakefileGenerator3::ComputeObjectFilenames(
                         std::map<cmSourceFile const*, std::string>& mapping,
@@ -268,7 +255,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
     return;
     }
   // always write the top makefile
-  if (this->Parent)
+  if (!this->GetMakefile()->IsRootMakefile())
     {
     ruleFileStream.SetCopyIfDifferent(true);
     }
@@ -279,7 +266,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
   // only write local targets unless at the top Keep track of targets already
   // listed.
   std::set<std::string> emittedTargets;
-  if (this->Parent)
+  if (!this->GetMakefile()->IsRootMakefile())
     {
     // write our targets, and while doing it collect up the object
     // file rules
@@ -498,8 +485,7 @@ void cmLocalUnixMakefileGenerator3
 
       // Add a local name for the rule to relink the target before
       // installation.
-      if(t->second->Target
-                  ->NeedRelinkBeforeInstall(this->ConfigurationName))
+      if(t->second->NeedRelinkBeforeInstall(this->ConfigName))
         {
         makeTargetName = this->GetRelativeTargetDirectory(*t->second->Target);
         makeTargetName += "/preinstall";
@@ -542,10 +528,10 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
   infoFileStream
     << "# Relative path conversion top directories.\n"
     << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \""
-    << this->StateSnapshot.GetRelativePathTopSource()
+    << this->StateSnapshot.GetDirectory().GetRelativePathTopSource()
     << "\")\n"
     << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \""
-    << this->StateSnapshot.GetRelativePathTopBinary()
+    << this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()
     << "\")\n"
     << "\n";
 
@@ -900,7 +886,7 @@ void cmLocalUnixMakefileGenerator3
   std::vector<std::string> no_depends;
   std::vector<std::string> commands;
   commands.push_back(runRule);
-  if(this->Parent)
+  if(!this->GetMakefile()->IsRootMakefile())
     {
     this->CreateCDCommand(commands,
                           this->Makefile->GetHomeOutputDirectory(),
@@ -1019,8 +1005,7 @@ cmLocalUnixMakefileGenerator3
   for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
       i != ccs.end(); ++i)
     {
-    cmCustomCommandGenerator ccg(*i, this->ConfigurationName,
-                                 this->Makefile);
+    cmCustomCommandGenerator ccg(*i, this->ConfigName, this);
     this->AppendCustomDepend(depends, ccg);
     }
 }
@@ -1036,7 +1021,7 @@ cmLocalUnixMakefileGenerator3
     {
     // Lookup the real name of the dependency in case it is a CMake target.
     std::string dep;
-    if(this->GetRealDependency(*d, this->ConfigurationName,
+    if(this->GetRealDependency(*d, this->ConfigName,
                                dep))
       {
       depends.push_back(dep);
@@ -1055,8 +1040,7 @@ cmLocalUnixMakefileGenerator3
   for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
       i != ccs.end(); ++i)
     {
-    cmCustomCommandGenerator ccg(*i, this->ConfigurationName,
-                                 this->Makefile);
+    cmCustomCommandGenerator ccg(*i, this->ConfigName, this);
     this->AppendCustomCommand(commands, ccg, target, true, relative);
     }
 }
@@ -1259,7 +1243,7 @@ cmLocalUnixMakefileGenerator3
         f != files.end(); ++f)
       {
       std::string fc = this->Convert(*f,START_OUTPUT,UNCHANGED);
-      fout << "  " << cmLocalGenerator::EscapeForCMake(fc) << "\n";
+      fout << "  " << cmOutputConverter::EscapeForCMake(fc) << "\n";
       }
     fout << ")\n";
     }
@@ -1272,7 +1256,9 @@ cmLocalUnixMakefileGenerator3
     {
     // Get the set of source languages in the target.
     std::set<std::string> languages;
-    target.GetLanguages(languages,
+    cmGeneratorTarget *gtgt =
+        this->GlobalGenerator->GetGeneratorTarget(&target);
+    gtgt->GetLanguages(languages,
                       this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
     fout << "\n"
          << "# Per-language clean rules from dependency scanning.\n"
@@ -1614,12 +1600,14 @@ cmLocalUnixMakefileGenerator3
     if(const char* relativePathTopSource =
        mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE"))
       {
-      this->StateSnapshot.SetRelativePathTopSource(relativePathTopSource);
+      this->StateSnapshot.GetDirectory()
+            .SetRelativePathTopSource(relativePathTopSource);
       }
     if(const char* relativePathTopBinary =
        mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY"))
       {
-      this->StateSnapshot.SetRelativePathTopBinary(relativePathTopBinary);
+      this->StateSnapshot.GetDirectory()
+            .SetRelativePathTopBinary(relativePathTopBinary);
       }
     }
   else
@@ -1845,7 +1833,6 @@ void cmLocalUnixMakefileGenerator3
   std::vector<std::string> commands;
 
   // Write the all rule.
-  std::string dir;
   std::string recursiveTarget = this->Makefile->GetCurrentBinaryDirectory();
   recursiveTarget += "/all";
 
@@ -2046,7 +2033,7 @@ void cmLocalUnixMakefileGenerator3
     // Build a list of preprocessor definitions for the target.
     std::set<std::string> defines;
     this->AddCompileDefinitions(defines, &target,
-                                this->ConfigurationName, l->first);
+                                this->ConfigName, l->first);
     if(!defines.empty())
       {
       cmakefileStream
@@ -2057,7 +2044,7 @@ void cmLocalUnixMakefileGenerator3
           di != defines.end(); ++di)
         {
         cmakefileStream
-          << "  " << cmLocalGenerator::EscapeForCMake(*di) << "\n";
+          << "  " << cmOutputConverter::EscapeForCMake(*di) << "\n";
         }
       cmakefileStream
         << "  )\n";
@@ -2111,7 +2098,7 @@ void cmLocalUnixMakefileGenerator3
         tri != transformRules.end(); ++tri)
       {
       cmakefileStream << "  "
-          << cmLocalGenerator::EscapeForCMake(*tri) << "\n";
+          << cmOutputConverter::EscapeForCMake(*tri) << "\n";
       }
     cmakefileStream
       << "  )\n";
@@ -2270,7 +2257,7 @@ cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p,
                           std::string());
       std::vector<std::string>::const_iterator compStart
           = components.begin() + 1;
-      result += cmJoin(cmRange(compStart, compEnd), slash);
+      result += cmJoin(cmMakeRange(compStart, compEnd), slash);
       // Only the last component can be empty to avoid double slashes.
       result += slash;
       result += components.back();
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 988d660..98f15e6 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -12,7 +12,7 @@
 #ifndef cmLocalUnixMakefileGenerator3_h
 #define cmLocalUnixMakefileGenerator3_h
 
-#include "cmLocalGenerator.h"
+#include "cmLocalCommonGenerator.h"
 
 // for cmDepends::DependencyVector
 #include "cmDepends.h"
@@ -31,26 +31,19 @@ class cmSourceFile;
  * cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its
  * member Makefile.
  */
-class cmLocalUnixMakefileGenerator3 : public cmLocalGenerator
+class cmLocalUnixMakefileGenerator3 : public cmLocalCommonGenerator
 {
 public:
-  cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg,
-                                cmLocalGenerator* parent,
-                                cmState::Snapshot snapshot);
+  cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
   virtual ~cmLocalUnixMakefileGenerator3();
 
-  /**
-   * Process the CMakeLists files for this directory to fill in the
-   * Makefile ivar
-   */
-  virtual void Configure();
+  virtual void ComputeHomeRelativeOutputPath();
 
   /**
    * Generate the makefile for this directory.
    */
   virtual void Generate();
 
-
   // this returns the relative path between the HomeOutputDirectory and this
   // local generators StartOutputDirectory
   const std::string &GetHomeRelativeOutputPath();
@@ -153,9 +146,6 @@ public:
   void AddImplicitDepends(cmTarget const& tgt, const std::string& lang,
                           const char* obj, const char* src);
 
-  void AppendGlobalTargetDepends(std::vector<std::string>& depends,
-                                 cmTarget& target);
-
   // write the target rules for the local Makefile into the stream
   void WriteLocalAllRules(std::ostream& ruleFileStream);
 
@@ -260,26 +250,8 @@ private:
 
   ImplicitDependTargetMap ImplicitDepends;
 
-  //==========================================================================
-  // Configuration settings.
-  int MakefileVariableSize;
-  std::string ConfigurationName;
-  bool MakeCommandEscapeTargetTwice;
-  bool BorlandMakeCurlyHack;
-  //==========================================================================
-
   std::string HomeRelativeOutputPath;
 
-  /* Copy the setting of CMAKE_COLOR_MAKEFILE from the makefile at the
-     beginning of generation to avoid many duplicate lookups.  */
-  bool ColorMakefile;
-
-  /* Copy the setting of CMAKE_SKIP_PREPROCESSED_SOURCE_RULES and
-     CMAKE_SKIP_ASSEMBLY_SOURCE_RULES at the beginning of generation to
-     avoid many duplicate lookups.  */
-  bool SkipPreprocessedSourceRules;
-  bool SkipAssemblySourceRules;
-
   struct LocalObjectEntry
   {
     cmTarget* Target;
@@ -308,6 +280,13 @@ private:
   /* does the work for each target */
   std::map<std::string, std::string> MakeVariableMap;
   std::map<std::string, std::string> ShortMakeVariableMap;
+
+  int MakefileVariableSize;
+  bool MakeCommandEscapeTargetTwice;
+  bool BorlandMakeCurlyHack;
+  bool ColorMakefile;
+  bool SkipPreprocessedSourceRules;
+  bool SkipAssemblySourceRules;
 };
 
 #endif
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index ad6a020..b043b00 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -33,7 +33,7 @@ class cmVS10XMLParser : public cmXMLParser
   virtual void StartElement(const std::string& name, const char**)
     {
       // once the GUID is found do nothing
-      if(this->GUID.size())
+      if(!this->GUID.empty())
         {
         return;
         }
@@ -62,10 +62,8 @@ class cmVS10XMLParser : public cmXMLParser
 
 //----------------------------------------------------------------------------
 cmLocalVisualStudio10Generator
-::cmLocalVisualStudio10Generator(cmGlobalGenerator* gg,
-                                 cmLocalGenerator* parent,
-                                 cmState::Snapshot snapshot):
-  cmLocalVisualStudio7Generator(gg, parent, snapshot)
+::cmLocalVisualStudio10Generator(cmGlobalGenerator* gg, cmMakefile* mf):
+  cmLocalVisualStudio7Generator(gg, mf)
 {
 }
 
@@ -107,10 +105,9 @@ void cmLocalVisualStudio10Generator
   cmVS10XMLParser parser;
   parser.ParseFile(path);
 
-  // if we can not find a GUID then create one
+  // if we can not find a GUID then we will generate one later
   if(parser.GUID.empty())
     {
-    this->GlobalGenerator->CreateGUID(name);
     return;
     }
 
diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h
index c588aaf..e187590 100644
--- a/Source/cmLocalVisualStudio10Generator.h
+++ b/Source/cmLocalVisualStudio10Generator.h
@@ -25,9 +25,7 @@ class cmLocalVisualStudio10Generator : public cmLocalVisualStudio7Generator
 {
 public:
   ///! Set cache only and recurse to false by default.
-  cmLocalVisualStudio10Generator(cmGlobalGenerator* gg,
-                                 cmLocalGenerator* parent,
-                                 cmState::Snapshot snapshot);
+  cmLocalVisualStudio10Generator(cmGlobalGenerator* gg, cmMakefile* mf);
 
   virtual ~cmLocalVisualStudio10Generator();
 
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index ad34857..cc94cd4 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -24,10 +24,8 @@
 #include <cmsys/FStream.hxx>
 
 cmLocalVisualStudio6Generator
-::cmLocalVisualStudio6Generator(cmGlobalGenerator* gg,
-                                cmLocalGenerator* parent,
-                                cmState::Snapshot snapshot):
-  cmLocalVisualStudioGenerator(gg, parent, snapshot)
+::cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, cmMakefile* mf):
+  cmLocalVisualStudioGenerator(gg, mf)
 {
 }
 
@@ -62,7 +60,7 @@ public:
     }
   void Write(cmCustomCommand const& cc)
     {
-    cmCustomCommandGenerator ccg(cc, this->Config, this->LG->GetMakefile());
+    cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
     if(this->First)
       {
       this->Code += this->Event + "_Cmds=";
@@ -82,21 +80,14 @@ private:
   std::string Event;
 };
 
-void cmLocalVisualStudio6Generator::AddHelperCommands()
-{
-  std::set<std::string> lang;
-  lang.insert("C");
-  lang.insert("CXX");
-  this->CreateCustomTargetsAndCommands(lang);
-}
-
 void cmLocalVisualStudio6Generator::AddCMakeListsRules()
 {
   cmTargets &tgts = this->Makefile->GetTargets();
   for(cmTargets::iterator l = tgts.begin();
       l != tgts.end(); l++)
     {
-    if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
+    if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY
+        || l->second.GetType() == cmTarget::GLOBAL_TARGET)
       {
       continue;
       }
@@ -235,13 +226,10 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
   comment += makefileIn;
   std::string args;
   args = "-H";
-  args += this->Convert(this->Makefile->GetHomeDirectory(),
-                        START_OUTPUT, UNCHANGED, true);
+  args += this->Makefile->GetHomeDirectory();
   commandLine.push_back(args);
   args = "-B";
-  args +=
-    this->Convert(this->Makefile->GetHomeOutputDirectory(),
-                  START_OUTPUT, UNCHANGED, true);
+  args += this->Makefile->GetHomeOutputDirectory();
   commandLine.push_back(args);
 
   std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
@@ -315,9 +303,12 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
   // We may be modifying the source groups temporarily, so make a copy.
   std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
 
+  cmGeneratorTarget* gt =
+    this->GlobalGenerator->GetGeneratorTarget(&target);
+
   // get the classes from the source lists then add them to the groups
   std::vector<cmSourceFile*> classes;
-  if (!target.GetConfigCommonSourceFiles(classes))
+  if (!gt->GetConfigCommonSourceFiles(classes))
     {
     return;
     }
@@ -498,7 +489,7 @@ void cmLocalVisualStudio6Generator
       // Tell MS-Dev what the source is.  If the compiler knows how to
       // build it, then it will.
       fout << "SOURCE=" <<
-        this->ConvertToOptionallyRelativeOutputPath(source.c_str()) << "\n\n";
+        this->ConvertToOutputFormat(source.c_str(), SHELL) << "\n\n";
       if(!depends.empty())
         {
         // Write out the dependencies for the rule.
@@ -507,7 +498,7 @@ void cmLocalVisualStudio6Generator
             d != depends.end(); ++d)
           {
           fout << "\\\n\t" <<
-            this->ConvertToOptionallyRelativeOutputPath(d->c_str());
+            this->ConvertToOutputFormat(d->c_str(), SHELL);
           }
         fout << "\n";
         }
@@ -628,7 +619,7 @@ cmLocalVisualStudio6Generator
   for(i = this->Configurations.begin(); i != this->Configurations.end(); ++i)
     {
     std::string config = this->GetConfigName(*i);
-    cmCustomCommandGenerator ccg(command, config, this->Makefile);
+    cmCustomCommandGenerator ccg(command, config, this);
     std::string comment =
       this->ConstructComment(ccg, "Building Custom Rule $(InputPath)");
     if(comment == "<hack>")
@@ -663,7 +654,7 @@ cmLocalVisualStudio6Generator
       if(this->GetRealDependency(d->c_str(), config.c_str(), dep))
         {
         fout << "\\\n\t" <<
-          this->ConvertToOptionallyRelativeOutputPath(dep.c_str());
+          this->ConvertToOutputFormat(dep.c_str(), SHELL);
         }
       }
     fout << "\n";
@@ -689,7 +680,7 @@ cmLocalVisualStudio6Generator
           ++o)
         {
         // Write a rule for every output generated by this command.
-        fout << this->ConvertToOptionallyRelativeOutputPath(o->c_str())
+        fout << this->ConvertToOutputFormat(o->c_str(), SHELL)
              << " :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
         fout << script.c_str() << "\n\n";
         }
@@ -906,7 +897,7 @@ cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target,
     for(i = includes.begin(); i != includes.end(); ++i)
       {
       std::string tmp =
-        this->ConvertToOptionallyRelativeOutputPath(i->c_str());
+        this->ConvertToOutputFormat(i->c_str(), SHELL);
       if(useShortPath)
         {
         cmSystemTools::GetShortPath(tmp.c_str(), tmp);
@@ -994,17 +985,17 @@ void cmLocalVisualStudio6Generator
   std::string libMultiLineDebugOptions;
   std::string libMultiLineOptimizedOptions;
 
-  if(libPath.size())
+  if(!libPath.empty())
     {
     std::string lpath =
-      this->ConvertToOptionallyRelativeOutputPath(libPath.c_str());
-    if(lpath.size() == 0)
+      this->ConvertToOutputFormat(libPath.c_str(), SHELL);
+    if(lpath.empty())
       {
       lpath = ".";
       }
     std::string lpathIntDir = libPath + "$(INTDIR)";
     lpathIntDir =
-      this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+      this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
     if(pathEmitted.insert(lpath).second)
       {
       libOptions += " /LIBPATH:";
@@ -1027,17 +1018,17 @@ void cmLocalVisualStudio6Generator
       libMultiLineOptionsForDebug += " \n";
       }
     }
-  if(exePath.size())
+  if(!exePath.empty())
     {
     std::string lpath =
-      this->ConvertToOptionallyRelativeOutputPath(exePath.c_str());
-    if(lpath.size() == 0)
+      this->ConvertToOutputFormat(exePath.c_str(), SHELL);
+    if(lpath.empty())
       {
       lpath = ".";
       }
     std::string lpathIntDir = exePath + "$(INTDIR)";
     lpathIntDir =
-      this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+      this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
 
     if(pathEmitted.insert(lpath).second)
       {
@@ -1071,14 +1062,14 @@ void cmLocalVisualStudio6Generator
       path += "/";
       }
     std::string lpath =
-      this->ConvertToOptionallyRelativeOutputPath(path.c_str());
-    if(lpath.size() == 0)
+      this->ConvertToOutputFormat(path.c_str(), SHELL);
+    if(lpath.empty())
       {
       lpath = ".";
       }
     std::string lpathIntDir = path + "$(INTDIR)";
     lpathIntDir =
-      this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+      this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
     if(pathEmitted.insert(lpath).second)
       {
       libOptions += " /LIBPATH:";
@@ -1125,10 +1116,12 @@ void cmLocalVisualStudio6Generator
       cmTarget* tgt = this->GlobalGenerator->FindTarget(j->first.c_str());
       if(tgt)
         {
+        cmGeneratorTarget* gt =
+          this->GlobalGenerator->GetGeneratorTarget(tgt);
         lib = cmSystemTools::GetFilenameWithoutExtension
-          (tgt->GetFullName().c_str());
+          (gt->GetFullName().c_str());
         libDebug = cmSystemTools::GetFilenameWithoutExtension
-          (tgt->GetFullName("Debug").c_str());
+          (gt->GetFullName("Debug").c_str());
         lib += ".lib";
         libDebug += ".lib";
         }
@@ -1142,9 +1135,9 @@ void cmLocalVisualStudio6Generator
           libDebug += ".lib";
           }
         }
-      lib = this->ConvertToOptionallyRelativeOutputPath(lib.c_str());
+      lib = this->ConvertToOutputFormat(lib.c_str(), SHELL);
       libDebug =
-        this->ConvertToOptionallyRelativeOutputPath(libDebug.c_str());
+        this->ConvertToOutputFormat(libDebug.c_str(), SHELL);
 
       if (j->second == cmTarget::GENERAL)
         {
@@ -1268,8 +1261,8 @@ void cmLocalVisualStudio6Generator
     extraLinkOptionsRelWithDebInfo += targetLinkFlags;
     }
 
-
-
+  cmGeneratorTarget* gt =
+    this->GlobalGenerator->GetGeneratorTarget(&target);
 
   // Get standard libraries for this language.
   if(targetBuilds)
@@ -1278,10 +1271,10 @@ void cmLocalVisualStudio6Generator
     std::vector<std::string> configs;
     target.GetMakefile()->GetConfigurations(configs);
     std::vector<std::string>::const_iterator it = configs.begin();
-    const std::string& linkLanguage = target.GetLinkerLanguage(*it);
+    const std::string& linkLanguage = gt->GetLinkerLanguage(*it);
     for ( ; it != configs.end(); ++it)
       {
-      const std::string& configLinkLanguage = target.GetLinkerLanguage(*it);
+      const std::string& configLinkLanguage = gt->GetLinkerLanguage(*it);
       if (configLinkLanguage != linkLanguage)
         {
         cmSystemTools::Error
@@ -1338,11 +1331,11 @@ void cmLocalVisualStudio6Generator
      target.GetType() == cmTarget::SHARED_LIBRARY ||
      target.GetType() == cmTarget::MODULE_LIBRARY)
     {
-    outputName = target.GetFullName();
-    outputNameDebug = target.GetFullName("Debug");
-    outputNameRelease = target.GetFullName("Release");
-    outputNameMinSizeRel = target.GetFullName("MinSizeRel");
-    outputNameRelWithDebInfo = target.GetFullName("RelWithDebInfo");
+    outputName = gt->GetFullName();
+    outputNameDebug = gt->GetFullName("Debug");
+    outputNameRelease = gt->GetFullName("Release");
+    outputNameMinSizeRel = gt->GetFullName("MinSizeRel");
+    outputNameRelWithDebInfo = gt->GetFullName("RelWithDebInfo");
     }
   else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
     {
@@ -1367,21 +1360,21 @@ void cmLocalVisualStudio6Generator
     {
 #ifdef CM_USE_OLD_VS6
     outputDirOld =
-      removeQuotes(this->ConvertToOptionallyRelativeOutputPath
-                   (target.GetDirectory().c_str()));
+      removeQuotes(this->ConvertToOutputFormat
+                   (target.GetDirectory().c_str(), SHELL));
 #endif
     outputDirDebug =
-        removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
-                       target.GetDirectory("Debug").c_str()));
+        removeQuotes(this->ConvertToOutputFormat(
+                       target.GetDirectory("Debug").c_str(), SHELL));
     outputDirRelease =
-        removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
-                 target.GetDirectory("Release").c_str()));
+        removeQuotes(this->ConvertToOutputFormat(
+                 target.GetDirectory("Release").c_str(), SHELL));
     outputDirMinSizeRel =
-        removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
-                 target.GetDirectory("MinSizeRel").c_str()));
+        removeQuotes(this->ConvertToOutputFormat(
+                 target.GetDirectory("MinSizeRel").c_str(), SHELL));
     outputDirRelWithDebInfo =
-        removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
-                 target.GetDirectory("RelWithDebInfo").c_str()));
+        removeQuotes(this->ConvertToOutputFormat(
+                 target.GetDirectory("RelWithDebInfo").c_str(), SHELL));
     }
   else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
     {
@@ -1439,30 +1432,28 @@ void cmLocalVisualStudio6Generator
     fullPathImpRelease += "/";
     fullPathImpMinSizeRel += "/";
     fullPathImpRelWithDebInfo += "/";
-    fullPathImpDebug += target.GetFullName("Debug", true);
-    fullPathImpRelease += target.GetFullName("Release", true);
-    fullPathImpMinSizeRel += target.GetFullName("MinSizeRel", true);
-    fullPathImpRelWithDebInfo += target.GetFullName("RelWithDebInfo", true);
+    fullPathImpDebug += gt->GetFullName("Debug", true);
+    fullPathImpRelease += gt->GetFullName("Release", true);
+    fullPathImpMinSizeRel += gt->GetFullName("MinSizeRel", true);
+    fullPathImpRelWithDebInfo += gt->GetFullName("RelWithDebInfo", true);
 
     targetImplibFlagDebug = "/implib:";
     targetImplibFlagRelease = "/implib:";
     targetImplibFlagMinSizeRel = "/implib:";
     targetImplibFlagRelWithDebInfo = "/implib:";
     targetImplibFlagDebug +=
-      this->ConvertToOptionallyRelativeOutputPath(fullPathImpDebug.c_str());
+      this->ConvertToOutputFormat(fullPathImpDebug.c_str(), SHELL);
     targetImplibFlagRelease +=
-      this->ConvertToOptionallyRelativeOutputPath(fullPathImpRelease.c_str());
+      this->ConvertToOutputFormat(fullPathImpRelease.c_str(), SHELL);
     targetImplibFlagMinSizeRel +=
-      this->ConvertToOptionallyRelativeOutputPath(
-        fullPathImpMinSizeRel.c_str());
+      this->ConvertToOutputFormat(fullPathImpMinSizeRel.c_str(), SHELL);
     targetImplibFlagRelWithDebInfo +=
-      this->ConvertToOptionallyRelativeOutputPath(
-        fullPathImpRelWithDebInfo.c_str());
+      this->ConvertToOutputFormat(fullPathImpRelWithDebInfo.c_str(), SHELL);
     }
 
 #ifdef CM_USE_OLD_VS6
   // Compute link information for the target.
-  if(extraLinkOptions.size())
+  if(!extraLinkOptions.empty())
     {
     libOptions += " ";
     libOptions += extraLinkOptions;
@@ -1553,7 +1544,7 @@ void cmLocalVisualStudio6Generator
 
   std::string line;
   std::string libnameExports;
-  if(exportSymbol.size())
+  if(!exportSymbol.empty())
     {
     libnameExports = "/D \"";
     libnameExports += exportSymbol;
@@ -1669,12 +1660,12 @@ void cmLocalVisualStudio6Generator
     // to convert to output path for unix to win32 conversion
     cmSystemTools::ReplaceString
       (line, "LIBRARY_OUTPUT_PATH",
-       removeQuotes(this->ConvertToOptionallyRelativeOutputPath
-                    (libPath.c_str())).c_str());
+       removeQuotes(this->ConvertToOutputFormat
+                    (libPath.c_str(), SHELL)).c_str());
     cmSystemTools::ReplaceString
       (line, "EXECUTABLE_OUTPUT_PATH",
-       removeQuotes(this->ConvertToOptionallyRelativeOutputPath
-                    (exePath.c_str())).c_str());
+       removeQuotes(this->ConvertToOutputFormat
+                    (exePath.c_str(), SHELL)).c_str());
 #endif
 
     if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY)
@@ -1713,10 +1704,10 @@ void cmLocalVisualStudio6Generator
       std::vector<std::string> configs;
       target.GetMakefile()->GetConfigurations(configs);
       std::vector<std::string>::const_iterator it = configs.begin();
-      const std::string& linkLanguage = target.GetLinkerLanguage(*it);
+      const std::string& linkLanguage = gt->GetLinkerLanguage(*it);
       for ( ; it != configs.end(); ++it)
         {
-        const std::string& configLinkLanguage = target.GetLinkerLanguage(*it);
+        const std::string& configLinkLanguage = gt->GetLinkerLanguage(*it);
         if (configLinkLanguage != linkLanguage)
           {
           cmSystemTools::Error
@@ -1858,8 +1849,10 @@ void cmLocalVisualStudio6Generator
                      const std::string extraOptions,
                      std::string& options)
 {
+  cmGeneratorTarget* gt =
+    this->GlobalGenerator->GetGeneratorTarget(&target);
   // Compute the link information for this configuration.
-  cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+  cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
   if(!pcli)
     {
     return;
@@ -1884,9 +1877,9 @@ void cmLocalVisualStudio6Generator
         }
       dir += "$(IntDir)";
       options += "# ADD LINK32 /LIBPATH:";
-      options += this->ConvertToOptionallyRelativeOutputPath(dir.c_str());
+      options += this->ConvertToOutputFormat(dir.c_str(), SHELL);
       options += " /LIBPATH:";
-      options += this->ConvertToOptionallyRelativeOutputPath(d->c_str());
+      options += this->ConvertToOutputFormat(d->c_str(), SHELL);
       options += "\n";
       }
     }
@@ -1897,7 +1890,7 @@ void cmLocalVisualStudio6Generator
     if(l->IsPath)
       {
       options +=
-        this->ConvertToOptionallyRelativeOutputPath(l->Value.c_str());
+        this->ConvertToOutputFormat(l->Value.c_str(), SHELL);
       }
     else if (!l->Target
         || l->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
@@ -1933,7 +1926,7 @@ void cmLocalVisualStudio6Generator
     options += "# ADD ";
     options += tool;
     options += "32 ";
-    options += this->ConvertToOptionallyRelativeOutputPath(oi->c_str());
+    options += this->ConvertToOutputFormat(oi->c_str(), SHELL);
     options += "\n";
     }
 }
diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h
index 8f4d521..828d252 100644
--- a/Source/cmLocalVisualStudio6Generator.h
+++ b/Source/cmLocalVisualStudio6Generator.h
@@ -29,13 +29,10 @@ class cmLocalVisualStudio6Generator : public cmLocalVisualStudioGenerator
 {
 public:
   ///! Set cache only and recurse to false by default.
-  cmLocalVisualStudio6Generator(cmGlobalGenerator* gg,
-                                cmLocalGenerator* parent,
-                                cmState::Snapshot snapshot);
+  cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, cmMakefile* mf);
 
   virtual ~cmLocalVisualStudio6Generator();
 
-  virtual void AddHelperCommands();
   virtual void AddCMakeListsRules();
 
   /**
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 9c031cf..a4bce8a 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -23,8 +23,6 @@
 #include "cmComputeLinkInformation.h"
 #include "cmGeneratedFileStream.h"
 
-#include <cmsys/System.h>
-
 #include <ctype.h> // for isspace
 
 static bool cmLVS6G_IsFAT(const char* dir);
@@ -55,10 +53,8 @@ static void cmConvertToWindowsSlash(std::string& s)
 
 //----------------------------------------------------------------------------
 cmLocalVisualStudio7Generator
-::cmLocalVisualStudio7Generator(cmGlobalGenerator* gg,
-                                cmLocalGenerator* parent,
-                                cmState::Snapshot snapshot):
-  cmLocalVisualStudioGenerator(gg, parent, snapshot)
+::cmLocalVisualStudio7Generator(cmGlobalGenerator* gg, cmMakefile* mf):
+  cmLocalVisualStudioGenerator(gg, mf)
 {
   this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
 }
@@ -70,20 +66,9 @@ cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
 
 void cmLocalVisualStudio7Generator::AddHelperCommands()
 {
-  std::set<std::string> lang;
-  lang.insert("C");
-  lang.insert("CXX");
-  lang.insert("RC");
-  lang.insert("IDL");
-  lang.insert("DEF");
-  lang.insert("Fortran");
-  this->CreateCustomTargetsAndCommands(lang);
-
   // Now create GUIDs for targets
   cmTargets &tgts = this->Makefile->GetTargets();
 
-  cmGlobalVisualStudio7Generator* gg =
-    static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
   for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
     {
     if(l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
@@ -96,10 +81,6 @@ void cmLocalVisualStudio7Generator::AddHelperCommands()
       this->ReadAndStoreExternalGUID(
         l->second.GetName().c_str(), path);
       }
-    else
-      {
-      gg->CreateGUID(l->first.c_str());
-      }
     }
 
 
@@ -125,6 +106,10 @@ void cmLocalVisualStudio7Generator::AddCMakeListsRules()
       // Add the rule to targets that need it.
       for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
         {
+        if (l->second.GetType() == cmTarget::GLOBAL_TARGET)
+          {
+          continue;
+          }
         if(l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
           {
           l->second.AddSource(sf->GetFullPath());
@@ -305,13 +290,10 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
   comment += makefileIn;
   std::string args;
   args = "-H";
-  args += this->Convert(this->Makefile->GetHomeDirectory(),
-                        START_OUTPUT, UNCHANGED, true);
+  args += this->Makefile->GetHomeDirectory();
   commandLine.push_back(args);
   args = "-B";
-  args +=
-    this->Convert(this->Makefile->GetHomeOutputDirectory(),
-                  START_OUTPUT, UNCHANGED, true);
+  args += this->Makefile->GetHomeOutputDirectory();
   commandLine.push_back(args);
   commandLine.push_back("--check-stamp-file");
   std::string stampFilename = this->Convert(stampName.c_str(), FULL,
@@ -630,7 +612,7 @@ public:
     }
   void Write(cmCustomCommand const& cc)
     {
-    cmCustomCommandGenerator ccg(cc, this->Config, this->LG->GetMakefile());
+    cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
     if(this->First)
       {
       const char* comment = ccg.GetComment();
@@ -680,6 +662,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
   const char* configType = "10";
   const char* projectType = 0;
   bool targetBuilds = true;
+
+  cmGeneratorTarget* gt =
+    this->GlobalGenerator->GetGeneratorTarget(&target);
+
   switch(target.GetType())
     {
     case cmTarget::OBJECT_LIBRARY:
@@ -712,7 +698,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
     {
     const std::string& linkLanguage = (this->FortranProject?
                                        std::string("Fortran"):
-                                target.GetLinkerLanguage(configName));
+                                gt->GetLinkerLanguage(configName));
     if(linkLanguage.empty())
       {
       cmSystemTools::Error
@@ -774,10 +760,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
   targetOptions.Parse(flags.c_str());
   targetOptions.Parse(defineFlags.c_str());
   targetOptions.ParseFinish();
-  cmGeneratorTarget* gt =
-    this->GlobalGenerator->GetGeneratorTarget(&target);
   std::vector<std::string> targetDefines;
-  target.GetCompileDefinitions(targetDefines, configName, "CXX");
+  gt->GetCompileDefinitions(targetDefines, configName, "CXX");
   targetOptions.AddDefines(targetDefines);
   targetOptions.SetVerboseMakefile(
     this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
@@ -819,7 +803,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
   if (this->FortranProject)
     {
     // Intel Fortran >= 15.0 uses TargetName property.
-    std::string targetNameFull = target.GetFullName(configName);
+    std::string targetNameFull = gt->GetFullName(configName);
     std::string targetName =
       cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
     std::string targetExt =
@@ -897,7 +881,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
   if(target.GetType() <= cmTarget::OBJECT_LIBRARY)
     {
     // Specify the compiler program database file if configured.
-    std::string pdb = target.GetCompilePDBPath(configName);
+    std::string pdb = gt->GetCompilePDBPath(configName);
     if(!pdb.empty())
       {
       fout <<  "\t\t\t\tProgramDataBaseFileName=\""
@@ -988,25 +972,43 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
   fout << "\t\t\t\tProxyFileName=\"$(InputName)_p.c\"/>\n";
   // end of <Tool Name=VCMIDLTool
 
-  // Check if we need the FAT32 workaround.
+  // Add manifest tool settings.
   if(targetBuilds && this->GetVersion() >= cmGlobalVisualStudioGenerator::VS8)
     {
+    const char* manifestTool  = "VCManifestTool";
+    if (this->FortranProject)
+      {
+      manifestTool = "VFManifestTool";
+      }
+    fout <<
+      "\t\t\t<Tool\n"
+      "\t\t\t\tName=\"" << manifestTool << "\"";
+
+    std::vector<cmSourceFile const*> manifest_srcs;
+    gt->GetManifests(manifest_srcs, configName);
+    if (!manifest_srcs.empty())
+      {
+      fout << "\n\t\t\t\tAdditionalManifestFiles=\"";
+      for (std::vector<cmSourceFile const*>::const_iterator
+             mi = manifest_srcs.begin(); mi != manifest_srcs.end(); ++mi)
+        {
+        std::string m = (*mi)->GetFullPath();
+        fout << this->ConvertToXMLOutputPath(m.c_str()) << ";";
+        }
+      fout << "\"";
+      }
+
+    // Check if we need the FAT32 workaround.
     // Check the filesystem type where the target will be written.
-    if(cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
+    if (cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
       {
       // Add a flag telling the manifest tool to use a workaround
       // for FAT32 file systems, which can cause an empty manifest
       // to be embedded into the resulting executable.  See CMake
       // bug #2617.
-      const char* manifestTool  = "VCManifestTool";
-      if(this->FortranProject)
-        {
-        manifestTool = "VFManifestTool";
-        }
-      fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << manifestTool << "\"\n"
-           << "\t\t\t\tUseFAT32Workaround=\"true\"\n"
-           << "\t\t\t/>\n";
+      fout << "\n\t\t\t\tUseFAT32Workaround=\"true\"";
       }
+    fout << "/>\n";
     }
 
   this->OutputTargetRules(fout, configName, target, libName);
@@ -1087,9 +1089,20 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
   if(!this->ModuleDefinitionFile.empty())
     {
     std::string defFile =
-      this->ConvertToOptionallyRelativeOutputPath(this->ModuleDefinitionFile);
+      this->ConvertToOutputFormat(this->ModuleDefinitionFile, SHELL);
     linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
     }
+  cmGeneratorTarget* gt =
+    this->GlobalGenerator->GetGeneratorTarget(&target);
+
+  if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if (target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def");
+      }
+    }
   switch(target.GetType())
     {
     case cmTarget::UNKNOWN_LIBRARY:
@@ -1112,7 +1125,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
       }
     case cmTarget::STATIC_LIBRARY:
     {
-    std::string targetNameFull = target.GetFullName(configName);
+    std::string targetNameFull = gt->GetFullName(configName);
     std::string libpath = target.GetDirectory(configName);
     libpath += "/";
     libpath += targetNameFull;
@@ -1152,11 +1165,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     std::string targetNameFull;
     std::string targetNameImport;
     std::string targetNamePDB;
-    target.GetLibraryNames(targetName, targetNameSO, targetNameFull,
+    gt->GetLibraryNames(targetName, targetNameSO, targetNameFull,
                            targetNameImport, targetNamePDB, configName);
 
     // Compute the link library and directory information.
-    cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+    cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
     if(!pcli)
       {
       return;
@@ -1249,11 +1262,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     std::string targetNameFull;
     std::string targetNameImport;
     std::string targetNamePDB;
-    target.GetExecutableNames(targetName, targetNameFull,
+    gt->GetExecutableNames(targetName, targetNameFull,
                               targetNameImport, targetNamePDB, configName);
 
     // Compute the link library and directory information.
-    cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+    cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
     if(!pcli)
       {
       return;
@@ -1472,10 +1485,13 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
   // We may be modifying the source groups temporarily, so make a copy.
   std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
 
+  cmGeneratorTarget* gt =
+    this->GlobalGenerator->GetGeneratorTarget(&target);
+
   // get the classes from the source lists then add them to the groups
   this->ModuleDefinitionFile = "";
   std::vector<cmSourceFile*> classes;
-  if (!target.GetConfigCommonSourceFiles(classes))
+  if (!gt->GetConfigCommonSourceFiles(classes))
     {
     return;
     }
@@ -1517,8 +1533,6 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
     {
     // VS >= 8 support per-config source locations so we
     // list object library content as external objects.
-    cmGeneratorTarget* gt =
-      this->GlobalGenerator->GetGeneratorTarget(&target);
     std::vector<std::string> objs;
     gt->UseObjectLibraries(objs, "");
     if(!objs.empty())
@@ -1640,7 +1654,7 @@ cmLocalVisualStudio7GeneratorFCInfo
       lg->GlobalGenerator->GetLanguageFromExtension
       (sf.GetExtension().c_str());
     const std::string& sourceLang = lg->GetSourceFileLanguage(sf);
-    const std::string& linkLanguage = target.GetLinkerLanguage(i->c_str());
+    const std::string& linkLanguage = gt->GetLinkerLanguage(i->c_str());
     bool needForceLang = false;
     // source file does not match its extension language
     if(lang != sourceLang)
@@ -1906,7 +1920,7 @@ WriteCustomRule(std::ostream& fout,
   for (std::vector<std::string>::const_iterator i = configs.begin();
        i != configs.end(); ++i)
     {
-    cmCustomCommandGenerator ccg(command, *i, this->Makefile);
+    cmCustomCommandGenerator ccg(command, *i, this);
     cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i];
     fout << "\t\t\t\t<FileConfiguration\n";
     fout << "\t\t\t\t\tName=\"" << *i << "|"
@@ -2024,7 +2038,28 @@ void cmLocalVisualStudio7Generator
   // Add pre-link event.
   tool = this->FortranProject? "VFPreLinkEventTool":"VCPreLinkEventTool";
   event.Start(tool);
-  event.Write(target.GetPreLinkCommands());
+  bool addedPrelink = false;
+  if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if (target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      addedPrelink = true;
+      std::vector<cmCustomCommand> commands =
+        target.GetPreLinkCommands();
+      cmGlobalVisualStudioGenerator* gg
+        = static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
+      cmGeneratorTarget* gt =
+        this->GlobalGenerator->GetGeneratorTarget(&target);
+      gg->AddSymbolExportCommand(
+        gt, commands, configName);
+      event.Write(commands);
+      }
+    }
+  if (!addedPrelink)
+    {
+    event.Write(target.GetPreLinkCommands());
+    }
   cmsys::auto_ptr<cmCustomCommand> pcc(
     this->MaybeCreateImplibDir(target, configName, this->FortranProject));
   if(pcc.get())
@@ -2234,7 +2269,7 @@ std::string cmLocalVisualStudio7Generator::EscapeForXML(const std::string& s)
 std::string cmLocalVisualStudio7Generator
 ::ConvertToXMLOutputPath(const char* path)
 {
-  std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
+  std::string ret = this->ConvertToOutputFormat(path, SHELL);
   cmSystemTools::ReplaceString(ret, "&", "&");
   cmSystemTools::ReplaceString(ret, "\"", """);
   cmSystemTools::ReplaceString(ret, "<", "<");
@@ -2245,7 +2280,7 @@ std::string cmLocalVisualStudio7Generator
 std::string cmLocalVisualStudio7Generator
 ::ConvertToXMLOutputPathSingle(const char* path)
 {
-  std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
+  std::string ret = this->ConvertToOutputFormat(path, SHELL);
   cmSystemTools::ReplaceString(ret, "\"", "");
   cmSystemTools::ReplaceString(ret, "&", "&");
   cmSystemTools::ReplaceString(ret, "<", "<");
@@ -2265,7 +2300,7 @@ public:
   virtual void StartElement(const std::string& name, const char** atts)
     {
       // once the GUID is found do nothing
-      if(this->GUID.size())
+      if(!this->GUID.empty())
         {
         return;
         }
@@ -2312,12 +2347,9 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
 {
   cmVS7XMLParser parser;
   parser.ParseFile(path);
-  // if we can not find a GUID then create one
-  if(parser.GUID.size() == 0)
+  // if we can not find a GUID then we will generate one later
+  if(parser.GUID.empty())
     {
-    cmGlobalVisualStudio7Generator* gg =
-      static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
-    gg->CreateGUID(name);
     return;
     }
   std::string guidStoreName = name;
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 43f3af9..bc05a06 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -35,9 +35,7 @@ class cmLocalVisualStudio7Generator : public cmLocalVisualStudioGenerator
 {
 public:
   ///! Set cache only and recurse to false by default.
-  cmLocalVisualStudio7Generator(cmGlobalGenerator* gg,
-                                cmLocalGenerator* parent,
-                                cmState::Snapshot snapshot);
+  cmLocalVisualStudio7Generator(cmGlobalGenerator* gg, cmMakefile* mf);
 
   virtual ~cmLocalVisualStudio7Generator();
 
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index ca72939..c0072de 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -19,10 +19,8 @@
 
 //----------------------------------------------------------------------------
 cmLocalVisualStudioGenerator
-::cmLocalVisualStudioGenerator(cmGlobalGenerator* gg,
-                               cmLocalGenerator* parent,
-                               cmState::Snapshot snapshot)
-  : cmLocalGenerator(gg, parent, snapshot)
+::cmLocalVisualStudioGenerator(cmGlobalGenerator* gg, cmMakefile* mf)
+  : cmLocalGenerator(gg, mf)
 {
 }
 
@@ -57,7 +55,7 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames(
     cmSourceFile const* sf = si->first;
     std::string objectNameLower = cmSystemTools::LowerCase(
       cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
-    objectNameLower += ".obj";
+    objectNameLower += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
     counts[objectNameLower] += 1;
     }
 
@@ -70,7 +68,7 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames(
     cmSourceFile const* sf = si->first;
     std::string objectName =
       cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
-    objectName += ".obj";
+    objectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
     if(counts[cmSystemTools::LowerCase(objectName)] > 1)
       {
       const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf);
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index d414651..071bfb3 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -31,9 +31,7 @@ class cmCustomCommandGenerator;
 class cmLocalVisualStudioGenerator : public cmLocalGenerator
 {
 public:
-  cmLocalVisualStudioGenerator(cmGlobalGenerator* gg,
-                               cmLocalGenerator* parent,
-                               cmState::Snapshot snapshot);
+  cmLocalVisualStudioGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
   virtual ~cmLocalVisualStudioGenerator();
 
   /** Construct a script from the given list of command lines.  */
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
index 804dd7d..b19112d 100644
--- a/Source/cmLocalXCodeGenerator.cxx
+++ b/Source/cmLocalXCodeGenerator.cxx
@@ -16,9 +16,8 @@
 
 //----------------------------------------------------------------------------
 cmLocalXCodeGenerator::cmLocalXCodeGenerator(cmGlobalGenerator* gg,
-                                             cmLocalGenerator* parent,
-                                             cmState::Snapshot snapshot)
-  : cmLocalGenerator(gg, parent, snapshot)
+                                             cmMakefile* mf)
+  : cmLocalGenerator(gg, mf)
 {
   // the global generator does this, so do not
   // put these flags into the language flags
diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h
index 26fff9c..6d0926f 100644
--- a/Source/cmLocalXCodeGenerator.h
+++ b/Source/cmLocalXCodeGenerator.h
@@ -24,8 +24,8 @@ class cmLocalXCodeGenerator : public cmLocalGenerator
 {
 public:
   ///! Set cache only and recurse to false by default.
-  cmLocalXCodeGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent,
-                        cmState::Snapshot snapshot);
+  cmLocalXCodeGenerator(cmGlobalGenerator* gg,
+                        cmMakefile* mf);
 
   virtual ~cmLocalXCodeGenerator();
   virtual std::string GetTargetDirectory(cmTarget const& target) const;
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 7ac4432..e4026b0 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -96,12 +96,9 @@ bool cmMacroHelperCommand::InvokeInitialPass
     return false;
     }
 
-  // Enforce matching logical blocks inside the macro.
-  cmMakefile::LexicalPushPop lexScope(this->Makefile);
-
-  // Push a weak policy scope which restores the policies recorded at
-  // macro creation.
-  cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
+  cmMakefile::MacroPushPop macroScope(this->Makefile,
+                                      this->FilePath,
+                                      this->Policies);
 
   // set the value of argc
   std::ostringstream argcDefStream;
@@ -110,7 +107,7 @@ bool cmMacroHelperCommand::InvokeInitialPass
 
   std::vector<std::string>::const_iterator eit
       = expandedArgs.begin() + (this->Args.size() - 1);
-  std::string expandedArgn = cmJoin(cmRange(eit, expandedArgs.end()), ";");
+  std::string expandedArgn = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
   std::string expandedArgv = cmJoin(expandedArgs, ";");
   std::vector<std::string> variables;
   variables.reserve(this->Args.size() - 1);
@@ -126,10 +123,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
     sprintf(argvName,"${ARGV%i}",j);
     argVs.push_back(argvName);
     }
-  if(!this->Functions.empty())
-    {
-    this->FilePath = this->Functions[0].FilePath;
-    }
   // Invoke all the functions that were collected in the block.
   cmListFileFunction newLFF;
   // for each function
@@ -139,7 +132,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
     newLFF.Arguments.clear();
     newLFF.Arguments.reserve(this->Functions[c].Arguments.size());
     newLFF.Name = this->Functions[c].Name;
-    newLFF.FilePath = this->Functions[c].FilePath;
     newLFF.Line = this->Functions[c].Line;
 
     // for each argument of the current function
@@ -147,10 +139,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
            this->Functions[c].Arguments.begin();
          k != this->Functions[c].Arguments.end(); ++k)
       {
-      // Set the FilePath on the arguments to match the function since it is
-      // not stored and the original values may be freed
-      k->FilePath = this->FilePath.c_str();
-
       cmListFileArgument arg;
       arg.Value = k->Value;
       if(k->Delim != cmListFileArgument::Bracket)
@@ -181,7 +169,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
           }
         }
       arg.Delim = k->Delim;
-      arg.FilePath = k->FilePath;
       arg.Line = k->Line;
       newLFF.Arguments.push_back(arg);
       }
@@ -191,8 +178,7 @@ bool cmMacroHelperCommand::InvokeInitialPass
       {
       // The error message should have already included the call stack
       // so we do not need to report an error here.
-      lexScope.Quiet();
-      polScope.Quiet();
+      macroScope.Quiet();
       inStatus.SetNestedError(true);
       return false;
       }
@@ -225,11 +211,12 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
     // if this is the endmacro for this macro then execute
     if (!this->Depth)
       {
-      mf.AddMacro(this->Args[0].c_str());
+      mf.AppendProperty("MACROS", this->Args[0].c_str());
       // create a new command and add it to cmake
       cmMacroHelperCommand *f = new cmMacroHelperCommand();
       f->Args = this->Args;
       f->Functions = this->Functions;
+      f->FilePath = this->GetStartingContext().FilePath;
       mf.RecordPolicies(f->Policies);
       std::string newName = "_" + this->Args[0];
       mf.GetState()->RenameCommand(this->Args[0], newName);
@@ -259,7 +246,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
   if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endmacro"))
     {
     std::vector<std::string> expandedArguments;
-    mf.ExpandArguments(lff.Arguments, expandedArguments);
+    mf.ExpandArguments(lff.Arguments, expandedArguments,
+                       this->GetStartingContext().FilePath.c_str());
     // if the endmacro has arguments make sure they
     // match the arguments of the macro
     if ((expandedArguments.empty() ||
diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx
index a6d4e58..cbc7e02 100644
--- a/Source/cmMakeDepend.cxx
+++ b/Source/cmMakeDepend.cxx
@@ -49,7 +49,7 @@ void cmMakeDepend::SetMakefile(cmMakefile* makefile)
 
   // Now extract the include file regular expression from the makefile.
   this->IncludeFileRegularExpression.compile(
-    this->Makefile->IncludeFileRegularExpression.c_str());
+    this->Makefile->GetIncludeRegularExpression());
   this->ComplainFileRegularExpression.compile(
     this->Makefile->ComplainFileRegularExpression.c_str());
 
diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h
index 71b97eb..617f1fe 100644
--- a/Source/cmMakeDirectoryCommand.h
+++ b/Source/cmMakeDirectoryCommand.h
@@ -51,12 +51,6 @@ public:
    */
   virtual bool IsScriptable() const { return true; }
 
-  /** This command is kept for compatibility with older CMake versions. */
-  virtual bool IsDiscouraged() const
-    {
-    return true;
-    }
-
   cmTypeMacro(cmMakeDirectoryCommand, cmCommand);
 };
 
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index bdc55f2..cb66a75 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -16,10 +16,11 @@
 #include "cmSourceFileLocation.h"
 #include "cmSystemTools.h"
 #include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
 #include "cmCommands.h"
 #include "cmState.h"
+#include "cmOutputConverter.h"
 #include "cmFunctionBlocker.h"
+#include "cmGeneratorExpressionEvaluationFile.h"
 #include "cmListFileCache.h"
 #include "cmCommandArgumentParserHelper.h"
 #include "cmGeneratorExpression.h"
@@ -29,7 +30,6 @@
 #endif
 #include "cmInstallGenerator.h"
 #include "cmTestGenerator.h"
-#include "cmDefinitions.h"
 #include "cmAlgorithms.h"
 #include "cmake.h"
 #include <stdlib.h> // required for atoi
@@ -42,115 +42,22 @@
 #include <ctype.h> // for isspace
 #include <assert.h>
 
-class cmMakefile::Internals
-{
-public:
-  std::list<cmDefinitions> VarStack;
-  bool IsSourceFileTryCompile;
-
-  void PushDefinitions()
-  {
-    this->VarStack.push_back(cmDefinitions());
-  }
-
-  void InitializeDefinitions(cmMakefile* parent)
-  {
-    this->VarStack.back() =
-        cmDefinitions::MakeClosure(parent->Internal->VarStack.rbegin(),
-                                   parent->Internal->VarStack.rend());
-  }
-
-  const char* GetDefinition(std::string const& name)
-  {
-    return cmDefinitions::Get(name, this->VarStack.rbegin(),
-                                    this->VarStack.rend());
-  }
-
-  bool IsInitialized(std::string const& name)
-  {
-    return cmDefinitions::HasKey(name, this->VarStack.rbegin(),
-                                 this->VarStack.rend());
-  }
-
-  void SetDefinition(std::string const& name, std::string const& value)
-  {
-    this->VarStack.back().Set(name, value.c_str());
-  }
-
-  void RemoveDefinition(std::string const& name)
-  {
-    this->VarStack.back().Set(name, 0);
-  }
-
-  std::vector<std::string> UnusedKeys() const
-  {
-    return this->VarStack.back().UnusedKeys();
-  }
-
-  std::vector<std::string> ClosureKeys() const
-  {
-    return cmDefinitions::ClosureKeys(this->VarStack.rbegin(),
-                                      this->VarStack.rend());
-  }
-
-  void PopDefinitions()
-  {
-    this->VarStack.pop_back();
-  }
-
-  bool RaiseScope(std::string const& var, const char* varDef, cmMakefile* mf)
-  {
-    std::list<cmDefinitions>::reverse_iterator it = this->VarStack.rbegin();
-    assert(it != this->VarStack.rend());
-    ++it;
-    if(it == this->VarStack.rend())
-      {
-      cmLocalGenerator* plg = mf->GetLocalGenerator()->GetParent();
-      if(!plg)
-        {
-        return false;
-        }
-      // Update the definition in the parent directory top scope.  This
-      // directory's scope was initialized by the closure of the parent
-      // scope, so we do not need to localize the definition first.
-      cmMakefile* parent = plg->GetMakefile();
-      if (varDef)
-        {
-        parent->AddDefinition(var, varDef);
-        }
-      else
-        {
-        parent->RemoveDefinition(var);
-        }
-      return true;
-      }
-    // First localize the definition in the current scope.
-    cmDefinitions::Raise(var, this->VarStack.rbegin(), this->VarStack.rend());
-
-    // Now update the definition in the parent scope.
-    it->Set(var, varDef);
-    return true;
-  }
-};
-
 // default is not to be building executables
-cmMakefile::cmMakefile(cmLocalGenerator* localGenerator)
-  : Internal(new Internals),
-    LocalGenerator(localGenerator),
-    StateSnapshot(localGenerator->GetStateSnapshot())
+cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator,
+                       cmState::Snapshot const& snapshot)
+  : GlobalGenerator(globalGenerator),
+    StateSnapshot(snapshot)
 {
-  this->Internal->PushDefinitions();
-  this->Internal->IsSourceFileTryCompile = false;
+  this->IsSourceFileTryCompile = false;
 
   // Initialize these first since AddDefaultDefinitions calls AddDefinition
   this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
   this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars();
 
-  this->GeneratingBuildSystem = false;
   this->SuppressWatches = false;
 
   // Setup the default include file regular expression (match everything).
-  this->IncludeFileRegularExpression = "^.*$";
+  this->SetProperty("INCLUDE_REGULAR_EXPRESSION", "^.*$");
   // Setup the default include complaint regular expression (match nothing).
   this->ComplainFileRegularExpression = "^$";
   // Source and header file extensions that we can handle
@@ -188,12 +95,12 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator)
   this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
   this->cmNamedCurly.compile("^[A-Za-z0-9/_.+-]+{");
 
+  this->StateSnapshot = this->StateSnapshot.GetState()
+      ->CreatePolicyScopeSnapshot(this->StateSnapshot);
+
   // Enter a policy level for this directory.
   this->PushPolicy();
 
-  // Protect the directory-level policies.
-  this->PushPolicyBarrier();
-
   // push empty loop block
   this->PushLoopBlockBarrier();
 
@@ -213,8 +120,6 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator)
   this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$");
 #endif
 
-  this->Properties.SetCMakeInstance(this->GetCMakeInstance());
-
   {
   const char* dir = this->GetCMakeInstance()->GetHomeDirectory();
   this->AddDefinition("CMAKE_SOURCE_DIR", dir);
@@ -236,12 +141,10 @@ cmMakefile::~cmMakefile()
   cmDeleteAll(this->ImportedTargetsOwned);
   cmDeleteAll(this->FinalPassCommands);
   cmDeleteAll(this->FunctionBlockers);
+  cmDeleteAll(this->EvaluationFiles);
+  this->EvaluationFiles.clear();
+
   this->FunctionBlockers.clear();
-  if (this->PolicyStack.size() != 1)
-  {
-    cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
-      " popped properly");
-  }
 }
 
 //----------------------------------------------------------------------------
@@ -249,11 +152,11 @@ void cmMakefile::IssueMessage(cmake::MessageType t,
                               std::string const& text) const
 {
   // Collect context information.
-  if(!this->CallStack.empty())
+  if(!this->ExecutionStatusStack.empty())
     {
     if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
       {
-      this->CallStack.back().Status->SetNestedError(true);
+      this->ExecutionStatusStack.back()->SetNestedError(true);
       }
     this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace());
     }
@@ -262,46 +165,99 @@ void cmMakefile::IssueMessage(cmake::MessageType t,
     cmListFileContext lfc;
     // We are not currently executing a command.  Add whatever context
     // information we have.
-    lfc.FilePath = this->ListFileStack.back();
+    lfc.FilePath = this->GetExecutionFilePath();
 
     if(!this->GetCMakeInstance()->GetIsInTryCompile())
       {
-      lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath,
-                                                   cmLocalGenerator::HOME);
+      cmOutputConverter converter(this->StateSnapshot);
+      lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
       }
     lfc.Line = 0;
     this->GetCMakeInstance()->IssueMessage(t, text, lfc);
     }
 }
 
+cmStringRange cmMakefile::GetIncludeDirectoriesEntries() const
+{
+  return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();
+}
+
+cmBacktraceRange cmMakefile::GetIncludeDirectoriesBacktraces() const
+{
+  return this->StateSnapshot.GetDirectory()
+      .GetIncludeDirectoriesEntryBacktraces();
+}
+
+cmStringRange cmMakefile::GetCompileOptionsEntries() const
+{
+  return this->StateSnapshot.GetDirectory().GetCompileOptionsEntries();
+}
+
+cmBacktraceRange cmMakefile::GetCompileOptionsBacktraces() const
+{
+  return this->StateSnapshot.GetDirectory().GetCompileOptionsEntryBacktraces();
+}
+
+cmStringRange cmMakefile::GetCompileDefinitionsEntries() const
+{
+  return this->StateSnapshot.GetDirectory().GetCompileDefinitionsEntries();
+}
+
+cmBacktraceRange cmMakefile::GetCompileDefinitionsBacktraces() const
+{
+  return this->StateSnapshot.GetDirectory()
+      .GetCompileDefinitionsEntryBacktraces();
+}
+
 //----------------------------------------------------------------------------
 cmListFileBacktrace cmMakefile::GetBacktrace() const
 {
-  cmListFileBacktrace backtrace(this->GetLocalGenerator());
-  for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
-      i != this->CallStack.rend(); ++i)
+  cmListFileBacktrace backtrace;
+  if (!this->ContextStack.empty())
     {
-    backtrace.Append(*i->Context);
+    backtrace = cmListFileBacktrace(this->StateSnapshot,
+                                    *this->ContextStack.back());
     }
   return backtrace;
 }
 
 //----------------------------------------------------------------------------
+cmListFileBacktrace
+cmMakefile::GetBacktrace(cmCommandContext const& cc) const
+{
+  cmState::Snapshot snp = this->StateSnapshot;
+  return cmListFileBacktrace(snp, cc);
+}
+
+//----------------------------------------------------------------------------
 cmListFileContext cmMakefile::GetExecutionContext() const
 {
-  return *this->CallStack.back().Context;
+  return cmListFileContext::FromCommandContext(
+        *this->ContextStack.back(),
+        this->StateSnapshot.GetExecutionListFile());
 }
 
 //----------------------------------------------------------------------------
 void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
 {
   std::ostringstream msg;
-  msg << lff.FilePath << "(" << lff.Line << "):  ";
+  msg << this->GetExecutionFilePath() << "(" << lff.Line << "):  ";
   msg << lff.Name << "(";
+  bool expand = this->GetCMakeInstance()->GetTraceExpand();
+  std::string temp;
   for(std::vector<cmListFileArgument>::const_iterator i =
         lff.Arguments.begin(); i != lff.Arguments.end(); ++i)
     {
-    msg << i->Value;
+    if (expand)
+      {
+      temp = i->Value;
+      this->ExpandVariablesInString(temp);
+      msg << temp;
+      }
+    else
+      {
+      msg << i->Value;
+      }
     msg << " ";
     }
   msg << ")";
@@ -397,12 +353,12 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
 class cmMakefile::IncludeScope
 {
 public:
-  IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope);
+  IncludeScope(cmMakefile* mf, std::string const& filenametoread,
+               bool noPolicyScope);
   ~IncludeScope();
   void Quiet() { this->ReportError = false; }
 private:
   cmMakefile* Makefile;
-  const char* File;
   bool NoPolicyScope;
   bool CheckCMP0011;
   bool ReportError;
@@ -410,11 +366,20 @@ private:
 };
 
 //----------------------------------------------------------------------------
-cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
+cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf,
+                                       std::string const& filenametoread,
                                        bool noPolicyScope):
-  Makefile(mf), File(fname), NoPolicyScope(noPolicyScope),
+  Makefile(mf), NoPolicyScope(noPolicyScope),
   CheckCMP0011(false), ReportError(true)
 {
+  this->Makefile->PushFunctionBlockerBarrier();
+
+  this->Makefile->StateSnapshot =
+      this->Makefile->GetState()->CreateCallStackSnapshot(
+        this->Makefile->StateSnapshot,
+        this->Makefile->ContextStack.back()->Name,
+        this->Makefile->ContextStack.back()->Line,
+        filenametoread);
   if(!this->NoPolicyScope)
     {
     // Check CMP0011 to determine the policy scope type.
@@ -443,24 +408,19 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
         break;
       }
     }
-
-  // The included file cannot pop our policy scope.
-  this->Makefile->PushPolicyBarrier();
 }
 
 //----------------------------------------------------------------------------
 cmMakefile::IncludeScope::~IncludeScope()
 {
-  // Enforce matching policy scopes inside the included file.
-  this->Makefile->PopPolicyBarrier(this->ReportError);
-
   if(!this->NoPolicyScope)
     {
     // If we need to enforce policy CMP0011 then the top entry is the
     // one we pushed above.  If the entry is empty, then the included
     // script did not set any policies that might affect the includer so
     // we do not need to enforce the policy.
-    if(this->CheckCMP0011 && this->Makefile->PolicyStack.back().IsEmpty())
+    if(this->CheckCMP0011
+       && !this->Makefile->StateSnapshot.HasDefinedPolicyCMP0011())
       {
       this->CheckCMP0011 = false;
       }
@@ -475,6 +435,9 @@ cmMakefile::IncludeScope::~IncludeScope()
       this->EnforceCMP0011();
       }
     }
+  this->Makefile->PopPolicyBarrier(this->ReportError);
+
+  this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
 }
 
 //----------------------------------------------------------------------------
@@ -489,7 +452,8 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
       {
       std::ostringstream w;
       w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0011) << "\n"
-        << "The included script\n  " << this->File << "\n"
+        << "The included script\n  "
+        << this->Makefile->GetExecutionFilePath() << "\n"
         << "affects policy settings.  "
         << "CMake is implying the NO_POLICY_SCOPE option for compatibility, "
         << "so the effects are applied to the including context.";
@@ -501,7 +465,8 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
       {
       std::ostringstream e;
       e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
-        << "The included script\n  " << this->File << "\n"
+        << "The included script\n  "
+        << this->Makefile->GetExecutionFilePath() << "\n"
         << "affects policy settings, so it requires this policy to be set.";
       this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
       }
@@ -515,38 +480,116 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
     }
 }
 
-bool cmMakefile::ProcessBuildsystemFile(const char* listfile)
+class cmParseFileScope
 {
-  this->AddDefinition("CMAKE_PARENT_LIST_FILE", listfile);
-  std::string curSrc = this->GetCurrentSourceDirectory();
-  return this->ReadListFile(listfile, true,
-                            curSrc == this->GetHomeDirectory());
-}
+public:
+  cmParseFileScope(cmMakefile* mf)
+    : Makefile(mf)
+  {
+    this->Makefile->ContextStack.push_back(&this->Context);
+  }
 
-bool cmMakefile::ReadDependentFile(const char* listfile, bool noPolicyScope)
+  ~cmParseFileScope()
+  {
+    this->Makefile->ContextStack.pop_back();
+  }
+
+private:
+  cmMakefile* Makefile;
+  cmCommandContext Context;
+};
+
+bool cmMakefile::ReadDependentFile(const char* filename, bool noPolicyScope)
 {
   this->AddDefinition("CMAKE_PARENT_LIST_FILE",
                       this->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
-  bool result = this->ReadListFile(listfile, noPolicyScope, false);
-  this->ListFileStack.pop_back();
-  return result;
+  std::string filenametoread =
+    cmSystemTools::CollapseFullPath(filename,
+                                    this->GetCurrentSourceDirectory());
+
+  IncludeScope incScope(this, filenametoread, noPolicyScope);
+
+  cmListFile listFile;
+  {
+  cmParseFileScope pfs(this);
+  if (!listFile.ParseFile(filenametoread.c_str(), false, this))
+    {
+    return false;
+    }
+  }
+
+  this->ReadListFile(listFile, filenametoread);
+  if(cmSystemTools::GetFatalErrorOccured())
+    {
+    incScope.Quiet();
+    }
+  return true;
 }
 
-bool cmMakefile::ReadListFile(const char* listfile)
+class cmMakefile::ListFileScope
 {
-  bool result = this->ReadListFile(listfile, true, false);
-  this->ListFileStack.pop_back();
-  return result;
-}
+public:
+  ListFileScope(cmMakefile* mf, std::string const& filenametoread)
+    : Makefile(mf), ReportError(true)
+  {
+    long line = 0;
+    std::string name;
+    if (!this->Makefile->ContextStack.empty())
+      {
+      line = this->Makefile->ContextStack.back()->Line;
+      name = this->Makefile->ContextStack.back()->Name;
+      }
+    this->Makefile->StateSnapshot =
+        this->Makefile->GetState()->CreateInlineListFileSnapshot(
+          this->Makefile->StateSnapshot, name, line, filenametoread);
+    assert(this->Makefile->StateSnapshot.IsValid());
+
+    this->Makefile->PushFunctionBlockerBarrier();
+  }
 
-bool cmMakefile::ReadListFile(const char* listfile,
-                              bool noPolicyScope,
-                              bool requireProjectCommand)
+  ~ListFileScope()
+  {
+    this->Makefile->PopPolicyBarrier(this->ReportError);
+    this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
+  }
+
+  void Quiet() { this->ReportError = false; }
+private:
+  cmMakefile* Makefile;
+  bool ReportError;
+};
+
+bool cmMakefile::ReadListFile(const char* filename)
 {
   std::string filenametoread =
-    cmSystemTools::CollapseFullPath(listfile,
+    cmSystemTools::CollapseFullPath(filename,
                                     this->GetCurrentSourceDirectory());
 
+  ListFileScope scope(this, filenametoread);
+
+  cmListFile listFile;
+  {
+  cmParseFileScope pfs(this);
+  if (!listFile.ParseFile(filenametoread.c_str(), false, this))
+    {
+    return false;
+    }
+  }
+
+  this->ReadListFile(listFile, filenametoread);
+  if(cmSystemTools::GetFatalErrorOccured())
+    {
+    scope.Quiet();
+    }
+  return true;
+}
+
+void cmMakefile::ReadListFile(cmListFile const& listFile,
+                              std::string const& filenametoread)
+{
+  // add this list file to the list of dependencies
+  this->ListFiles.push_back(filenametoread);
+
   std::string currentParentFile
       = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
   std::string currentFile
@@ -560,55 +603,14 @@ bool cmMakefile::ReadListFile(const char* listfile,
   this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
   this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
 
-  this->ListFileStack.push_back(filenametoread);
-
-  bool res = this->ReadListFileInternal(filenametoread.c_str(),
-                                        noPolicyScope, requireProjectCommand);
-
-  this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
-  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
-  this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
-                      cmSystemTools::GetFilenamePath(currentFile).c_str());
-  this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
-  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
-  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
-
-  if (res)
-    {
-    this->CheckForUnusedVariables();
-    }
-
-  return res;
-}
-
-bool cmMakefile::ReadListFileInternal(const char* filenametoread,
-                                      bool noPolicyScope,
-                                      bool requireProjectCommand)
-{
-  cmListFile cacheFile;
-  if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
-    {
-    return false;
-    }
-  // add this list file to the list of dependencies
-  this->ListFiles.push_back( filenametoread);
-
-  // Enforce balanced blocks (if/endif, function/endfunction, etc.).
-  {
-  LexicalPushPop lexScope(this);
-  IncludeScope incScope(this, filenametoread, noPolicyScope);
-
   // Run the parsed commands.
-  const size_t numberFunctions = cacheFile.Functions.size();
+  const size_t numberFunctions = listFile.Functions.size();
   for(size_t i =0; i < numberFunctions; ++i)
     {
     cmExecutionStatus status;
-    this->ExecuteCommand(cacheFile.Functions[i],status);
+    this->ExecuteCommand(listFile.Functions[i],status);
     if(cmSystemTools::GetFatalErrorOccured())
       {
-      // Exit early due to error.
-      lexScope.Quiet();
-      incScope.Quiet();
       break;
       }
     if(status.GetReturnInvoked())
@@ -617,16 +619,15 @@ bool cmMakefile::ReadListFileInternal(const char* filenametoread,
       break;
       }
     }
-  }
-
-  // If this is the directory-level CMakeLists.txt file then perform
-  // some extra checks.
-  if(this->ListFileStack.size() == 1)
-    {
-    this->EnforceDirectoryLevelRules();
-    }
+  this->CheckForUnusedVariables();
 
-  return true;
+  this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
+  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
+  this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
+                      cmSystemTools::GetFilenamePath(currentFile).c_str());
+  this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
+  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
+  this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
 }
 
 //----------------------------------------------------------------------------
@@ -668,6 +669,23 @@ void cmMakefile::EnforceDirectoryLevelRules() const
     }
 }
 
+void cmMakefile::AddEvaluationFile(const std::string& inputFile,
+                     cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
+                     cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
+                     bool inputIsContent)
+{
+  this->EvaluationFiles.push_back(
+              new cmGeneratorExpressionEvaluationFile(inputFile, outputName,
+                                                      condition,
+                                                      inputIsContent));
+}
+
+std::vector<cmGeneratorExpressionEvaluationFile*>
+cmMakefile::GetEvaluationFiles() const
+{
+  return this->EvaluationFiles;
+}
+
 namespace
 {
   struct file_not_persistent
@@ -1096,15 +1114,16 @@ cmMakefile::AddCustomCommandOldStyle(const std::string& target,
 }
 
 //----------------------------------------------------------------------------
-void cmMakefile::AddUtilityCommand(const std::string& utilityName,
-                                   bool excludeFromAll,
-                                   const std::vector<std::string>& depends,
-                                   const char* workingDirectory,
-                                   const char* command,
-                                   const char* arg1,
-                                   const char* arg2,
-                                   const char* arg3,
-                                   const char* arg4)
+cmTarget*
+cmMakefile::AddUtilityCommand(const std::string& utilityName,
+                              bool excludeFromAll,
+                              const std::vector<std::string>& depends,
+                              const char* workingDirectory,
+                              const char* command,
+                              const char* arg1,
+                              const char* arg2,
+                              const char* arg3,
+                              const char* arg4)
 {
   // Construct the command line for the custom command.
   cmCustomCommandLine commandLine;
@@ -1129,8 +1148,8 @@ void cmMakefile::AddUtilityCommand(const std::string& utilityName,
   commandLines.push_back(commandLine);
 
   // Call the real signature of this method.
-  this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
-                          depends, commandLines);
+  return this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
+                                 depends, commandLines);
 }
 
 //----------------------------------------------------------------------------
@@ -1361,7 +1380,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
           std::remove(defs.begin(), defs.end(), define);
       std::vector<std::string>::const_iterator defBegin =
           defs.begin();
-      std::string ndefs = cmJoin(cmRange(defBegin, defEnd), ";");
+      std::string ndefs = cmJoin(cmMakeRange(defBegin, defEnd), ";");
 
       // Store the new list.
       this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
@@ -1451,61 +1470,15 @@ void cmMakefile::AddLinkLibrary(const std::string& lib)
   this->AddLinkLibrary(lib,cmTarget::GENERAL);
 }
 
-void cmMakefile::AddLinkDirectory(const std::string& dir)
-{
-  // Don't add a link directory that is already present.  Yes, this
-  // linear search results in n^2 behavior, but n won't be getting
-  // much bigger than 20.  We cannot use a set because of order
-  // dependency of the link search path.
-
-  if(dir.empty())
-    {
-    return;
-    }
-  std::string newdir = dir;
-  // remove trailing slashes
-  if(*dir.rbegin() == '/')
-    {
-    newdir = dir.substr(0, dir.size()-1);
-    }
-  if(std::find(this->LinkDirectories.begin(),
-               this->LinkDirectories.end(), newdir)
-      == this->LinkDirectories.end())
-    {
-    this->LinkDirectories.push_back(dir);
-    }
-}
-
-void cmMakefile::InitializeFromParent()
+void cmMakefile::InitializeFromParent(cmMakefile* parent)
 {
-  cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
-
-  // Initialize definitions with the closure of the parent scope.
-  this->Internal->InitializeDefinitions(parent);
+  this->StateSnapshot.InitializeFromParent();
 
   this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR",
                       this->GetCurrentSourceDirectory());
   this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
                       this->GetCurrentBinaryDirectory());
 
-  const std::vector<cmValueWithOrigin>& parentIncludes =
-                                        parent->GetIncludeDirectoriesEntries();
-  this->IncludeDirectoriesEntries.insert(this->IncludeDirectoriesEntries.end(),
-                                         parentIncludes.begin(),
-                                         parentIncludes.end());
-
-  const std::vector<cmValueWithOrigin>& parentOptions =
-                                        parent->GetCompileOptionsEntries();
-  this->CompileOptionsEntries.insert(this->CompileOptionsEntries.end(),
-                                     parentOptions.begin(),
-                                     parentOptions.end());
-
-  const std::vector<cmValueWithOrigin>& parentDefines =
-                                      parent->GetCompileDefinitionsEntries();
-  this->CompileDefinitionsEntries.insert(this->CompileDefinitionsEntries.end(),
-                                         parentDefines.begin(),
-                                         parentDefines.end());
-
   this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
 
   // define flags
@@ -1536,27 +1509,180 @@ void cmMakefile::InitializeFromParent()
       }
     }
 
-  // link libraries
-  this->LinkLibraries = parent->LinkLibraries;
+  // link libraries
+  this->LinkLibraries = parent->LinkLibraries;
+
+  // link directories
+  this->SetProperty("LINK_DIRECTORIES",
+                    parent->GetProperty("LINK_DIRECTORIES"));
+
+  // the initial project name
+  this->SetProjectName(parent->GetProjectName());
+
+  // Copy include regular expressions.
+  this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
+
+  // Imported targets.
+  this->ImportedTargets = parent->ImportedTargets;
+}
+
+void cmMakefile::PushFunctionScope(std::string const& fileName,
+                                   const cmPolicies::PolicyMap& pm)
+{
+  this->StateSnapshot =
+      this->GetState()->CreateFunctionCallSnapshot(
+        this->StateSnapshot,
+        this->ContextStack.back()->Name, this->ContextStack.back()->Line,
+        fileName);
+  assert(this->StateSnapshot.IsValid());
+
+  this->PushLoopBlockBarrier();
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+  this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope();
+#endif
+
+  this->PushFunctionBlockerBarrier();
+
+  this->PushPolicy(true, pm);
+}
+
+void cmMakefile::PopFunctionScope(bool reportError)
+{
+  this->PopPolicy();
+
+  this->PopPolicyBarrier(reportError);
+
+  this->PopFunctionBlockerBarrier(reportError);
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+  this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope();
+#endif
+
+  this->PopLoopBlockBarrier();
+
+  this->CheckForUnusedVariables();
+}
+
+void cmMakefile::PushMacroScope(std::string const& fileName,
+                                const cmPolicies::PolicyMap& pm)
+{
+  this->StateSnapshot =
+      this->GetState()->CreateMacroCallSnapshot(
+        this->StateSnapshot,
+        this->ContextStack.back()->Name, this->ContextStack.back()->Line,
+        fileName);
+  assert(this->StateSnapshot.IsValid());
+
+  this->PushFunctionBlockerBarrier();
+
+  this->PushPolicy(true, pm);
+}
+
+void cmMakefile::PopMacroScope(bool reportError)
+{
+  this->PopPolicy();
+  this->PopPolicyBarrier(reportError);
+
+  this->PopFunctionBlockerBarrier(reportError);
+}
+
+bool cmMakefile::IsRootMakefile() const
+{
+  return !this->StateSnapshot.GetBuildsystemDirectoryParent().IsValid();
+}
+
+class cmMakefile::BuildsystemFileScope
+{
+public:
+  BuildsystemFileScope(cmMakefile* mf)
+    : Makefile(mf), ReportError(true)
+  {
+    std::string currentStart =
+        this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource();
+    currentStart += "/CMakeLists.txt";
+    this->Makefile->StateSnapshot.SetListFile(currentStart);
+    this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
+        ->CreatePolicyScopeSnapshot(this->Makefile->StateSnapshot);
+    this->Makefile->PushFunctionBlockerBarrier();
+
+    this->GG = mf->GetGlobalGenerator();
+    this->CurrentMakefile = this->GG->GetCurrentMakefile();
+    this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot();
+    this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
+    this->GG->SetCurrentMakefile(mf);
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+    this->GG->GetFileLockPool().PushFileScope();
+#endif
+  }
+
+  ~BuildsystemFileScope()
+  {
+    this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
+    this->Makefile->PopPolicyBarrier(this->ReportError);
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+    this->GG->GetFileLockPool().PopFileScope();
+#endif
+    this->GG->SetCurrentMakefile(this->CurrentMakefile);
+    this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
+  }
+
+  void Quiet() { this->ReportError = false; }
+private:
+  cmMakefile* Makefile;
+  cmGlobalGenerator* GG;
+  cmMakefile* CurrentMakefile;
+  cmState::Snapshot Snapshot;
+  bool ReportError;
+};
+
+//----------------------------------------------------------------------------
+void cmMakefile::Configure()
+{
+  BuildsystemFileScope scope(this);
 
-  // link directories
-  this->LinkDirectories = parent->LinkDirectories;
+  // make sure the CMakeFiles dir is there
+  std::string filesDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
+  filesDir += cmake::GetCMakeFilesDirectory();
+  cmSystemTools::MakeDirectory(filesDir.c_str());
 
-  // the initial project name
-  this->ProjectName = parent->ProjectName;
+  std::string currentStart =
+      this->StateSnapshot.GetDirectory().GetCurrentSource();
+  currentStart += "/CMakeLists.txt";
+  assert(cmSystemTools::FileExists(currentStart.c_str(), true));
+  this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str());
 
-  // Copy include regular expressions.
-  this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
-  this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
+  cmListFile listFile;
+  {
+  cmParseFileScope pfs(this);
+  if (!listFile.ParseFile(currentStart.c_str(), this->IsRootMakefile(), this))
+    {
+    return;
+    }
+  }
+  this->ReadListFile(listFile, currentStart);
+  if(cmSystemTools::GetFatalErrorOccured())
+    {
+    scope.Quiet();
+    }
 
-  // Imported targets.
-  this->ImportedTargets = parent->ImportedTargets;
+   // at the end handle any old style subdirs
+  std::vector<cmMakefile*> subdirs = this->UnConfiguredDirectories;
+
+  // for each subdir recurse
+  std::vector<cmMakefile*>::iterator sdi = subdirs.begin();
+  for (; sdi != subdirs.end(); ++sdi)
+    {
+    this->ConfigureSubDirectory(*sdi);
+    }
+
+  this->AddCMakeDependFilesFromUser();
 }
 
-void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
+void cmMakefile::ConfigureSubDirectory(cmMakefile *mf)
 {
-  lg2->GetMakefile()->InitializeFromParent();
-  std::string currentStart = lg2->GetMakefile()->GetCurrentSourceDirectory();
+  mf->InitializeFromParent(this);
+  std::string currentStart = mf->GetCurrentSourceDirectory();
   if (this->GetCMakeInstance()->GetDebugOutput())
     {
     std::string msg="   Entering             ";
@@ -1594,11 +1720,11 @@ void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
         // NEW behavior prints the error.
         this->IssueMessage(cmake::FATAL_ERROR, e.str());
       }
-    lg2->SetConfiguredCMP0014(true);
     return;
     }
   // finally configure the subdir
-  lg2->Configure();
+  mf->Configure();
+
   if (this->GetCMakeInstance()->GetDebugOutput())
     {
     std::string msg="   Returning to         ";
@@ -1619,50 +1745,60 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
     }
 
   cmState::Snapshot newSnapshot = this->GetState()
-      ->CreateSnapshot(this->StateSnapshot);
+      ->CreateBuildsystemDirectorySnapshot(this->StateSnapshot,
+                                           this->ContextStack.back()->Name,
+                                           this->ContextStack.back()->Line);
 
-  // create a new local generator and set its parent
-  cmLocalGenerator *lg2 = this->GetGlobalGenerator()
-        ->MakeLocalGenerator(newSnapshot, this->LocalGenerator);
-  this->GetGlobalGenerator()->AddLocalGenerator(lg2);
+  cmMakefile* subMf = new cmMakefile(this->GlobalGenerator, newSnapshot);
+  this->GetGlobalGenerator()->AddMakefile(subMf);
 
   // set the subdirs start dirs
-  lg2->GetMakefile()->SetCurrentSourceDirectory(srcPath);
-  lg2->GetMakefile()->SetCurrentBinaryDirectory(binPath);
+  subMf->SetCurrentSourceDirectory(srcPath);
+  subMf->SetCurrentBinaryDirectory(binPath);
   if(excludeFromAll)
     {
-    lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
+    subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
     }
 
   if (immediate)
     {
-    this->ConfigureSubDirectory(lg2);
+    this->ConfigureSubDirectory(subMf);
+    }
+  else
+    {
+    this->UnConfiguredDirectories.push_back(subMf);
     }
 }
 
 void cmMakefile::SetCurrentSourceDirectory(const std::string& dir)
 {
-  this->StateSnapshot.SetCurrentSourceDirectory(dir);
+  this->StateSnapshot.GetDirectory().SetCurrentSource(dir);
   this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR",
-                      this->StateSnapshot.GetCurrentSourceDirectory());
+                      this->StateSnapshot.GetDirectory().GetCurrentSource());
 }
 
 const char* cmMakefile::GetCurrentSourceDirectory() const
 {
-  return this->StateSnapshot.GetCurrentSourceDirectory();
+  return this->StateSnapshot.GetDirectory().GetCurrentSource();
 }
 
 void cmMakefile::SetCurrentBinaryDirectory(const std::string& dir)
 {
-  this->StateSnapshot.SetCurrentBinaryDirectory(dir);
-  const char* binDir = this->StateSnapshot.GetCurrentBinaryDirectory();
+  this->StateSnapshot.GetDirectory().SetCurrentBinary(dir);
+  const char* binDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
   cmSystemTools::MakeDirectory(binDir);
   this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", binDir);
 }
 
 const char* cmMakefile::GetCurrentBinaryDirectory() const
 {
-  return this->StateSnapshot.GetCurrentBinaryDirectory();
+  return this->StateSnapshot.GetDirectory().GetCurrentBinary();
+}
+
+void cmMakefile::AddGeneratorTarget(cmTarget* t, cmGeneratorTarget* gt)
+{
+  this->GeneratorTargets[t] = gt;
+  this->GetGlobalGenerator()->AddGeneratorTarget(t, gt);
 }
 
 //----------------------------------------------------------------------------
@@ -1674,20 +1810,25 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs,
     return;
     }
 
-  std::vector<cmValueWithOrigin>::iterator position =
-                              before ? this->IncludeDirectoriesEntries.begin()
-                                    : this->IncludeDirectoriesEntries.end();
-
   cmListFileBacktrace lfbt = this->GetBacktrace();
-  cmValueWithOrigin entry(cmJoin(incs, ";"), lfbt);
-  this->IncludeDirectoriesEntries.insert(position, entry);
+  std::string entryString = cmJoin(incs, ";");
+  if (before)
+    {
+    this->StateSnapshot.GetDirectory()
+          .PrependIncludeDirectoriesEntry(entryString, lfbt);
+    }
+  else
+    {
+    this->StateSnapshot.GetDirectory()
+          .AppendIncludeDirectoriesEntry(entryString, lfbt);
+    }
 
   // Property on each target:
   for (cmTargets::iterator l = this->Targets.begin();
        l != this->Targets.end(); ++l)
     {
     cmTarget &t = l->second;
-    t.InsertInclude(entry, before);
+    t.InsertInclude(entryString, lfbt, before);
     }
 }
 
@@ -1716,7 +1857,7 @@ void cmMakefile::AddDefinition(const std::string& name, const char* value)
     {
     this->LogUnused("changing definition", name);
     }
-  this->Internal->SetDefinition(name, value);
+  this->StateSnapshot.SetDefinition(name, value);
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
   cmVariableWatch* vv = this->GetVariableWatch();
@@ -1779,7 +1920,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
   this->GetState()->AddCacheEntry(name, haveVal ? val.c_str() : 0,
                                           doc, type);
   // if there was a definition then remove it
-  this->Internal->RemoveDefinition(name);
+  this->StateSnapshot.RemoveDefinition(name);
 }
 
 
@@ -1789,7 +1930,9 @@ void cmMakefile::AddDefinition(const std::string& name, bool value)
     {
     this->LogUnused("changing definition", name);
     }
-  this->Internal->SetDefinition(name, value ? "ON" : "OFF");
+
+  this->StateSnapshot.SetDefinition(name, value ? "ON" : "OFF");
+
 #ifdef CMAKE_BUILD_WITH_CMAKE
   cmVariableWatch* vv = this->GetVariableWatch();
   if ( vv )
@@ -1806,7 +1949,7 @@ void cmMakefile::CheckForUnusedVariables() const
     {
     return;
     }
-  const std::vector<std::string>& unused = this->Internal->UnusedKeys();
+  const std::vector<std::string>& unused = this->StateSnapshot.UnusedKeys();
   std::vector<std::string>::const_iterator it = unused.begin();
   for (; it != unused.end(); ++it)
     {
@@ -1816,12 +1959,12 @@ void cmMakefile::CheckForUnusedVariables() const
 
 void cmMakefile::MarkVariableAsUsed(const std::string& var)
 {
-  this->Internal->GetDefinition(var);
+  this->StateSnapshot.GetDefinition(var);
 }
 
 bool cmMakefile::VariableInitialized(const std::string& var) const
 {
-  return this->Internal->IsInitialized(var);
+  return this->StateSnapshot.IsInitialized(var);
 }
 
 void cmMakefile::LogUnused(const char* reason,
@@ -1831,7 +1974,7 @@ void cmMakefile::LogUnused(const char* reason,
     {
     std::string path;
     cmListFileContext lfc;
-    if (!this->CallStack.empty())
+    if (!this->ExecutionStatusStack.empty())
       {
       lfc = this->GetExecutionContext();
       path = lfc.FilePath;
@@ -1843,8 +1986,8 @@ void cmMakefile::LogUnused(const char* reason,
       lfc.FilePath = path;
       lfc.Line = 0;
       }
-    lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath,
-                                                 cmLocalGenerator::HOME);
+    cmOutputConverter converter(this->StateSnapshot);
+    lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
 
     if (this->CheckSystemVars ||
         cmSystemTools::IsSubDirectory(path,
@@ -1869,7 +2012,7 @@ void cmMakefile::RemoveDefinition(const std::string& name)
     {
     this->LogUnused("unsetting", name);
     }
-  this->Internal->RemoveDefinition(name);
+  this->StateSnapshot.RemoveDefinition(name);
 #ifdef CMAKE_BUILD_WITH_CMAKE
   cmVariableWatch* vv = this->GetVariableWatch();
   if ( vv )
@@ -1885,11 +2028,15 @@ void cmMakefile::RemoveCacheDefinition(const std::string& name)
   this->GetState()->RemoveCacheEntry(name);
 }
 
-void cmMakefile::SetProjectName(const char* p)
+void cmMakefile::SetProjectName(std::string const& p)
 {
-  this->ProjectName = p;
+  this->StateSnapshot.SetProjectName(p);
 }
 
+std::string cmMakefile::GetProjectName() const
+{
+  return this->StateSnapshot.GetProjectName();
+}
 
 void cmMakefile::AddGlobalLinkInformation(const std::string& name,
                                           cmTarget& target)
@@ -1903,11 +2050,27 @@ void cmMakefile::AddGlobalLinkInformation(const std::string& name,
       return;
     default:;
     }
-  std::vector<std::string>::iterator j;
-  for(j = this->LinkDirectories.begin();
-      j != this->LinkDirectories.end(); ++j)
+  if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES"))
     {
-    target.AddLinkDirectory(*j);
+    std::vector<std::string> linkDirs;
+    cmSystemTools::ExpandListArgument(linkDirsProp, linkDirs);
+
+    for(std::vector<std::string>::iterator j = linkDirs.begin();
+        j != linkDirs.end(); ++j)
+      {
+      std::string newdir = *j;
+      // remove trailing slashes
+      if(*j->rbegin() == '/')
+        {
+        newdir = j->substr(0, j->size()-1);
+        }
+      if(std::find(this->LinkDirectories.begin(),
+                   this->LinkDirectories.end(), newdir)
+          == this->LinkDirectories.end())
+        {
+        target.AddLinkDirectory(*j);
+        }
+      }
     }
   target.MergeLinkLibraries( *this, name, this->LinkLibraries );
 }
@@ -2116,25 +2279,10 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
     return;
     }
   // build the whole source group path
-  const char* fullname = sg->GetFullName();
-  cmGlobalGenerator* gg = this->GetGlobalGenerator();
-  if(strlen(fullname))
-    {
-    std::string guidName = "SG_Filter_";
-    guidName += fullname;
-    gg->CreateGUID(guidName);
-    }
   for(++i; i<=lastElement; ++i)
     {
     sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName()));
     sg = sg->LookupChild(name[i].c_str());
-    fullname = sg->GetFullName();
-    if(strlen(fullname))
-      {
-      std::string guidName = "SG_Filter_";
-      guidName += fullname;
-      gg->CreateGUID(guidName);
-      }
     }
 
   sg->SetGroupRegex(regex);
@@ -2177,7 +2325,8 @@ void cmMakefile::ExpandVariablesCMP0019()
        l != this->Targets.end(); ++l)
     {
     cmTarget &t = l->second;
-    if (t.GetType() == cmTarget::INTERFACE_LIBRARY)
+    if (t.GetType() == cmTarget::INTERFACE_LIBRARY
+        || t.GetType() == cmTarget::GLOBAL_TARGET)
       {
       continue;
       }
@@ -2197,19 +2346,19 @@ void cmMakefile::ExpandVariablesCMP0019()
       }
     }
 
-  for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
-      d != this->LinkDirectories.end(); ++d)
+  if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES"))
     {
-    if(mightExpandVariablesCMP0019(d->c_str()))
+    if(mightExpandVariablesCMP0019(linkDirsProp))
       {
-      std::string orig = *d;
-      this->ExpandVariablesInString(*d, true, true);
-      if(pol == cmPolicies::WARN && *d != orig)
+      std::string d = linkDirsProp;
+      std::string orig = linkDirsProp;
+      this->ExpandVariablesInString(d, true, true);
+      if(pol == cmPolicies::WARN && d != orig)
         {
-        w << "Evaluated link directory\n"
+        w << "Evaluated link directories\n"
           << "  " << orig << "\n"
           << "as\n"
-          << "  " << *d << "\n";
+          << "  " << d << "\n";
         }
       }
     }
@@ -2278,6 +2427,18 @@ bool cmMakefile::PlatformIs64Bit() const
   return false;
 }
 
+bool cmMakefile::PlatformIsAppleIos() const
+{
+  std::string sdkRoot;
+  sdkRoot = this->GetSafeDefinition("CMAKE_OSX_SYSROOT");
+  sdkRoot = cmSystemTools::LowerCase(sdkRoot);
+
+  return sdkRoot.find("iphoneos") == 0 ||
+         sdkRoot.find("/iphoneos") != std::string::npos ||
+         sdkRoot.find("iphonesimulator") == 0 ||
+         sdkRoot.find("/iphonesimulator") != std::string::npos;
+}
+
 const char* cmMakefile::GetSONameFlag(const std::string& language) const
 {
   std::string name = "CMAKE_SHARED_LIBRARY_SONAME";
@@ -2335,7 +2496,7 @@ const char* cmMakefile::GetRequiredDefinition(const std::string& name) const
 
 bool cmMakefile::IsDefinitionSet(const std::string& name) const
 {
-  const char* def = this->Internal->GetDefinition(name);
+  const char* def = this->StateSnapshot.GetDefinition(name);
   if(!def)
     {
     def = this->GetState()->GetInitializedCacheValue(name);
@@ -2356,7 +2517,7 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const
 
 const char* cmMakefile::GetDefinition(const std::string& name) const
 {
-  const char* def = this->Internal->GetDefinition(name);
+  const char* def = this->StateSnapshot.GetDefinition(name);
   if(!def)
     {
     def = this->GetState()->GetInitializedCacheValue(name);
@@ -2390,18 +2551,11 @@ const char* cmMakefile::GetSafeDefinition(const std::string& def) const
   return ret;
 }
 
-std::vector<std::string> cmMakefile
-::GetDefinitions(int cacheonly /* = 0 */) const
+std::vector<std::string> cmMakefile::GetDefinitions() const
 {
-  std::vector<std::string> res;
-  if ( !cacheonly )
-    {
-    res = this->Internal->ClosureKeys();
-    }
-  std::vector<std::string> cacheKeys =
-      this->GetState()->GetCacheEntryKeys();
+  std::vector<std::string> res = this->StateSnapshot.ClosureKeys();
+  std::vector<std::string> cacheKeys = this->GetState()->GetCacheEntryKeys();
   res.insert(res.end(), cacheKeys.begin(), cacheKeys.end());
-
   std::sort(res.begin(), res.end());
   return res;
 }
@@ -2763,8 +2917,9 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew(
                 {
                 std::ostringstream msg;
                 cmListFileContext lfc;
-                lfc.FilePath = this->LocalGenerator
-                    ->Convert(filename, cmLocalGenerator::HOME);
+                cmOutputConverter converter(this->StateSnapshot);
+                lfc.FilePath =
+                    converter.Convert(filename, cmOutputConverter::HOME);
                 lfc.Line = line;
                 msg << "uninitialized variable \'" << lookup << "\'";
                 this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING,
@@ -3063,7 +3218,7 @@ void cmMakefile::AddDefaultDefinitions()
 //----------------------------------------------------------------------------
 std::string
 cmMakefile::GetConfigurations(std::vector<std::string>& configs,
-                              bool single) const
+                              bool singleConfig) const
 {
   if(this->GetGlobalGenerator()->IsMultiConfig())
     {
@@ -3077,7 +3232,7 @@ cmMakefile::GetConfigurations(std::vector<std::string>& configs,
   else
     {
     const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
-    if(single && !buildType.empty())
+    if(singleConfig && !buildType.empty())
       {
       configs.push_back(buildType);
       }
@@ -3214,11 +3369,22 @@ bool cmMakefile::IsLoopBlock() const
   return !this->LoopBlockCounter.empty() && this->LoopBlockCounter.top() > 0;
 }
 
+std::string cmMakefile::GetExecutionFilePath() const
+{
+  assert(this->StateSnapshot.IsValid());
+  return this->StateSnapshot.GetExecutionListFile();
+}
+
 //----------------------------------------------------------------------------
 bool cmMakefile::ExpandArguments(
   std::vector<cmListFileArgument> const& inArgs,
-  std::vector<std::string>& outArgs) const
+  std::vector<std::string>& outArgs, const char* filename) const
 {
+  std::string efp = this->GetExecutionFilePath();
+  if (!filename)
+    {
+    filename = efp.c_str();
+    }
   std::vector<cmListFileArgument>::const_iterator i;
   std::string value;
   outArgs.reserve(inArgs.size());
@@ -3233,8 +3399,7 @@ bool cmMakefile::ExpandArguments(
     // Expand the variables in the argument.
     value = i->Value;
     this->ExpandVariablesInString(value, false, false, false,
-                                  i->FilePath, i->Line,
-                                  false, false);
+                                  filename, i->Line, false, false);
 
     // If the argument is quoted, it should be one argument.
     // Otherwise, it may be a list of arguments.
@@ -3253,8 +3418,13 @@ bool cmMakefile::ExpandArguments(
 //----------------------------------------------------------------------------
 bool cmMakefile::ExpandArguments(
   std::vector<cmListFileArgument> const& inArgs,
-  std::vector<cmExpandedCommandArgument>& outArgs) const
+  std::vector<cmExpandedCommandArgument>& outArgs, const char* filename) const
 {
+  std::string efp = this->GetExecutionFilePath();
+  if (!filename)
+    {
+    filename = efp.c_str();
+    }
   std::vector<cmListFileArgument>::const_iterator i;
   std::string value;
   outArgs.reserve(inArgs.size());
@@ -3269,8 +3439,7 @@ bool cmMakefile::ExpandArguments(
     // Expand the variables in the argument.
     value = i->Value;
     this->ExpandVariablesInString(value, false, false, false,
-                                  i->FilePath, i->Line,
-                                  false, false);
+                                  filename, i->Line, false, false);
 
     // If the argument is quoted, it should be one argument.
     // Otherwise, it may be a list of arguments.
@@ -3294,7 +3463,7 @@ bool cmMakefile::ExpandArguments(
 //----------------------------------------------------------------------------
 void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
 {
-  if(!this->CallStack.empty())
+  if(!this->ExecutionStatusStack.empty())
     {
     // Record the context in which the blocker is created.
     fb->SetStartingContext(this->GetExecutionContext());
@@ -3327,11 +3496,13 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb,
       if(!(*pos)->ShouldRemove(lff, *this))
         {
         cmListFileContext const& lfc = fb->GetStartingContext();
+        cmListFileContext closingContext =
+            cmListFileContext::FromCommandContext(lff, lfc.FilePath);
         std::ostringstream e;
         e << "A logical block opening on the line\n"
           << "  " << lfc << "\n"
           << "closes on the line\n"
-          << "  " << lff << "\n"
+          << "  " << closingContext << "\n"
           << "with mis-matching arguments.";
         this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
         }
@@ -3344,19 +3515,6 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb,
   return cmsys::auto_ptr<cmFunctionBlocker>();
 }
 
-//----------------------------------------------------------------------------
-cmMakefile::LexicalPushPop::LexicalPushPop(cmMakefile* mf):
-  Makefile(mf), ReportError(true)
-{
-  this->Makefile->PushFunctionBlockerBarrier();
-}
-
-//----------------------------------------------------------------------------
-cmMakefile::LexicalPushPop::~LexicalPushPop()
-{
-  this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
-}
-
 const char* cmMakefile::GetHomeDirectory() const
 {
   return this->GetCMakeInstance()->GetHomeDirectory();
@@ -3448,7 +3606,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
                            const std::vector<std::string> *cmakeArgs,
                            std::string& output)
 {
-  this->Internal->IsSourceFileTryCompile = fast;
+  this->IsSourceFileTryCompile = fast;
   // does the binary directory exist ? If not create it...
   if (!cmSystemTools::FileIsDirectory(bindir))
     {
@@ -3473,7 +3631,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
       "Internal CMake error, TryCompile bad GlobalGenerator");
     // return to the original directory
     cmSystemTools::ChangeDirectory(cwd);
-    this->Internal->IsSourceFileTryCompile = false;
+    this->IsSourceFileTryCompile = false;
     return 1;
     }
   cm.SetGlobalGenerator(gg);
@@ -3544,7 +3702,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
       "Internal CMake error, TryCompile configure of cmake failed");
     // return to the original directory
     cmSystemTools::ChangeDirectory(cwd);
-    this->Internal->IsSourceFileTryCompile = false;
+    this->IsSourceFileTryCompile = false;
     return 1;
     }
 
@@ -3554,7 +3712,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
       "Internal CMake error, TryCompile generation of cmake failed");
     // return to the original directory
     cmSystemTools::ChangeDirectory(cwd);
-    this->Internal->IsSourceFileTryCompile = false;
+    this->IsSourceFileTryCompile = false;
     return 1;
     }
 
@@ -3567,23 +3725,23 @@ int cmMakefile::TryCompile(const std::string& srcdir,
                                                    this);
 
   cmSystemTools::ChangeDirectory(cwd);
-  this->Internal->IsSourceFileTryCompile = false;
+  this->IsSourceFileTryCompile = false;
   return ret;
 }
 
 bool cmMakefile::GetIsSourceFileTryCompile() const
 {
-  return this->Internal->IsSourceFileTryCompile;
+  return this->IsSourceFileTryCompile;
 }
 
 cmake *cmMakefile::GetCMakeInstance() const
 {
-  return this->GetGlobalGenerator()->GetCMakeInstance();
+  return this->GlobalGenerator->GetCMakeInstance();
 }
 
 cmGlobalGenerator* cmMakefile::GetGlobalGenerator() const
 {
-  return this->LocalGenerator->GetGlobalGenerator();
+  return this->GlobalGenerator;
 }
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
@@ -3598,18 +3756,6 @@ cmVariableWatch *cmMakefile::GetVariableWatch() const
 }
 #endif
 
-void cmMakefile::AddMacro(const char* name)
-{
-  assert(name);
-  this->MacrosList.push_back(name);
-}
-
-void cmMakefile::GetListOfMacros(std::string& macros) const
-{
-  assert(macros.empty());
-  macros = cmJoin(this->MacrosList, ";");
-}
-
 cmState *cmMakefile::GetState() const
 {
   return this->GetCMakeInstance()->GetState();
@@ -3919,234 +4065,28 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
 
 void cmMakefile::SetProperty(const std::string& prop, const char* value)
 {
-  if ( prop == "LINK_DIRECTORIES" )
-    {
-    std::vector<std::string> varArgsExpanded;
-    if(value)
-      {
-      cmSystemTools::ExpandListArgument(value, varArgsExpanded);
-      }
-    this->SetLinkDirectories(varArgsExpanded);
-    return;
-    }
-  if (prop == "INCLUDE_DIRECTORIES")
-    {
-    this->IncludeDirectoriesEntries.clear();
-      if (!value)
-        {
-        return;
-        }
-    cmListFileBacktrace lfbt = this->GetBacktrace();
-    this->IncludeDirectoriesEntries.push_back(
-                                        cmValueWithOrigin(value, lfbt));
-    return;
-    }
-  if (prop == "COMPILE_OPTIONS")
-    {
-    this->CompileOptionsEntries.clear();
-      if (!value)
-        {
-        return;
-        }
-    cmListFileBacktrace lfbt = this->GetBacktrace();
-    this->CompileOptionsEntries.push_back(cmValueWithOrigin(value, lfbt));
-    return;
-    }
-  if (prop == "COMPILE_DEFINITIONS")
-    {
-    this->CompileDefinitionsEntries.clear();
-    if (!value)
-      {
-      return;
-      }
-    cmListFileBacktrace lfbt = this->GetBacktrace();
-    cmValueWithOrigin entry(value, lfbt);
-    this->CompileDefinitionsEntries.push_back(entry);
-    return;
-    }
-
-  if ( prop == "INCLUDE_REGULAR_EXPRESSION" )
-    {
-    this->SetIncludeRegularExpression(value);
-    return;
-    }
-
-  if ( prop == "ADDITIONAL_MAKE_CLEAN_FILES" )
-    {
-    // This property is not inherrited
-    if ( strcmp(this->GetCurrentSourceDirectory(),
-                this->GetCurrentSourceDirectory()) != 0 )
-      {
-      return;
-      }
-    }
-
-  this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
+  cmListFileBacktrace lfbt = this->GetBacktrace();
+  this->StateSnapshot.GetDirectory().SetProperty(prop, value, lfbt);
 }
 
 void cmMakefile::AppendProperty(const std::string& prop,
                                 const char* value,
                                 bool asString)
 {
-  if (prop == "INCLUDE_DIRECTORIES")
-    {
-    cmListFileBacktrace lfbt = this->GetBacktrace();
-    this->IncludeDirectoriesEntries.push_back(
-                                        cmValueWithOrigin(value, lfbt));
-    return;
-    }
-  if (prop == "COMPILE_OPTIONS")
-    {
-    cmListFileBacktrace lfbt = this->GetBacktrace();
-    this->CompileOptionsEntries.push_back(
-                                        cmValueWithOrigin(value, lfbt));
-    return;
-    }
-  if (prop == "COMPILE_DEFINITIONS")
-    {
-    cmListFileBacktrace lfbt = this->GetBacktrace();
-    this->CompileDefinitionsEntries.push_back(
-                                        cmValueWithOrigin(value, lfbt));
-    return;
-    }
-  if ( prop == "LINK_DIRECTORIES" )
-    {
-    std::vector<std::string> varArgsExpanded;
-    cmSystemTools::ExpandListArgument(value, varArgsExpanded);
-    for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
-        vi != varArgsExpanded.end(); ++vi)
-      {
-      this->AddLinkDirectory(*vi);
-      }
-    return;
-    }
-
-  this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY,asString);
+  cmListFileBacktrace lfbt = this->GetBacktrace();
+  this->StateSnapshot.GetDirectory().AppendProperty(prop, value,
+                                                    asString, lfbt);
 }
 
 const char *cmMakefile::GetProperty(const std::string& prop) const
 {
-  return this->GetProperty(prop, cmProperty::DIRECTORY);
+  return this->StateSnapshot.GetDirectory().GetProperty(prop);
 }
 
 const char *cmMakefile::GetProperty(const std::string& prop,
-                                    cmProperty::ScopeType scope) const
+                                    bool chain) const
 {
-  // watch for specific properties
-  static std::string output;
-  output = "";
-  if (prop == "PARENT_DIRECTORY")
-    {
-    cmState::Snapshot parent = this->StateSnapshot.GetParent();
-    if(parent.IsValid())
-      {
-      return parent.GetCurrentSourceDirectory();
-      }
-    return "";
-    }
-  else if (prop == "INCLUDE_REGULAR_EXPRESSION" )
-    {
-    output = this->GetIncludeRegularExpression();
-    return output.c_str();
-    }
-  else if (prop == "LISTFILE_STACK")
-    {
-    output = cmJoin(this->ListFileStack, ";");
-    return output.c_str();
-    }
-  else if (prop == "VARIABLES" || prop == "CACHE_VARIABLES")
-    {
-    int cacheonly = 0;
-    if ( prop == "CACHE_VARIABLES" )
-      {
-      cacheonly = 1;
-      }
-    output = cmJoin(this->GetDefinitions(cacheonly), ";");
-    return output.c_str();
-    }
-  else if (prop == "MACROS")
-    {
-    this->GetListOfMacros(output);
-    return output.c_str();
-    }
-  else if (prop == "DEFINITIONS")
-    {
-    switch(this->GetPolicyStatus(cmPolicies::CMP0059))
-      {
-      case cmPolicies::WARN:
-          this->IssueMessage(cmake::AUTHOR_WARNING, cmPolicies::
-                             GetPolicyWarning(cmPolicies::CMP0059));
-      case cmPolicies::OLD:
-        output += this->DefineFlagsOrig;
-        return output.c_str();
-      case cmPolicies::NEW:
-      case cmPolicies::REQUIRED_ALWAYS:
-      case cmPolicies::REQUIRED_IF_USED:
-        break;
-      }
-    }
-  else if (prop == "LINK_DIRECTORIES")
-    {
-    output = cmJoin(this->GetLinkDirectories(), ";");
-    return output.c_str();
-    }
-  else if (prop == "INCLUDE_DIRECTORIES")
-    {
-    std::string sep;
-    for (std::vector<cmValueWithOrigin>::const_iterator
-        it = this->IncludeDirectoriesEntries.begin(),
-        end = this->IncludeDirectoriesEntries.end();
-        it != end; ++it)
-      {
-      output += sep;
-      output += it->Value;
-      sep = ";";
-      }
-    return output.c_str();
-    }
-  else if (prop == "COMPILE_OPTIONS")
-    {
-    std::string sep;
-    for (std::vector<cmValueWithOrigin>::const_iterator
-        it = this->CompileOptionsEntries.begin(),
-        end = this->CompileOptionsEntries.end();
-        it != end; ++it)
-      {
-      output += sep;
-      output += it->Value;
-      sep = ";";
-      }
-    return output.c_str();
-    }
-  else if (prop == "COMPILE_DEFINITIONS")
-    {
-    std::string sep;
-    for (std::vector<cmValueWithOrigin>::const_iterator
-        it = this->CompileDefinitionsEntries.begin(),
-        end = this->CompileDefinitionsEntries.end();
-        it != end; ++it)
-      {
-      output += sep;
-      output += it->Value;
-      sep = ";";
-      }
-    return output.c_str();
-    }
-
-  bool chain = false;
-  const char *retVal =
-    this->Properties.GetPropertyValue(prop, scope, chain);
-  if (chain)
-    {
-    if(this->LocalGenerator->GetParent())
-      {
-      return this->LocalGenerator->GetParent()->GetMakefile()->
-        GetProperty(prop, scope);
-      }
-    return this->GetState()->GetGlobalProperty(prop);
-    }
-
-  return retVal;
+  return this->StateSnapshot.GetDirectory().GetProperty(prop, chain);
 }
 
 bool cmMakefile::GetPropertyAsBool(const std::string& prop) const
@@ -4154,31 +4094,9 @@ bool cmMakefile::GetPropertyAsBool(const std::string& prop) const
   return cmSystemTools::IsOn(this->GetProperty(prop));
 }
 
-//----------------------------------------------------------------------------
-const char* cmMakefile::GetFeature(const std::string& feature,
-                                   const std::string& config)
+std::vector<std::string> cmMakefile::GetPropertyKeys() const
 {
-  // TODO: Define accumulation policy for features (prepend, append, replace).
-  // Currently we always replace.
-  if(!config.empty())
-    {
-    std::string featureConfig = feature;
-    featureConfig += "_";
-    featureConfig += cmSystemTools::UpperCase(config);
-    if(const char* value = this->GetProperty(featureConfig))
-      {
-      return value;
-      }
-    }
-  if(const char* value = this->GetProperty(feature))
-    {
-    return value;
-    }
-  if(cmLocalGenerator* parent = this->LocalGenerator->GetParent())
-    {
-    return parent->GetMakefile()->GetFeature(feature, config);
-    }
-  return 0;
+  return this->StateSnapshot.GetDirectory().GetPropertyKeys();
 }
 
 cmTarget* cmMakefile::FindTarget(const std::string& name,
@@ -4253,14 +4171,22 @@ void cmMakefile::AddCMakeDependFilesFromUser()
 
 std::string cmMakefile::FormatListFileStack() const
 {
+  std::vector<std::string> listFiles;
+  cmState::Snapshot snp = this->StateSnapshot;
+  while (snp.IsValid())
+    {
+    listFiles.push_back(snp.GetExecutionListFile());
+    snp = snp.GetCallStackParent();
+    }
+  std::reverse(listFiles.begin(), listFiles.end());
   std::ostringstream tmp;
-  size_t depth = this->ListFileStack.size();
+  size_t depth = listFiles.size();
   if (depth > 0)
     {
-    std::vector<std::string>::const_iterator it = this->ListFileStack.end();
+    std::vector<std::string>::const_iterator it = listFiles.end();
     do
       {
-      if (depth != this->ListFileStack.size())
+      if (depth != listFiles.size())
         {
         tmp << "\n                ";
         }
@@ -4271,7 +4197,7 @@ std::string cmMakefile::FormatListFileStack() const
       tmp << *it;
       depth--;
       }
-    while (it != this->ListFileStack.begin());
+    while (it != listFiles.begin());
     }
   return tmp.str();
 }
@@ -4279,8 +4205,17 @@ std::string cmMakefile::FormatListFileStack() const
 
 void cmMakefile::PushScope()
 {
-  this->Internal->PushDefinitions();
-
+  std::string commandName;
+  long line = 0;
+  if (!this->ContextStack.empty())
+    {
+    commandName = this->ContextStack.back()->Name;
+    line = this->ContextStack.back()->Line;
+    }
+  this->StateSnapshot = this->GetState()->CreateVariableScopeSnapshot(
+        this->StateSnapshot,
+        commandName,
+        line);
   this->PushLoopBlockBarrier();
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -4298,7 +4233,9 @@ void cmMakefile::PopScope()
 
   this->CheckForUnusedVariables();
 
-  this->Internal->PopDefinitions();
+  this->StateSnapshot =
+      this->GetState()->Pop(this->StateSnapshot);
+  assert(this->StateSnapshot.IsValid());
 }
 
 void cmMakefile::RaiseScope(const std::string& var, const char *varDef)
@@ -4308,7 +4245,7 @@ void cmMakefile::RaiseScope(const std::string& var, const char *varDef)
     return;
     }
 
-  if (!this->Internal->RaiseScope(var, varDef, this))
+  if (!this->StateSnapshot.RaiseScope(var, varDef))
     {
     std::ostringstream m;
     m << "Cannot set \"" << var << "\": current scope has no parent.";
@@ -4596,57 +4533,21 @@ void cmMakefile::StoreMatches(cmsys::RegularExpression& re)
   this->MarkVariableAsUsed(nMatchesVariable);
 }
 
-//----------------------------------------------------------------------------
-cmPolicies::PolicyStatus
-cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const
+cmState::Snapshot cmMakefile::GetStateSnapshot() const
 {
-  // Get the current setting of the policy.
-  cmPolicies::PolicyStatus cur = this->GetPolicyStatusInternal(id);
-
-  // If the policy is required to be set to NEW but is not, ignore the
-  // current setting and tell the caller.
-  if(cur != cmPolicies::NEW)
-    {
-    if(cur == cmPolicies::REQUIRED_ALWAYS ||
-       cur == cmPolicies::REQUIRED_IF_USED)
-      {
-      return cur;
-      }
-    cmPolicies::PolicyStatus def = cmPolicies::GetPolicyStatus(id);
-    if(def == cmPolicies::REQUIRED_ALWAYS ||
-       def == cmPolicies::REQUIRED_IF_USED)
-      {
-      return def;
-      }
-    }
+  return this->StateSnapshot;
+}
 
-  // The current setting is okay.
-  return cur;
+const char* cmMakefile::GetDefineFlagsCMP0059() const
+{
+  return this->DefineFlagsOrig.c_str();
 }
 
 //----------------------------------------------------------------------------
 cmPolicies::PolicyStatus
-cmMakefile::GetPolicyStatusInternal(cmPolicies::PolicyID id) const
+cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const
 {
-  // Is the policy set in our stack?
-  for(PolicyStackType::const_reverse_iterator psi = this->PolicyStack.rbegin();
-      psi != this->PolicyStack.rend(); ++psi)
-    {
-    if(psi->IsDefined(id))
-      {
-      return psi->Get(id);
-      }
-    }
-
-  // If we have a parent directory, recurse up to it.
-  if(this->LocalGenerator->GetParent())
-    {
-    cmMakefile* parent = this->LocalGenerator->GetParent()->GetMakefile();
-    return parent->GetPolicyStatusInternal(id);
-    }
-
-  // The policy is not set.  Use the default for this CMake version.
-  return cmPolicies::GetPolicyStatus(id);
+  return this->StateSnapshot.GetPolicy(id);
 }
 
 //----------------------------------------------------------------------------
@@ -4660,7 +4561,8 @@ bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var)
       return cmSystemTools::IsOn(val);
       }
     }
-  // Enable optional policy warnings with --debug-output or --trace.
+  // Enable optional policy warnings with --debug-output, --trace,
+  // or --trace-expand.
   cmake* cm = this->GetCMakeInstance();
   return cm->GetDebugOutput() || cm->GetTrace();
 }
@@ -4694,34 +4596,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
     return false;
     }
 
-  // Update the policy stack from the top to the top-most strong entry.
-  bool previous_was_weak = true;
-  for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
-      previous_was_weak && psi != this->PolicyStack.rend(); ++psi)
-    {
-    psi->Set(id, status);
-    previous_was_weak = psi->Weak;
-    }
-
-  // Special hook for presenting compatibility variable as soon as
-  // the user requests it.
-  if(id == cmPolicies::CMP0001 &&
-     (status == cmPolicies::WARN || status == cmPolicies::OLD))
-    {
-    if(!(this->GetState()
-         ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
-      {
-      // Set it to 2.4 because that is the last version where the
-      // variable had meaning.
-      this->AddCacheDefinition
-        ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
-         "For backwards compatibility, what version of CMake "
-         "commands and "
-         "syntax should this version of CMake try to support.",
-         cmState::STRING);
-      }
-    }
-
+  this->StateSnapshot.SetPolicy(id, status);
   return true;
 }
 
@@ -4730,32 +4605,28 @@ cmMakefile::PolicyPushPop::PolicyPushPop(cmMakefile* m, bool weak,
                                          cmPolicies::PolicyMap const& pm):
   Makefile(m), ReportError(true)
 {
+  this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
+      ->CreatePolicyScopeSnapshot(this->Makefile->StateSnapshot);
   this->Makefile->PushPolicy(weak, pm);
-  this->Makefile->PushPolicyBarrier();
 }
 
 //----------------------------------------------------------------------------
 cmMakefile::PolicyPushPop::~PolicyPushPop()
 {
-  this->Makefile->PopPolicyBarrier(this->ReportError);
   this->Makefile->PopPolicy();
+  this->Makefile->PopPolicyBarrier(this->ReportError);
 }
 
 //----------------------------------------------------------------------------
 void cmMakefile::PushPolicy(bool weak, cmPolicies::PolicyMap const& pm)
 {
-  // Allocate a new stack entry.
-  this->PolicyStack.push_back(PolicyStackEntry(pm, weak));
+  this->StateSnapshot.PushPolicy(pm, weak);
 }
 
 //----------------------------------------------------------------------------
 void cmMakefile::PopPolicy()
 {
-  if(this->PolicyStack.size() > this->PolicyBarriers.back())
-    {
-    this->PolicyStack.pop_back();
-    }
-  else
+  if (!this->StateSnapshot.PopPolicy())
     {
     this->IssueMessage(cmake::FATAL_ERROR,
                        "cmake_policy POP without matching PUSH");
@@ -4763,17 +4634,9 @@ void cmMakefile::PopPolicy()
 }
 
 //----------------------------------------------------------------------------
-void cmMakefile::PushPolicyBarrier()
-{
-  this->PolicyBarriers.push_back(this->PolicyStack.size());
-}
-
-//----------------------------------------------------------------------------
 void cmMakefile::PopPolicyBarrier(bool reportError)
 {
-  // Remove any extra entries pushed on the barrier.
-  PolicyStackType::size_type barrier = this->PolicyBarriers.back();
-  while(this->PolicyStack.size() > barrier)
+  while (!this->StateSnapshot.CanPopPolicyScope())
     {
     if(reportError)
       {
@@ -4784,8 +4647,8 @@ void cmMakefile::PopPolicyBarrier(bool reportError)
     this->PopPolicy();
     }
 
-  // Remove the barrier.
-  this->PolicyBarriers.pop_back();
+  this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
+  assert(this->StateSnapshot.IsValid());
 }
 
 //----------------------------------------------------------------------------
@@ -4795,9 +4658,10 @@ bool cmMakefile::SetPolicyVersion(const char *version)
 }
 
 //----------------------------------------------------------------------------
-bool cmMakefile::HasCMP0054AlreadyBeenReported() const
+bool cmMakefile::HasCMP0054AlreadyBeenReported(
+    cmListFileContext const& context) const
 {
-  return !this->CMP0054ReportedIds.insert(this->GetExecutionContext()).second;
+  return !this->CMP0054ReportedIds.insert(context).second;
 }
 
 //----------------------------------------------------------------------------
@@ -5357,3 +5221,44 @@ AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const
     }
   return true;
 }
+
+
+cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf,
+                                             const std::string& fileName,
+                                             cmPolicies::PolicyMap const& pm)
+  : Makefile(mf), ReportError(true)
+{
+  this->Makefile->PushFunctionScope(fileName, pm);
+}
+
+cmMakefile::FunctionPushPop::~FunctionPushPop()
+{
+  this->Makefile->PopFunctionScope(this->ReportError);
+}
+
+
+cmMakefile::MacroPushPop::MacroPushPop(cmMakefile* mf,
+                                       const std::string& fileName,
+                                       const cmPolicies::PolicyMap& pm)
+  : Makefile(mf), ReportError(true)
+{
+  this->Makefile->PushMacroScope(fileName, pm);
+}
+
+cmMakefile::MacroPushPop::~MacroPushPop()
+{
+  this->Makefile->PopMacroScope(this->ReportError);
+}
+
+cmMakefileCall::cmMakefileCall(cmMakefile* mf, const cmCommandContext& lfc,
+                               cmExecutionStatus& status): Makefile(mf)
+{
+  this->Makefile->ContextStack.push_back(&lfc);
+  this->Makefile->ExecutionStatusStack.push_back(&status);
+}
+
+cmMakefileCall::~cmMakefileCall()
+{
+  this->Makefile->ExecutionStatusStack.pop_back();
+  this->Makefile->ContextStack.pop_back();
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 27ef075..111f074 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -14,8 +14,6 @@
 
 #include "cmExecutionStatus.h"
 #include "cmListFileCache.h"
-#include "cmPolicies.h"
-#include "cmPropertyMap.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 #include "cmNewLineStyle.h"
@@ -23,6 +21,7 @@
 #include "cmExpandedCommandArgument.h"
 #include "cmake.h"
 #include "cmState.h"
+#include "cmAlgorithms.h"
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
 #include "cmSourceGroup.h"
@@ -43,7 +42,6 @@
 class cmFunctionBlocker;
 class cmCommand;
 class cmInstallGenerator;
-class cmLocalGenerator;
 class cmMakeDepend;
 class cmSourceFile;
 class cmTest;
@@ -52,6 +50,7 @@ class cmVariableWatch;
 class cmake;
 class cmMakefileCall;
 class cmCMakePolicyCommand;
+class cmGeneratorExpressionEvaluationFile;
 
 /** \class cmMakefile
  * \brief Process the input CMakeLists.txt file.
@@ -62,8 +61,6 @@ class cmCMakePolicyCommand;
  */
 class cmMakefile
 {
-  class Internals;
-  cmsys::auto_ptr<Internals> Internal;
 public:
   /* Mark a variable as used */
   void MarkVariableAsUsed(const std::string& var);
@@ -73,24 +70,28 @@ public:
   /**
    * Construct an empty makefile.
    */
-  cmMakefile(cmLocalGenerator* localGenerator);
+  cmMakefile(cmGlobalGenerator* globalGenerator,
+             const cmState::Snapshot& snapshot);
 
   /**
    * Destructor.
    */
   ~cmMakefile();
 
-  bool ReadListFile(const char* listfile);
+  bool ReadListFile(const char* filename);
 
-  bool ReadDependentFile(const char* listfile, bool noPolicyScope = true);
+  bool ReadDependentFile(const char* filename, bool noPolicyScope = true);
 
-  bool ProcessBuildsystemFile(const char* listfile);
+  bool ProcessBuildsystemFile(const char* filename);
 
   /**
    * Add a function blocker to this makefile
    */
   void AddFunctionBlocker(cmFunctionBlocker* fb);
 
+  /// @return whether we are processing the top CMakeLists.txt file.
+  bool IsRootMakefile() const;
+
   /**
    * Remove the function blocker whose scope ends with the given command.
    * This returns ownership of the function blocker object.
@@ -98,19 +99,6 @@ public:
   cmsys::auto_ptr<cmFunctionBlocker>
   RemoveFunctionBlocker(cmFunctionBlocker* fb, const cmListFileFunction& lff);
 
-  /** Push/pop a lexical (function blocker) barrier automatically.  */
-  class LexicalPushPop
-  {
-  public:
-    LexicalPushPop(cmMakefile* mf);
-    ~LexicalPushPop();
-    void Quiet() { this->ReportError = false; }
-  private:
-    cmMakefile* Makefile;
-    bool ReportError;
-  };
-  friend class LexicalPushPop;
-
   /**
    * Try running cmake and building a file. This is used for dynalically
    * loaded commands, not as part of the usual build process.
@@ -123,10 +111,6 @@ public:
 
   bool GetIsSourceFileTryCompile() const;
 
-  ///! Get the current makefile generator.
-  cmLocalGenerator* GetLocalGenerator() const
-    { return this->LocalGenerator;}
-
   /**
    * Help enforce global target name uniqueness.
    */
@@ -204,14 +188,15 @@ public:
    * Add a utility to the build.  A utiltity target is a command that
    * is run every time the target is built.
    */
-  void AddUtilityCommand(const std::string& utilityName, bool excludeFromAll,
-                         const std::vector<std::string>& depends,
-                         const char* workingDirectory,
-                         const char* command,
-                         const char* arg1=0,
-                         const char* arg2=0,
-                         const char* arg3=0,
-                         const char* arg4=0);
+  cmTarget* AddUtilityCommand(const std::string& utilityName,
+                              bool excludeFromAll,
+                              const std::vector<std::string>& depends,
+                              const char* workingDirectory,
+                              const char* command,
+                              const char* arg1=0,
+                              const char* arg2=0,
+                              const char* arg3=0,
+                              const char* arg4=0);
   cmTarget* AddUtilityCommand(const std::string& utilityName,
                               bool excludeFromAll,
                               const char* workingDirectory,
@@ -240,20 +225,6 @@ public:
   void AddLinkDirectoryForTarget(const std::string& tgt, const std::string& d);
 
   /**
-   * Add a link directory to the build.
-   */
-  void AddLinkDirectory(const std::string&);
-
-  const std::vector<std::string>& GetLinkDirectories() const
-    {
-      return this->LinkDirectories;
-    }
-  void SetLinkDirectories(const std::vector<std::string>& vec)
-    {
-      this->LinkDirectories = vec;
-    }
-
-  /**
    * Add a subdirectory to the build.
    */
   void AddSubDirectory(const std::string& fullSrcDir,
@@ -261,10 +232,12 @@ public:
                        bool excludeFromAll,
                        bool immediate);
 
+  void Configure();
+
   /**
    * Configure a subdirectory
    */
-  void ConfigureSubDirectory(cmLocalGenerator *);
+  void ConfigureSubDirectory(cmMakefile* mf);
 
   /**
    * Add an include directory to the build.
@@ -299,15 +272,12 @@ public:
   /**
    * Specify the name of the project for this build.
    */
-  void SetProjectName(const char*);
+  void SetProjectName(std::string const& name);
 
   /**
    * Get the name of the project for this build.
    */
-  const char* GetProjectName() const
-    {
-      return this->ProjectName.c_str();
-    }
+  std::string GetProjectName() const;
 
   /** Get the configurations to be generated.  */
   std::string GetConfigurations(std::vector<std::string>& configs,
@@ -363,17 +333,10 @@ public:
   friend class PolicyPushPop;
 
   /**
-    * Get the Policies Instance
-    */
-  cmPolicies *GetPolicies() const;
-
-  mutable std::set<cmListFileContext> CMP0054ReportedIds;
-
-  /**
    * Determine if the given context, name pair has already been reported
    * in context of CMP0054.
    */
-  bool HasCMP0054AlreadyBeenReported() const;
+  bool HasCMP0054AlreadyBeenReported(const cmListFileContext &context) const;
 
   bool IgnoreErrorsCMP0061() const;
 
@@ -403,11 +366,11 @@ public:
    */
   void SetIncludeRegularExpression(const char* regex)
     {
-      this->IncludeFileRegularExpression = regex;
+      this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex);
     }
   const char* GetIncludeRegularExpression() const
     {
-      return this->IncludeFileRegularExpression.c_str();
+      return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
     }
 
   /**
@@ -445,6 +408,7 @@ public:
     {
       this->GeneratorTargets = targets;
     }
+  void AddGeneratorTarget(cmTarget* t, cmGeneratorTarget* gt);
 
   cmTarget* FindTarget(const std::string& name,
                        bool excludeAliases = false) const;
@@ -506,7 +470,7 @@ public:
    * cacheonly is specified and is greater than 0, then only cache
    * variables will be listed.
    */
-  std::vector<std::string> GetDefinitions(int cacheonly=0) const;
+  std::vector<std::string> GetDefinitions() const;
 
   /**
    * Test a boolean variable to see if it is true or false.
@@ -520,6 +484,9 @@ public:
   /** Return whether the target platform is 64-bit.  */
   bool PlatformIs64Bit() const;
 
+  /** Return whether the target platform is Apple iOS.  */
+  bool PlatformIsAppleIos() const;
+
   /** Retrieve soname flag for the specified language if supported */
   const char* GetSONameFlag(const std::string& language) const;
 
@@ -563,6 +530,7 @@ public:
    * Get the current context backtrace.
    */
   cmListFileBacktrace GetBacktrace() const;
+  cmListFileBacktrace GetBacktrace(cmCommandContext const& lfc) const;
   cmListFileContext GetExecutionContext() const;
 
   /**
@@ -658,10 +626,12 @@ public:
    * variable replacement and list expansion.
    */
   bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
-                       std::vector<std::string>& outArgs) const;
+                       std::vector<std::string>& outArgs,
+                       const char* filename = 0) const;
 
   bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
-                       std::vector<cmExpandedCommandArgument>& outArgs) const;
+                       std::vector<cmExpandedCommandArgument>& outArgs,
+                       const char* filename = 0) const;
 
   /**
    * Get the instance
@@ -682,12 +652,6 @@ public:
    */
   cmSourceFile *GetSourceFileWithOutput(const std::string& outName) const;
 
-  /**
-   * Add a macro to the list of macros. The arguments should be name of the
-   * macro and a documentation signature of it
-   */
-  void AddMacro(const char* name);
-
   ///! Add a new cmTest to the list of tests for this makefile.
   cmTest* CreateTest(const std::string& testName);
 
@@ -697,11 +661,6 @@ public:
   cmTest* GetTest(const std::string& testName) const;
 
   /**
-   * Get a list of macros as a ; separated string
-   */
-  void GetListOfMacros(std::string& macros) const;
-
-  /**
    * Return a location of a file in cmake or custom modules directory
    */
   std::string GetModulesFile(const char* name) const;
@@ -711,18 +670,12 @@ public:
   void AppendProperty(const std::string& prop, const char *value,
                       bool asString=false);
   const char *GetProperty(const std::string& prop) const;
-  const char *GetProperty(const std::string& prop,
-                          cmProperty::ScopeType scope) const;
+  const char *GetProperty(const std::string& prop, bool chain) const;
   bool GetPropertyAsBool(const std::string& prop) const;
-
-  const char* GetFeature(const std::string& feature,
-                         const std::string& config);
-
-  // Get the properties
-  cmPropertyMap &GetProperties() { return this->Properties; }
+  std::vector<std::string> GetPropertyKeys() const;
 
   ///! Initialize a makefile from its parent
-  void InitializeFromParent();
+  void InitializeFromParent(cmMakefile* parent);
 
   void AddInstallGenerator(cmInstallGenerator* g)
     { if(g) this->InstallGenerators.push_back(g); }
@@ -734,7 +687,38 @@ public:
   const std::vector<cmTestGenerator*>& GetTestGenerators() const
     { return this->TestGenerators; }
 
-  // push and pop variable scopes
+  class FunctionPushPop
+  {
+  public:
+    FunctionPushPop(cmMakefile* mf, std::string const& fileName,
+                    cmPolicies::PolicyMap const& pm);
+    ~FunctionPushPop();
+
+    void Quiet() { this->ReportError = false; }
+  private:
+    cmMakefile* Makefile;
+    bool ReportError;
+  };
+
+  class MacroPushPop
+  {
+  public:
+    MacroPushPop(cmMakefile* mf, std::string const& fileName,
+                 cmPolicies::PolicyMap const& pm);
+    ~MacroPushPop();
+
+    void Quiet() { this->ReportError = false; }
+  private:
+    cmMakefile* Makefile;
+    bool ReportError;
+  };
+
+  void PushFunctionScope(std::string const& fileName,
+                         cmPolicies::PolicyMap const& pm);
+  void PopFunctionScope(bool reportError);
+  void PushMacroScope(std::string const& fileName,
+                      cmPolicies::PolicyMap const& pm);
+  void PopMacroScope(bool reportError);
   void PushScope();
   void PopScope();
   void RaiseScope(const std::string& var, const char *value);
@@ -759,21 +743,12 @@ public:
   /** Set whether or not to report a CMP0000 violation.  */
   void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
 
-  const std::vector<cmValueWithOrigin>& GetIncludeDirectoriesEntries() const
-  {
-    return this->IncludeDirectoriesEntries;
-  }
-  const std::vector<cmValueWithOrigin>& GetCompileOptionsEntries() const
-  {
-    return this->CompileOptionsEntries;
-  }
-  const std::vector<cmValueWithOrigin>& GetCompileDefinitionsEntries() const
-  {
-    return this->CompileDefinitionsEntries;
-  }
-
-  bool IsGeneratingBuildSystem() const { return this->GeneratingBuildSystem; }
-  void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; }
+  cmStringRange GetIncludeDirectoriesEntries() const;
+  cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
+  cmStringRange GetCompileOptionsEntries() const;
+  cmBacktraceRange GetCompileOptionsBacktraces() const;
+  cmStringRange GetCompileDefinitionsEntries() const;
+  cmBacktraceRange GetCompileDefinitionsBacktraces() const;
 
   void AddQtUiFileWithOptions(cmSourceFile *sf);
   std::vector<cmSourceFile*> GetQtUiFilesWithOptions() const;
@@ -807,6 +782,20 @@ public:
   void ClearMatches();
   void StoreMatches(cmsys::RegularExpression& re);
 
+  cmState::Snapshot GetStateSnapshot() const;
+
+  const char* GetDefineFlagsCMP0059() const;
+
+  std::string GetExecutionFilePath() const;
+
+  void EnforceDirectoryLevelRules() const;
+
+  void AddEvaluationFile(const std::string &inputFile,
+                  cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
+                  cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
+                  bool inputIsContent);
+  std::vector<cmGeneratorExpressionEvaluationFile*> GetEvaluationFiles() const;
+
 protected:
   // add link libraries and directories to the target
   void AddGlobalLinkInformation(const std::string& name, cmTarget& target);
@@ -814,7 +803,7 @@ protected:
   // Check for a an unused variable
   void LogUnused(const char* reason, const std::string& name) const;
 
-  std::string ProjectName;    // project name
+  mutable std::set<cmListFileContext> CMP0054ReportedIds;
 
   // libraries, classes, and executables
   mutable cmTargets Targets;
@@ -849,16 +838,11 @@ protected:
   std::vector<cmInstallGenerator*> InstallGenerators;
   std::vector<cmTestGenerator*> TestGenerators;
 
-  std::string IncludeFileRegularExpression;
   std::string ComplainFileRegularExpression;
   std::vector<std::string> SourceFileExtensions;
   std::vector<std::string> HeaderFileExtensions;
   std::string DefineFlags;
 
-  std::vector<cmValueWithOrigin> IncludeDirectoriesEntries;
-  std::vector<cmValueWithOrigin> CompileOptionsEntries;
-  std::vector<cmValueWithOrigin> CompileDefinitionsEntries;
-
   // Track the value of the computed DEFINITIONS property.
   void AddDefineFlag(const char*, std::string&);
   void RemoveDefineFlag(const char*, std::string::size_type, std::string&);
@@ -869,7 +853,7 @@ protected:
 #endif
 
   std::vector<cmCommand*> FinalPassCommands;
-  cmLocalGenerator* LocalGenerator;
+  cmGlobalGenerator* GlobalGenerator;
   bool IsFunctionBlocked(const cmListFileFunction& lff,
                          cmExecutionStatus &status);
 
@@ -879,13 +863,8 @@ private:
 
   cmState::Snapshot StateSnapshot;
 
-  bool ReadListFile(const char* listfile,
-                    bool noPolicyScope,
-                    bool requireProjectCommand);
-
-  bool ReadListFileInternal(const char* filenametoread,
-                            bool noPolicyScope,
-                            bool requireProjectCommand);
+  void ReadListFile(cmListFile const& listFile,
+                    const std::string& filenametoread);
 
   bool ParseDefineFlag(std::string const& definition, bool remove);
 
@@ -904,31 +883,19 @@ private:
 
   std::stack<int> LoopBlockCounter;
 
-  std::vector<std::string> MacrosList;
-
   mutable cmsys::RegularExpression cmDefineRegex;
   mutable cmsys::RegularExpression cmDefine01Regex;
   mutable cmsys::RegularExpression cmAtVarRegex;
   mutable cmsys::RegularExpression cmNamedCurly;
 
-  cmPropertyMap Properties;
-
-  // Unused variable flags
-  bool WarnUnused;
-  bool CheckSystemVars;
+  std::vector<cmMakefile*> UnConfiguredDirectories;
 
-  // stack of list files being read
-  std::vector<std::string> ListFileStack;
+  std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
 
-  // stack of commands being invoked.
-  struct CallStackEntry
-  {
-    cmListFileContext const* Context;
-    cmExecutionStatus* Status;
-  };
-  typedef std::vector<CallStackEntry> CallStackType;
-  CallStackType CallStack;
+  std::vector<cmCommandContext const*> ContextStack;
+  std::vector<cmExecutionStatus*> ExecutionStatusStack;
   friend class cmMakefileCall;
+  friend class cmParseFileScope;
 
   std::vector<cmTarget*> ImportedTargetsOwned;
   TargetMap ImportedTargets;
@@ -937,31 +904,15 @@ private:
   void PushPolicy(bool weak = false,
                   cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
   void PopPolicy();
-  void PushPolicyBarrier();
   void PopPolicyBarrier(bool reportError = true);
   friend class cmCMakePolicyCommand;
   class IncludeScope;
   friend class IncludeScope;
+  class ListFileScope;
+  friend class ListFileScope;
+  class BuildsystemFileScope;
+  friend class BuildsystemFileScope;
 
-  // stack of policy settings
-  struct PolicyStackEntry: public cmPolicies::PolicyMap
-  {
-    typedef cmPolicies::PolicyMap derived;
-    PolicyStackEntry(bool w = false): derived(), Weak(w) {}
-    PolicyStackEntry(derived const& d, bool w = false): derived(d), Weak(w) {}
-    PolicyStackEntry(PolicyStackEntry const& r): derived(r), Weak(r.Weak) {}
-    bool Weak;
-  };
-  typedef std::vector<PolicyStackEntry> PolicyStackType;
-  PolicyStackType PolicyStack;
-  std::vector<PolicyStackType::size_type> PolicyBarriers;
-  cmPolicies::PolicyStatus
-  GetPolicyStatusInternal(cmPolicies::PolicyID id) const;
-
-  bool CheckCMP0000;
-
-  // Enforce rules about CMakeLists.txt files.
-  void EnforceDirectoryLevelRules() const;
 
   // CMP0053 == old
   cmake::MessageType ExpandVariablesInStringOld(
@@ -985,7 +936,6 @@ private:
                                   long line,
                                   bool removeEmpty,
                                   bool replaceAt) const;
-  bool GeneratingBuildSystem;
   /**
    * Old version of GetSourceFileWithOutput(const std::string&) kept for
    * backward-compatibility. It implements a linear search and support
@@ -1031,6 +981,11 @@ private:
 
   void CheckForUnusedVariables() const;
 
+  // Unused variable flags
+  bool WarnUnused;
+  bool CheckSystemVars;
+  bool CheckCMP0000;
+  bool IsSourceFileTryCompile;
   mutable bool SuppressWatches;
 };
 
@@ -1040,16 +995,9 @@ class cmMakefileCall
 {
 public:
   cmMakefileCall(cmMakefile* mf,
-                 cmListFileContext const& lfc,
-                 cmExecutionStatus& status): Makefile(mf)
-    {
-    cmMakefile::CallStackEntry entry = {&lfc, &status};
-    this->Makefile->CallStack.push_back(entry);
-    }
-  ~cmMakefileCall()
-    {
-    this->Makefile->CallStack.pop_back();
-    }
+                 cmCommandContext const& lfc,
+                 cmExecutionStatus& status);
+  ~cmMakefileCall();
 private:
   cmMakefile* Makefile;
 };
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 37b297e..90f679e 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -22,10 +22,10 @@
 //----------------------------------------------------------------------------
 cmMakefileExecutableTargetGenerator
 ::cmMakefileExecutableTargetGenerator(cmGeneratorTarget* target):
-  cmMakefileTargetGenerator(target->Target)
+  cmMakefileTargetGenerator(target)
 {
   this->CustomCommandDriver = OnDepends;
-  this->Target->GetExecutableNames(
+  this->GeneratorTarget->GetExecutableNames(
     this->TargetNameOut, this->TargetNameReal, this->TargetNameImport,
     this->TargetNamePDB, this->ConfigName);
 
@@ -58,7 +58,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
 
   // write the link rules
   this->WriteExecutableRule(false);
-  if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+  if(this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName))
     {
     // Write rules to link an installable version of the target.
     this->WriteExecutableRule(true);
@@ -94,7 +94,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   std::string targetNameReal;
   std::string targetNameImport;
   std::string targetNamePDB;
-  this->Target->GetExecutableNames
+  this->GeneratorTarget->GetExecutableNames
     (targetName, targetNameReal, targetNameImport, targetNamePDB,
      this->ConfigName);
 
@@ -130,7 +130,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
     }
 
   std::string compilePdbOutputPath =
-    this->Target->GetCompilePDBDirectory(this->ConfigName);
+    this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
   cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
 
   std::string pdbOutputPath = this->Target->GetPDBDirectory(this->ConfigName);
@@ -161,7 +161,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
 
   // Get the language to use for linking this executable.
   std::string linkLanguage =
-    this->Target->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
 
   // Make sure we have a link language.
   if(linkLanguage.empty())
@@ -353,6 +353,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
                           useResponseFileForObjects, buildObjs, depends,
                           useWatcomQuote);
 
+  std::string manifests = this->GetManifests();
+
   cmLocalGenerator::RuleVariables vars;
   vars.RuleLauncher = "RULE_LAUNCH_LINK";
   vars.CMTarget = this->Target;
@@ -391,6 +393,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   vars.LinkLibraries = linkLibs.c_str();
   vars.Flags = flags.c_str();
   vars.LinkFlags = linkFlags.c_str();
+  vars.Manifests = manifests.c_str();
+
   // Expand placeholders in the commands.
   this->LocalGenerator->TargetImplib = targetOutPathImport;
   for(std::vector<std::string>::iterator i = real_link_commands.begin();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 450f573..cd387a0 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -18,16 +18,17 @@
 #include "cmSourceFile.h"
 #include "cmTarget.h"
 #include "cmake.h"
+#include "cmAlgorithms.h"
 
 //----------------------------------------------------------------------------
 cmMakefileLibraryTargetGenerator
 ::cmMakefileLibraryTargetGenerator(cmGeneratorTarget* target):
-  cmMakefileTargetGenerator(target->Target)
+  cmMakefileTargetGenerator(target)
 {
   this->CustomCommandDriver = OnDepends;
   if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
     {
-    this->Target->GetLibraryNames(
+    this->GeneratorTarget->GetLibraryNames(
       this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
       this->TargetNameImport, this->TargetNamePDB, this->ConfigName);
     }
@@ -68,7 +69,7 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
       break;
     case cmTarget::SHARED_LIBRARY:
       this->WriteSharedLibraryRules(false);
-      if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+      if(this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName))
         {
         // Write rules to link an installable version of the target.
         this->WriteSharedLibraryRules(true);
@@ -76,7 +77,7 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
       break;
     case cmTarget::MODULE_LIBRARY:
       this->WriteModuleLibraryRules(false);
-      if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+      if(this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName))
         {
         // Write rules to link an installable version of the target.
         this->WriteModuleLibraryRules(true);
@@ -132,7 +133,7 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
 void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
 {
   std::string linkLanguage =
-    this->Target->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
   std::string linkRuleVar = "CMAKE_";
   linkRuleVar += linkLanguage;
   linkRuleVar += "_CREATE_STATIC_LIBRARY";
@@ -158,7 +159,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
     return;
     }
   std::string linkLanguage =
-    this->Target->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
   std::string linkRuleVar = "CMAKE_";
   linkRuleVar += linkLanguage;
   linkRuleVar += "_CREATE_SHARED_LIBRARY";
@@ -182,7 +183,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
 void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
 {
   std::string linkLanguage =
-    this->Target->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
   std::string linkRuleVar = "CMAKE_";
   linkRuleVar += linkLanguage;
   linkRuleVar += "_CREATE_SHARED_MODULE";
@@ -205,7 +206,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
 void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
 {
   std::string linkLanguage =
-    this->Target->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
   std::string linkRuleVar = "CMAKE_";
   linkRuleVar += linkLanguage;
   linkRuleVar += "_CREATE_MACOSX_FRAMEWORK";
@@ -237,7 +238,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
 
   // Get the language to use for linking this library.
   std::string linkLanguage =
-    this->Target->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
 
   // Make sure we have a link language.
   if(linkLanguage.empty())
@@ -265,7 +266,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
   std::string targetNameReal;
   std::string targetNameImport;
   std::string targetNamePDB;
-  this->Target->GetLibraryNames(
+  this->GeneratorTarget->GetLibraryNames(
     targetName, targetNameSO, targetNameReal, targetNameImport, targetNamePDB,
     this->ConfigName);
 
@@ -310,7 +311,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
     }
 
   std::string compilePdbOutputPath =
-    this->Target->GetCompilePDBDirectory(this->ConfigName);
+    this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
   cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
 
   std::string pdbOutputPath = this->Target->GetPDBDirectory(this->ConfigName);
@@ -563,6 +564,60 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
                           useResponseFileForObjects, buildObjs, depends,
                           useWatcomQuote);
 
+  // maybe create .def file from list of objects
+  if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if(this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      std::string name_of_def_file =
+        this->Target->GetSupportDirectory();
+      name_of_def_file += std::string("/") +
+        this->Target->GetName();
+      name_of_def_file += ".def";
+      std::string cmd = cmSystemTools::GetCMakeCommand();
+      cmd = this->Convert(cmd, cmLocalGenerator::NONE,
+                          cmLocalGenerator::SHELL);
+      cmd += " -E __create_def ";
+      cmd += this->Convert(name_of_def_file,
+                           cmLocalGenerator::START_OUTPUT,
+                           cmLocalGenerator::SHELL);
+      cmd += " ";
+      std::string objlist_file = name_of_def_file;
+      objlist_file += ".objs";
+      cmd += this->Convert(objlist_file,
+                           cmLocalGenerator::START_OUTPUT,
+                           cmLocalGenerator::SHELL);
+      real_link_commands.push_back(cmd);
+      // create a list of obj files for the -E __create_def to read
+      cmGeneratedFileStream fout(objlist_file.c_str());
+      for(std::vector<std::string>::const_iterator i = this->Objects.begin();
+          i != this->Objects.end(); ++i)
+        {
+        if(cmHasLiteralSuffix(*i, ".obj"))
+          {
+          fout << *i << "\n";
+          }
+        }
+      for(std::vector<std::string>::const_iterator i =
+        this->ExternalObjects.begin();
+          i != this->ExternalObjects.end(); ++i)
+        {
+        fout << *i << "\n";
+        }
+      // now add the def file link flag
+      linkFlags += " ";
+      linkFlags +=
+        this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+      linkFlags += this->Convert(name_of_def_file,
+                                 cmLocalGenerator::START_OUTPUT,
+                                 cmLocalGenerator::SHELL);
+      linkFlags += " ";
+      }
+    }
+
+  std::string manifests = this->GetManifests();
+
   cmLocalGenerator::RuleVariables vars;
   vars.TargetPDB = targetOutPathPDB.c_str();
 
@@ -600,20 +655,22 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
   vars.Target = target.c_str();
   vars.LinkLibraries = linkLibs.c_str();
   vars.ObjectsQuoted = buildObjs.c_str();
-  if (this->Target->HasSOName(this->ConfigName))
+  if (this->GeneratorTarget->HasSOName(this->ConfigName))
     {
     vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
     vars.TargetSOName= targetNameSO.c_str();
     }
   vars.LinkFlags = linkFlags.c_str();
 
+  vars.Manifests = manifests.c_str();
+
   // Compute the directory portion of the install_name setting.
   std::string install_name_dir;
   if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
     {
     // Get the install_name directory for the build tree.
     install_name_dir =
-      this->Target->GetInstallNameDirForBuildTree(this->ConfigName);
+      this->GeneratorTarget->GetInstallNameDirForBuildTree(this->ConfigName);
 
     // Set the rule variable replacement value.
     if(install_name_dir.empty())
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 7b88bc7..b278087 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -32,25 +32,20 @@
 
 #include <ctype.h>
 
-cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
-  : OSXBundleGenerator(0)
+cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
+  : cmCommonTargetGenerator(cmOutputConverter::START_OUTPUT, target)
+  , OSXBundleGenerator(0)
   , MacOSXContentGenerator(0)
 {
   this->BuildFileStream = 0;
   this->InfoFileStream = 0;
   this->FlagFileStream = 0;
   this->CustomCommandDriver = OnBuild;
-  this->FortranModuleDirectoryComputed = false;
-  this->Target = target;
-  this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator =
-    static_cast<cmLocalUnixMakefileGenerator3*>(
-      this->Makefile->GetLocalGenerator());
-  this->ConfigName = this->LocalGenerator->ConfigurationName.c_str();
+    static_cast<cmLocalUnixMakefileGenerator3*>(target->GetLocalGenerator());
   this->GlobalGenerator =
     static_cast<cmGlobalUnixMakefileGenerator3*>(
       this->LocalGenerator->GetGlobalGenerator());
-  this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target);
   cmake* cm = this->GlobalGenerator->GetCMakeInstance();
   this->NoRuleMessages = false;
   if(const char* ruleStatus = cm->GetState()
@@ -172,7 +167,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
     {
     cmCustomCommandGenerator ccg(*(*si)->GetCustomCommand(),
                                  this->ConfigName,
-                                 this->Makefile);
+                                 this->LocalGenerator);
     this->GenerateCustomRuleFile(ccg);
     if (clean)
       {
@@ -277,85 +272,11 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
     << "\n\n";
 }
 
-//----------------------------------------------------------------------------
-std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
-{
-  ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
-  if (i == this->FlagsByLanguage.end())
-    {
-    std::string flags;
-    const char *lang = l.c_str();
-
-    // Add language feature flags.
-    this->AddFeatureFlags(flags, lang);
-
-    this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
-                                               lang, this->ConfigName);
-
-    // Fortran-specific flags computed for this target.
-    if(l == "Fortran")
-      {
-      this->AddFortranFlags(flags);
-      }
-
-    this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
-                                          lang, this->ConfigName);
-
-    this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target,
-                                                   lang);
-
-    // Add include directory flags.
-    this->AddIncludeFlags(flags, lang);
-
-    // Append old-style preprocessor definition flags.
-    this->LocalGenerator->
-      AppendFlags(flags, this->Makefile->GetDefineFlags());
-
-    // Add include directory flags.
-    this->LocalGenerator->
-      AppendFlags(flags,this->GetFrameworkFlags(l));
-
-    // Add target-specific flags.
-    this->LocalGenerator->AddCompileOptions(flags, this->Target,
-                                            lang, this->ConfigName);
-
-    ByLanguageMap::value_type entry(l, flags);
-    i = this->FlagsByLanguage.insert(entry).first;
-    }
-  return i->second;
-}
-
-std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
-{
-  ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
-  if (i == this->DefinesByLanguage.end())
-    {
-    std::set<std::string> defines;
-    const char *lang = l.c_str();
-    // Add the export symbol definition for shared library objects.
-    if(const char* exportMacro = this->Target->GetExportMacro())
-      {
-      this->LocalGenerator->AppendDefines(defines, exportMacro);
-      }
-
-    // Add preprocessor definitions for this target and configuration.
-    this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
-                            this->LocalGenerator->ConfigurationName, l);
-
-    std::string definesString;
-    this->LocalGenerator->JoinDefines(defines, definesString, lang);
-
-    ByLanguageMap::value_type entry(l, definesString);
-    i = this->DefinesByLanguage.insert(entry).first;
-    }
-  return i->second;
-}
-
 void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
 {
   // write language flags for target
   std::set<std::string> languages;
-  this->Target->GetLanguages(languages,
+  this->GeneratorTarget->GetLanguages(languages,
                       this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   // put the compiler in the rules.make file so that if it changes
   // things rebuild
@@ -374,11 +295,14 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
     {
     std::string flags = this->GetFlags(*l);
     std::string defines = this->GetDefines(*l);
+    std::string includes = this->GetIncludes(*l);
     // Escape comment characters so they do not terminate assignment.
     cmSystemTools::ReplaceString(flags, "#", "\\#");
     cmSystemTools::ReplaceString(defines, "#", "\\#");
+    cmSystemTools::ReplaceString(includes, "#", "\\#");
     *this->FlagFileStream << *l << "_FLAGS = " << flags << "\n\n";
     *this->FlagFileStream << *l << "_DEFINES = " << defines << "\n\n";
+    *this->FlagFileStream << *l << "_INCLUDES = " << includes << "\n\n";
     }
 }
 
@@ -389,7 +313,7 @@ cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
   (cmSourceFile const& source, const char* pkgloc)
 {
   // Skip OS X content when not building a Framework or Bundle.
-  if(!this->Generator->GetTarget()->IsBundleOnApple())
+  if(!this->Generator->GetGeneratorTarget()->IsBundleOnApple())
     {
     return;
     }
@@ -490,7 +414,6 @@ void cmMakefileTargetGenerator
   // we compute some depends when writing the depend.make that we will also
   // use in the build.make, same with depMakeFile
   std::vector<std::string> depends;
-  std::string depMakeFile;
 
   // generate the build rule file
   this->WriteObjectBuildFile(obj, lang, source, depends);
@@ -512,35 +435,6 @@ void cmMakefileTargetGenerator
 //----------------------------------------------------------------------------
 void
 cmMakefileTargetGenerator
-::AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source)
-{
-  const char* srcfmt = source.GetProperty("Fortran_FORMAT");
-  cmLocalGenerator::FortranFormat format =
-    this->LocalGenerator->GetFortranFormat(srcfmt);
-  if(format == cmLocalGenerator::FortranFormatNone)
-    {
-    const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT");
-    format = this->LocalGenerator->GetFortranFormat(tgtfmt);
-    }
-  const char* var = 0;
-  switch (format)
-    {
-    case cmLocalGenerator::FortranFormatFixed:
-      var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break;
-    case cmLocalGenerator::FortranFormatFree:
-      var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break;
-    default: break;
-    }
-  if(var)
-    {
-    this->LocalGenerator->AppendFlags(
-      flags, this->Makefile->GetDefinition(var));
-    }
-}
-
-//----------------------------------------------------------------------------
-void
-cmMakefileTargetGenerator
 ::WriteObjectBuildFile(std::string &obj,
                        const std::string& lang,
                        cmSourceFile const& source,
@@ -568,7 +462,7 @@ cmMakefileTargetGenerator
   this->LocalGenerator->AppendFlags(flags, langFlags);
 
   std::string configUpper =
-    cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
+    cmSystemTools::UpperCase(this->LocalGenerator->GetConfigName());
 
   // Add Fortran format flags.
   if(lang == "Fortran")
@@ -614,13 +508,7 @@ cmMakefileTargetGenerator
     }
 
   // Get the output paths for source and object files.
-  std::string sourceFile = source.GetFullPath();
-  if(this->LocalGenerator->UseRelativePaths)
-    {
-    sourceFile = this->Convert(sourceFile,
-                               cmLocalGenerator::START_OUTPUT);
-    }
-  sourceFile = this->Convert(sourceFile,
+  std::string sourceFile = this->Convert(source.GetFullPath(),
                              cmLocalGenerator::NONE,
                              cmLocalGenerator::SHELL);
 
@@ -657,15 +545,15 @@ cmMakefileTargetGenerator
      this->Target->GetType() == cmTarget::MODULE_LIBRARY)
     {
     targetFullPathReal =
-      this->Target->GetFullPath(this->ConfigName, false, true);
+      this->GeneratorTarget->GetFullPath(this->ConfigName, false, true);
     targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName);
     targetFullPathPDB += "/";
-    targetFullPathPDB += this->Target->GetPDBName(this->ConfigName);
+    targetFullPathPDB += this->GeneratorTarget->GetPDBName(this->ConfigName);
     }
   if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
     {
     targetFullPathCompilePDB =
-      this->Target->GetCompilePDBPath(this->ConfigName);
+      this->GeneratorTarget->GetCompilePDBPath(this->ConfigName);
     if(targetFullPathCompilePDB.empty())
       {
       targetFullPathCompilePDB = this->Target->GetSupportDirectory() + "/";
@@ -725,6 +613,9 @@ cmMakefileTargetGenerator
 
   vars.Defines = definesString.c_str();
 
+  std::string const includesString = "$(" + lang + "_INCLUDES)";
+  vars.Includes = includesString.c_str();
+
   // At the moment, it is assumed that C, C++, and Fortran have both
   // assembly and preprocessor capabilities. The same is true for the
   // ability to export compile commands
@@ -757,6 +648,9 @@ cmMakefileTargetGenerator
     std::string langDefines = std::string("$(") + lang + "_DEFINES)";
     compileCommand.replace(compileCommand.find(langDefines),
                            langDefines.size(), this->GetDefines(lang));
+    std::string langIncludes = std::string("$(") + lang + "_INCLUDES)";
+    compileCommand.replace(compileCommand.find(langIncludes),
+                           langIncludes.size(), this->GetIncludes(lang));
     this->GlobalGenerator->AddCXXCompileCommand(
       source.GetFullPath(), workingDirectory, compileCommand);
     }
@@ -775,6 +669,25 @@ cmMakefileTargetGenerator
       }
     }
 
+  // Maybe insert a compiler launcher like ccache or distcc
+  if (!compileCommands.empty() && (lang == "C" || lang == "CXX"))
+    {
+    std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
+    const char *clauncher = this->Target->GetProperty(clauncher_prop);
+    if (clauncher && *clauncher)
+      {
+      std::vector<std::string> launcher_cmd;
+      cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
+      for (std::vector<std::string>::iterator i = launcher_cmd.begin(),
+             e = launcher_cmd.end(); i != e; ++i)
+        {
+        *i = this->LocalGenerator->EscapeForShell(*i);
+        }
+      std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
+      compileCommands.front().insert(0, run_launcher);
+      }
+    }
+
   // Expand placeholders in the commands.
   for(std::vector<std::string>::iterator i = compileCommands.begin();
       i != compileCommands.end(); ++i)
@@ -1132,8 +1045,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
         pi != this->MultipleOutputPairs.end(); ++pi)
       {
       *this->InfoFileStream
-        << "  " << cmLocalGenerator::EscapeForCMake(pi->first)
-        << " "  << cmLocalGenerator::EscapeForCMake(pi->second)
+        << "  " << cmOutputConverter::EscapeForCMake(pi->first)
+        << " "  << cmOutputConverter::EscapeForCMake(pi->second)
         << "\n";
       }
     *this->InfoFileStream << "  )\n\n";
@@ -1145,44 +1058,21 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
     << "\n"
     << "# Targets to which this target links.\n"
     << "set(CMAKE_TARGET_LINKED_INFO_FILES\n";
-  std::set<cmTarget const*> emitted;
-  const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
-  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
+  std::vector<std::string> dirs = this->GetLinkedTargetDirectories();
+  for (std::vector<std::string>::iterator i = dirs.begin();
+       i != dirs.end(); ++i)
     {
-    cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
-    for(cmComputeLinkInformation::ItemVector::const_iterator
-          i = items.begin(); i != items.end(); ++i)
-      {
-      cmTarget const* linkee = i->Target;
-      if(linkee && !linkee->IsImported()
-                // We can ignore the INTERFACE_LIBRARY items because
-                // Target->GetLinkInformation already processed their
-                // link interface and they don't have any output themselves.
-                && linkee->GetType() != cmTarget::INTERFACE_LIBRARY
-                && emitted.insert(linkee).second)
-        {
-        cmMakefile* mf = linkee->GetMakefile();
-        cmLocalGenerator* lg = mf->GetLocalGenerator();
-        std::string di = mf->GetCurrentBinaryDirectory();
-        di += "/";
-        di += lg->GetTargetDirectory(*linkee);
-        di += "/DependInfo.cmake";
-        *this->InfoFileStream << "  \"" << di << "\"\n";
-        }
-      }
+    *this->InfoFileStream << "  \"" << *i << "/DependInfo.cmake\"\n";
     }
   *this->InfoFileStream
     << "  )\n";
   }
 
-  // Check for a target-specific module output directory.
-  if(const char* mdir = this->GetFortranModuleDirectory())
-    {
-    *this->InfoFileStream
-      << "\n"
-      << "# Fortran module output directory.\n"
-      << "set(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n";
-    }
+  *this->InfoFileStream
+    << "\n"
+    << "# Fortran module output directory.\n"
+    << "set(CMAKE_Fortran_TARGET_MODULE_DIR \""
+    << this->GetFortranModuleDirectory() << "\")\n";
 
   // and now write the rule to use it
   std::vector<std::string> depends;
@@ -1266,7 +1156,8 @@ cmMakefileTargetGenerator
     {
     if(cmCustomCommand* cc = (*source)->GetCustomCommand())
       {
-      cmCustomCommandGenerator ccg(*cc, this->ConfigName, this->Makefile);
+      cmCustomCommandGenerator ccg(*cc, this->ConfigName,
+                                   this->LocalGenerator);
       const std::vector<std::string>& outputs = ccg.GetOutputs();
       depends.insert(depends.end(), outputs.begin(), outputs.end());
       }
@@ -1544,68 +1435,6 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(
 }
 
 //----------------------------------------------------------------------------
-std::string cmMakefileTargetGenerator::GetFrameworkFlags(std::string const& l)
-{
- if(!this->Makefile->IsOn("APPLE"))
-   {
-   return std::string();
-   }
-
-  std::string fwSearchFlagVar = "CMAKE_" + l + "_FRAMEWORK_SEARCH_FLAG";
-  const char* fwSearchFlag =
-    this->Makefile->GetDefinition(fwSearchFlagVar);
-  if(!(fwSearchFlag && *fwSearchFlag))
-    {
-    return std::string();
-    }
-
- std::set<std::string> emitted;
-#ifdef __APPLE__  /* don't insert this when crosscompiling e.g. to iphone */
-  emitted.insert("/System/Library/Frameworks");
-#endif
-  std::vector<std::string> includes;
-
-  const std::string& config =
-    this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
-  this->LocalGenerator->GetIncludeDirectories(includes,
-                                              this->GeneratorTarget,
-                                              "C", config);
-  // check all include directories for frameworks as this
-  // will already have added a -F for the framework
-  for(std::vector<std::string>::iterator i = includes.begin();
-      i != includes.end(); ++i)
-    {
-    if(this->Target->NameResolvesToFramework(*i))
-      {
-      std::string frameworkDir = *i;
-      frameworkDir += "/../";
-      frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
-      emitted.insert(frameworkDir);
-      }
-    }
-
-  std::string flags;
-  const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
-  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
-    {
-    std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
-    for(std::vector<std::string>::const_iterator i = frameworks.begin();
-        i != frameworks.end(); ++i)
-      {
-      if(emitted.insert(*i).second)
-        {
-        flags += fwSearchFlag;
-        flags += this->Convert(*i,
-                               cmLocalGenerator::START_OUTPUT,
-                               cmLocalGenerator::SHELL, true);
-        flags += " ";
-        }
-      }
-    }
-  return flags;
-}
-
-//----------------------------------------------------------------------------
 void cmMakefileTargetGenerator
 ::AppendTargetDepends(std::vector<std::string>& depends)
 {
@@ -1616,8 +1445,9 @@ void cmMakefileTargetGenerator
     }
 
   // Loop over all library dependencies.
-  const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
-  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
+  const char* cfg = this->LocalGenerator->GetConfigName().c_str();
+  if(cmComputeLinkInformation* cli =
+                              this->GeneratorTarget->GetLinkInformation(cfg))
     {
     std::vector<std::string> const& libDeps = cli->GetDepends();
     depends.insert(depends.end(), libDeps.begin(), libDeps.end());
@@ -1658,11 +1488,18 @@ void cmMakefileTargetGenerator
   this->AppendTargetDepends(depends);
 
   // Add a dependency on the link definitions file, if any.
-  std::string def = this->GeneratorTarget->GetModuleDefinitionFile(
-                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
-  if(!def.empty())
+  if(!this->ModuleDefinitionFile.empty())
+    {
+    depends.push_back(this->ModuleDefinitionFile);
+    }
+
+  // Add a dependency on user-specified manifest files, if any.
+  std::vector<cmSourceFile const*> manifest_srcs;
+  this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+  for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin();
+       mi != manifest_srcs.end(); ++mi)
     {
-    depends.push_back(def);
+    depends.push_back((*mi)->GetFullPath());
     }
 
   // Add user-specified dependencies.
@@ -1681,7 +1518,7 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
   if(this->Target->HasImplibGNUtoMS())
     {
     std::string ruleVar = "CMAKE_";
-    ruleVar += this->Target->GetLinkerLanguage(this->ConfigName);
+    ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
     ruleVar += "_GNUtoMS_RULE";
     if(const char* rule = this->Makefile->GetDefinition(ruleVar))
       {
@@ -1835,7 +1672,8 @@ cmMakefileTargetGenerator
     {
     // Lookup the response file reference flag.
     std::string responseFlagVar = "CMAKE_";
-    responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName);
+    responseFlagVar += this->GeneratorTarget
+                           ->GetLinkerLanguage(this->ConfigName);
     responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
     const char* responseFlag =
       this->Makefile->GetDefinition(responseFlagVar);
@@ -1879,7 +1717,8 @@ cmMakefileTargetGenerator
 
     // Lookup the response file reference flag.
     std::string responseFlagVar = "CMAKE_";
-    responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName);
+    responseFlagVar += this->GeneratorTarget
+                           ->GetLinkerLanguage(this->ConfigName);
     responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
     const char* responseFlag =
       this->Makefile->GetDefinition(responseFlagVar);
@@ -1969,149 +1808,3 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
     this->LocalGenerator->AppendFlags(flags, includeFlags);
     }
 }
-
-//----------------------------------------------------------------------------
-const char* cmMakefileTargetGenerator::GetFortranModuleDirectory()
-{
-  // Compute the module directory.
-  if(!this->FortranModuleDirectoryComputed)
-    {
-    const char* target_mod_dir =
-      this->Target->GetProperty("Fortran_MODULE_DIRECTORY");
-    const char* moddir_flag =
-      this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
-    if(target_mod_dir && moddir_flag)
-      {
-      // Compute the full path to the module directory.
-      if(cmSystemTools::FileIsFullPath(target_mod_dir))
-        {
-        // Already a full path.
-        this->FortranModuleDirectory = target_mod_dir;
-        }
-      else
-        {
-        // Interpret relative to the current output directory.
-        this->FortranModuleDirectory =
-          this->Makefile->GetCurrentBinaryDirectory();
-        this->FortranModuleDirectory += "/";
-        this->FortranModuleDirectory += target_mod_dir;
-        }
-
-      // Make sure the module output directory exists.
-      cmSystemTools::MakeDirectory(this->FortranModuleDirectory.c_str());
-      }
-    this->FortranModuleDirectoryComputed = true;
-    }
-
-  // Return the computed directory.
-  if(this->FortranModuleDirectory.empty())
-    {
-    return 0;
-    }
-  else
-    {
-    return this->FortranModuleDirectory.c_str();
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
-{
-  // Enable module output if necessary.
-  if(const char* modout_flag =
-     this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG"))
-    {
-    this->LocalGenerator->AppendFlags(flags, modout_flag);
-    }
-
-  // Add a module output directory flag if necessary.
-  const char* mod_dir = this->GetFortranModuleDirectory();
-  if(!mod_dir)
-    {
-    mod_dir = this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
-    }
-  if(mod_dir)
-    {
-    const char* moddir_flag =
-      this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
-    std::string modflag = moddir_flag;
-    modflag += this->Convert(mod_dir,
-                             cmLocalGenerator::START_OUTPUT,
-                             cmLocalGenerator::SHELL);
-    this->LocalGenerator->AppendFlags(flags, modflag);
-    }
-
-  // If there is a separate module path flag then duplicate the
-  // include path with it.  This compiler does not search the include
-  // path for modules.
-  if(const char* modpath_flag =
-     this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG"))
-    {
-    std::vector<std::string> includes;
-    const std::string& config =
-      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
-    this->LocalGenerator->GetIncludeDirectories(includes,
-                                                this->GeneratorTarget,
-                                                "C", config);
-    for(std::vector<std::string>::const_iterator idi = includes.begin();
-        idi != includes.end(); ++idi)
-      {
-      std::string flg = modpath_flag;
-      flg += this->Convert(*idi,
-                           cmLocalGenerator::NONE,
-                           cmLocalGenerator::SHELL);
-      this->LocalGenerator->AppendFlags(flags, flg);
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
-{
-  std::string def = this->GeneratorTarget->GetModuleDefinitionFile(
-                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
-  if(def.empty())
-    {
-    return;
-    }
-
-  // TODO: Create a per-language flag variable.
-  const char* defFileFlag =
-    this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
-  if(!defFileFlag)
-    {
-    return;
-    }
-
-  // Append the flag and value.  Use ConvertToLinkReference to help
-  // vs6's "cl -link" pass it to the linker.
-  std::string flag = defFileFlag;
-  flag += (this->LocalGenerator->ConvertToLinkReference(def));
-  this->LocalGenerator->AppendFlags(flags, flag);
-}
-
-//----------------------------------------------------------------------------
-const char* cmMakefileTargetGenerator::GetFeature(const std::string& feature)
-{
-  return this->Target->GetFeature(feature, this->ConfigName);
-}
-
-//----------------------------------------------------------------------------
-bool cmMakefileTargetGenerator::GetFeatureAsBool(const std::string& feature)
-{
-  return this->Target->GetFeatureAsBool(feature, this->ConfigName);
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::AddFeatureFlags(
-  std::string& flags, const std::string& lang
-  )
-{
-  // Add language-specific flags.
-  this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);
-
-  if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
-    {
-    this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
-    }
-}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 58044e8..fd4527b 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -12,6 +12,8 @@
 #ifndef cmMakefileTargetGenerator_h
 #define cmMakefileTargetGenerator_h
 
+#include "cmCommonTargetGenerator.h"
+
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmOSXBundleGenerator.h"
 
@@ -30,11 +32,11 @@ class cmSourceFile;
  * \brief Support Routines for writing makefiles
  *
  */
-class cmMakefileTargetGenerator
+class cmMakefileTargetGenerator: public cmCommonTargetGenerator
 {
 public:
   // constructor to set the ivars
-  cmMakefileTargetGenerator(cmTarget* target);
+  cmMakefileTargetGenerator(cmGeneratorTarget* target);
   virtual ~cmMakefileTargetGenerator();
 
   // construct using this factory call
@@ -51,6 +53,7 @@ public:
     { return this->ProgressFileNameFull; }
 
   cmTarget* GetTarget() { return this->Target;}
+  cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget;}
 
 protected:
 
@@ -124,12 +127,6 @@ protected:
 
   void DriveCustomCommands(std::vector<std::string>& depends);
 
-  // Return the a string with -F flags on apple
-  std::string GetFrameworkFlags(std::string const& l);
-
-  void AppendFortranFormatFlags(std::string& flags,
-                                cmSourceFile const& source);
-
   // append intertarget dependencies
   void AppendTargetDepends(std::vector<std::string>& depends);
 
@@ -173,12 +170,8 @@ protected:
   virtual void CloseFileStreams();
   void RemoveForbiddenFlags(const char* flagVar, const std::string& linkLang,
                             std::string& linkFlags);
-  cmTarget *Target;
-  cmGeneratorTarget* GeneratorTarget;
   cmLocalUnixMakefileGenerator3 *LocalGenerator;
   cmGlobalUnixMakefileGenerator3 *GlobalGenerator;
-  cmMakefile *Makefile;
-  std::string ConfigName;
 
   enum CustomCommandDriveType { OnBuild, OnDepends, OnUtility };
   CustomCommandDriveType CustomCommandDriver;
@@ -242,43 +235,6 @@ protected:
   std::set<std::string> MacContentFolders;
   cmOSXBundleGenerator* OSXBundleGenerator;
   MacOSXContentGeneratorType* MacOSXContentGenerator;
-
-  typedef std::map<std::string, std::string> ByLanguageMap;
-  std::string GetFlags(const std::string &l);
-  ByLanguageMap FlagsByLanguage;
-  std::string GetDefines(const std::string &l);
-  ByLanguageMap DefinesByLanguage;
-
-  // Target-wide Fortran module output directory.
-  bool FortranModuleDirectoryComputed;
-  std::string FortranModuleDirectory;
-  const char* GetFortranModuleDirectory();
-
-  // Compute target-specific Fortran language flags.
-  void AddFortranFlags(std::string& flags);
-
-  // Helper to add flag for windows .def file.
-  void AddModuleDefinitionFlag(std::string& flags);
-
-  // Add language feature flags.
-  void AddFeatureFlags(std::string& flags, const std::string& lang);
-
-  // Feature query methods.
-  const char* GetFeature(const std::string& feature);
-  bool GetFeatureAsBool(const std::string& feature);
-
-  //==================================================================
-  // Convenience routines that do nothing more than forward to
-  // implementaitons
-  std::string Convert(const std::string& source,
-                      cmLocalGenerator::RelativeRoot relative,
-                      cmLocalGenerator::OutputFormat output =
-                      cmLocalGenerator::UNCHANGED,
-                      bool optional = false)
-  {
-    return this->LocalGenerator->Convert(source, relative, output, optional);
-  }
-
 };
 
 #endif
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 25d929c..303ca63 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -21,7 +21,7 @@
 //----------------------------------------------------------------------------
 cmMakefileUtilityTargetGenerator
 ::cmMakefileUtilityTargetGenerator(cmGeneratorTarget* target):
-  cmMakefileTargetGenerator(target->Target)
+  cmMakefileTargetGenerator(target)
 {
   this->CustomCommandDriver = OnUtility;
   this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 0449c50..2854a82 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -69,7 +69,7 @@ bool cmMessageCommand
     ++i;
     }
 
-  std::string message = cmJoin(cmRange(i, args.end()), std::string());
+  std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
 
   if (type != cmake::MESSAGE)
     {
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index bbf03ff..84c19a3 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -32,7 +32,7 @@
 
 cmNinjaNormalTargetGenerator::
 cmNinjaNormalTargetGenerator(cmGeneratorTarget* target)
-  : cmNinjaTargetGenerator(target->Target)
+  : cmNinjaTargetGenerator(target)
   , TargetNameOut()
   , TargetNameSO()
   , TargetNameReal()
@@ -40,16 +40,15 @@ cmNinjaNormalTargetGenerator(cmGeneratorTarget* target)
   , TargetNamePDB()
   , TargetLinkLanguage("")
 {
-  this->TargetLinkLanguage = target->Target
-                                   ->GetLinkerLanguage(this->GetConfigName());
+  this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
   if (target->GetType() == cmTarget::EXECUTABLE)
-    target->Target->GetExecutableNames(this->TargetNameOut,
+    this->GetGeneratorTarget()->GetExecutableNames(this->TargetNameOut,
                                this->TargetNameReal,
                                this->TargetNameImport,
                                this->TargetNamePDB,
                                GetLocalGenerator()->GetConfigName());
   else
-    target->Target->GetLibraryNames(this->TargetNameOut,
+    this->GetGeneratorTarget()->GetLibraryNames(this->TargetNameOut,
                             this->TargetNameSO,
                             this->TargetNameReal,
                             this->TargetNameImport,
@@ -238,6 +237,7 @@ cmNinjaNormalTargetGenerator
 
     vars.Flags = "$FLAGS";
     vars.LinkFlags = "$LINK_FLAGS";
+    vars.Manifests = "$MANIFESTS";
 
     std::string langFlags;
     if (targetType != cmTarget::EXECUTABLE)
@@ -398,15 +398,16 @@ static int calculateCommandLineLengthLimit(int linkRuleLength)
 void cmNinjaNormalTargetGenerator::WriteLinkStatement()
 {
   cmTarget& target = *this->GetTarget();
+  cmGeneratorTarget& gt = *this->GetGeneratorTarget();
   const std::string cfgName = this->GetConfigName();
   std::string targetOutput = ConvertToNinjaPath(
-                               target.GetFullPath(cfgName));
+                               gt.GetFullPath(cfgName));
   std::string targetOutputReal = ConvertToNinjaPath(
-                                   target.GetFullPath(cfgName,
+                                   gt.GetFullPath(cfgName,
                                       /*implib=*/false,
                                       /*realpath=*/true));
   std::string targetOutputImplib = ConvertToNinjaPath(
-                                     target.GetFullPath(cfgName,
+                                     gt.GetFullPath(cfgName,
                                        /*implib=*/true));
 
   if (target.IsAppBundleOnApple())
@@ -486,6 +487,22 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
                           linkPath,
                           &genTarget,
                           useWatcomQuote);
+  if(this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")
+     && target.GetType() == cmTarget::SHARED_LIBRARY)
+    {
+    if(target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      std::string dllname = targetOutput;
+      std::string name_of_def_file
+        = target.GetSupportDirectory();
+      name_of_def_file += "/" + target.GetName();
+      name_of_def_file += ".def ";
+      vars["LINK_FLAGS"] += " /DEF:";
+      vars["LINK_FLAGS"] += this->GetLocalGenerator()
+        ->ConvertToOutputFormat(name_of_def_file.c_str(),
+                                cmLocalGenerator::SHELL);
+      }
+    }
 
   this->addPoolNinjaVariable("JOB_POOL_LINK", &target, vars);
 
@@ -493,6 +510,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   vars["LINK_FLAGS"] = cmGlobalNinjaGenerator
                         ::EncodeLiteral(vars["LINK_FLAGS"]);
 
+  vars["MANIFESTS"] = this->GetManifests();
+
   vars["LINK_PATH"] = frameworkPath + linkPath;
 
   // Compute architecture specific link flags.  Yes, these go into a different
@@ -514,13 +533,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     vars["LANGUAGE_COMPILE_FLAGS"] = t;
     }
 
-  if (target.HasSOName(cfgName))
+  if (this->GetGeneratorTarget()->HasSOName(cfgName))
     {
     vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
     vars["SONAME"] = this->TargetNameSO;
     if (targetType == cmTarget::SHARED_LIBRARY)
       {
-      std::string install_dir = target.GetInstallNameDirForBuildTree(cfgName);
+      std::string install_dir =
+          this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(cfgName);
       if (!install_dir.empty())
         {
         vars["INSTALLNAME_DIR"] = localGen.Convert(install_dir,
@@ -530,6 +550,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
       }
     }
 
+  cmNinjaDeps byproducts;
+
   if (!this->TargetNameImport.empty())
     {
     const std::string impLibPath = localGen.ConvertToOutputFormat(
@@ -539,7 +561,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     EnsureParentDirectoryExists(impLibPath);
     if(target.HasImportLibrary())
       {
-      outputs.push_back(targetOutputImplib);
+      byproducts.push_back(targetOutputImplib);
       }
     }
 
@@ -550,7 +572,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     std::string prefix;
     std::string base;
     std::string suffix;
-    target.GetFullNameComponents(prefix, base, suffix);
+    this->GetGeneratorTarget()->GetFullNameComponents(prefix, base, suffix);
     std::string dbg_suffix = ".dbg";
     // TODO: Where to document?
     if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX"))
@@ -560,11 +582,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     vars["TARGET_PDB"] = base + suffix + dbg_suffix;
     }
 
+  const std::string objPath = GetTarget()->GetSupportDirectory();
+  vars["OBJECT_DIR"] =
+    this->GetLocalGenerator()->ConvertToOutputFormat(
+      this->ConvertToNinjaPath(objPath), cmLocalGenerator::SHELL);
+  EnsureDirectoryExists(objPath);
+
   if (this->GetGlobalGenerator()->IsGCCOnWindows())
     {
-    const std::string objPath = GetTarget()->GetSupportDirectory();
-    vars["OBJECT_DIR"] = ConvertToNinjaPath(objPath);
-    EnsureDirectoryExists(objPath);
     // ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
     std::string& linkLibraries = vars["LINK_LIBRARIES"];
     std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
@@ -585,14 +610,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     &postBuildCmdLines
   };
 
-  cmNinjaDeps byproducts;
   for (unsigned i = 0; i != 3; ++i)
     {
     for (std::vector<cmCustomCommand>::const_iterator
          ci = cmdLists[i]->begin();
          ci != cmdLists[i]->end(); ++ci)
       {
-      cmCustomCommandGenerator ccg(*ci, cfgName, mf);
+      cmCustomCommandGenerator ccg(*ci, cfgName, this->GetLocalGenerator());
       localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
       std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
       std::transform(ccByproducts.begin(), ccByproducts.end(),
@@ -600,6 +624,43 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
       }
     }
 
+  // maybe create .def file from list of objects
+  if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+      this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if(target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      std::string cmakeCommand =
+      this->GetLocalGenerator()->ConvertToOutputFormat(
+        cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+      std::string name_of_def_file
+        = target.GetSupportDirectory();
+      name_of_def_file += "/" + target.GetName();
+      name_of_def_file += ".def";
+      std::string cmd = cmakeCommand;
+      cmd += " -E __create_def ";
+      cmd += this->GetLocalGenerator()
+        ->ConvertToOutputFormat(name_of_def_file.c_str(),
+                                cmLocalGenerator::SHELL);
+      cmd += " ";
+      cmNinjaDeps objs = this->GetObjects();
+      std::string obj_list_file = name_of_def_file;
+      obj_list_file += ".objs";
+      cmd += this->GetLocalGenerator()
+        ->ConvertToOutputFormat(obj_list_file.c_str(),
+                                cmLocalGenerator::SHELL);
+      preLinkCmdLines.push_back(cmd);
+      // create a list of obj files for the -E __create_def to read
+      cmGeneratedFileStream fout(obj_list_file.c_str());
+      for(cmNinjaDeps::iterator i=objs.begin(); i != objs.end(); ++i)
+        {
+        if(cmHasLiteralSuffix(*i, ".obj"))
+          {
+          fout << *i << "\n";
+          }
+        }
+      }
+    }
   // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for
   // the link commands.
   if (!preLinkCmdLines.empty())
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 879d6b7..6e6dc60 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -22,6 +22,7 @@
 #include "cmComputeLinkInformation.h"
 #include "cmSourceFile.h"
 #include "cmCustomCommandGenerator.h"
+#include "cmAlgorithms.h"
 
 #include <algorithm>
 
@@ -56,19 +57,15 @@ cmNinjaTargetGenerator::New(cmGeneratorTarget* target)
     }
 }
 
-cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target)
-  :
+cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmGeneratorTarget* target)
+  : cmCommonTargetGenerator(cmOutputConverter::HOME_OUTPUT, target),
     MacOSXContentGenerator(0),
     OSXBundleGenerator(0),
     MacContentFolders(),
-    Target(target),
-    Makefile(target->GetMakefile()),
     LocalGenerator(
-      static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())),
+      static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator())),
     Objects()
 {
-  this->GeneratorTarget =
-    this->GetGlobalGenerator()->GetGeneratorTarget(target);
   MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
 }
 
@@ -92,11 +89,6 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
   return this->LocalGenerator->GetGlobalNinjaGenerator();
 }
 
-std::string const& cmNinjaTargetGenerator::GetConfigName() const
-{
-  return this->LocalGenerator->GetConfigName();
-}
-
 std::string cmNinjaTargetGenerator::LanguageCompilerRule(
   const std::string& lang) const
 {
@@ -104,31 +96,6 @@ std::string cmNinjaTargetGenerator::LanguageCompilerRule(
     cmGlobalNinjaGenerator::EncodeRuleName(this->Target->GetName());
 }
 
-// TODO: Picked up from cmMakefileTargetGenerator.  Refactor it.
-const char* cmNinjaTargetGenerator::GetFeature(const std::string& feature)
-{
-  return this->Target->GetFeature(feature, this->GetConfigName());
-}
-
-// TODO: Picked up from cmMakefileTargetGenerator.  Refactor it.
-bool cmNinjaTargetGenerator::GetFeatureAsBool(const std::string& feature)
-{
-  return this->Target->GetFeatureAsBool(feature, this->GetConfigName());
-}
-
-// TODO: Picked up from cmMakefileTargetGenerator.  Refactor it.
-void cmNinjaTargetGenerator::AddFeatureFlags(std::string& flags,
-                                             const std::string& lang)
-{
-  // Add language-specific flags.
-  this->LocalGenerator->AddLanguageFlags(flags, lang, this->GetConfigName());
-
-  if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
-    {
-    this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
-    }
-}
-
 std::string
 cmNinjaTargetGenerator::OrderDependsTargetForTarget()
 {
@@ -143,71 +110,43 @@ std::string
 cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile const* source,
                                               const std::string& language)
 {
-  // TODO: Fortran support.
-  // // Fortran-specific flags computed for this target.
-  // if(*l == "Fortran")
-  //   {
-  //   this->AddFortranFlags(flags);
-  //   }
-
-  bool hasLangCached = this->LanguageFlags.count(language) != 0;
-  std::string& languageFlags = this->LanguageFlags[language];
-  if(!hasLangCached)
-    {
-    this->AddFeatureFlags(languageFlags, language);
-
-    this->GetLocalGenerator()->AddArchitectureFlags(languageFlags,
-                                                    this->GeneratorTarget,
-                                                    language,
-                                                    this->GetConfigName());
+  std::string flags = this->GetFlags(language);
 
-    // Add shared-library flags if needed.
-    this->LocalGenerator->AddCMP0018Flags(languageFlags, this->Target,
-                                          language,
-                                          this->GetConfigName());
-
-    this->LocalGenerator->AddVisibilityPresetFlags(languageFlags, this->Target,
-                                                   language);
-
-    std::vector<std::string> includes;
-    this->LocalGenerator->GetIncludeDirectories(includes,
-                                                this->GeneratorTarget,
-                                                language,
-                                                this->GetConfigName());
-    // Add include directory flags.
-    std::string includeFlags =
-      this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget,
-                                            language,
-      language == "RC" ? true : false,  // full include paths for RC
-                                        // needed by cmcldeps
-                                            false,
-                                            this->GetConfigName());
-    if (this->GetGlobalGenerator()->IsGCCOnWindows())
-      cmSystemTools::ReplaceString(includeFlags, "\\", "/");
-
-    this->LocalGenerator->AppendFlags(languageFlags, includeFlags);
-
-    // Append old-style preprocessor definition flags.
-    this->LocalGenerator->AppendFlags(languageFlags,
-                                      this->Makefile->GetDefineFlags());
-
-    // Add target-specific flags.
-    this->LocalGenerator->AddCompileOptions(languageFlags, this->Target,
-                                            language,
-                                            this->GetConfigName());
+  // Add Fortran format flags.
+  if(language == "Fortran")
+    {
+    this->AppendFortranFormatFlags(flags, *source);
     }
 
-  std::string flags = languageFlags;
-
   // Add source file specific flags.
   this->LocalGenerator->AppendFlags(flags,
     source->GetProperty("COMPILE_FLAGS"));
 
-  // TODO: Handle Apple frameworks.
-
   return flags;
 }
 
+void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
+                                             std::string const& language)
+{
+  std::vector<std::string> includes;
+  this->LocalGenerator->GetIncludeDirectories(includes,
+                                              this->GeneratorTarget,
+                                              language,
+                                              this->GetConfigName());
+  // Add include directory flags.
+  std::string includeFlags =
+    this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget,
+                                          language,
+        language == "RC" ? true : false,  // full include paths for RC
+                                          // needed by cmcldeps
+                                          false,
+                                          this->GetConfigName());
+  if (this->GetGlobalGenerator()->IsGCCOnWindows())
+    cmSystemTools::ReplaceString(includeFlags, "\\", "/");
+
+  this->LocalGenerator->AppendFlags(languageFlags, includeFlags);
+}
+
 bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
 {
   if (lang == "C" || lang == "CXX")
@@ -230,16 +169,6 @@ cmNinjaTargetGenerator::
 ComputeDefines(cmSourceFile const* source, const std::string& language)
 {
   std::set<std::string> defines;
-
-  // Add the export symbol definition for shared library objects.
-  if(const char* exportMacro = this->Target->GetExportMacro())
-    {
-    this->LocalGenerator->AppendDefines(defines, exportMacro);
-    }
-
-  // Add preprocessor definitions for this target and configuration.
-  this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
-                                             this->GetConfigName(), language);
   this->LocalGenerator->AppendDefines
     (defines,
      source->GetProperty("COMPILE_DEFINITIONS"));
@@ -251,7 +180,7 @@ ComputeDefines(cmSourceFile const* source, const std::string& language)
      source->GetProperty(defPropName));
   }
 
-  std::string definesString;
+  std::string definesString = this->GetDefines(language);
   this->LocalGenerator->JoinDefines(defines, definesString,
      language);
 
@@ -266,7 +195,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
     return cmNinjaDeps();
 
   cmComputeLinkInformation* cli =
-    this->Target->GetLinkInformation(this->GetConfigName());
+    this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
   if(!cli)
     return cmNinjaDeps();
 
@@ -277,7 +206,25 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
   // Add a dependency on the link definitions file, if any.
   if(!this->ModuleDefinitionFile.empty())
     {
-    result.push_back(this->ModuleDefinitionFile);
+    result.push_back(this->ConvertToNinjaPath(this->ModuleDefinitionFile));
+    }
+
+  // Add a dependency on user-specified manifest files, if any.
+  std::vector<cmSourceFile const*> manifest_srcs;
+  this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+  for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin();
+       mi != manifest_srcs.end(); ++mi)
+    {
+    result.push_back(this->ConvertToNinjaPath((*mi)->GetFullPath()));
+    }
+
+  // Add user-specified dependencies.
+  if (const char* linkDepends = this->Target->GetProperty("LINK_DEPENDS"))
+    {
+    std::vector<std::string> linkDeps;
+    cmSystemTools::ExpandListArgument(linkDepends, linkDeps);
+    std::transform(linkDeps.begin(), linkDeps.end(),
+                   std::back_inserter(result), MapToNinjaPath());
     }
 
   return result;
@@ -344,11 +291,12 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
       {
       pdbPath = this->Target->GetPDBDirectory(this->GetConfigName());
       pdbPath += "/";
-      pdbPath += this->Target->GetPDBName(this->GetConfigName());
+      pdbPath += this->GeneratorTarget->GetPDBName(this->GetConfigName());
       }
     if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
       {
-      compilePdbPath = this->Target->GetCompilePDBPath(this->GetConfigName());
+      compilePdbPath =
+              this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName());
       if(compilePdbPath.empty())
         {
         compilePdbPath = this->Target->GetSupportDirectory() + "/";
@@ -392,6 +340,7 @@ cmNinjaTargetGenerator
   vars.Source = "$in";
   vars.Object = "$out";
   vars.Defines = "$DEFINES";
+  vars.Includes = "$INCLUDES";
   vars.TargetPDB = "$TARGET_PDB";
   vars.TargetCompilePDB = "$TARGET_COMPILE_PDB";
   vars.ObjectDir = "$OBJECT_DIR";
@@ -422,7 +371,7 @@ cmNinjaTargetGenerator
                         mf->GetSafeDefinition("CMAKE_C_COMPILER") :
                         mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
       cldeps =  "\"";
-      cldeps += mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE");
+      cldeps += cmSystemTools::GetCMClDepsCommand();
       cldeps += "\" " + lang + " $in \"$DEP_FILE\" $out \"";
       cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX");
       cldeps += "\" \"" + cl + "\" ";
@@ -475,6 +424,25 @@ cmNinjaTargetGenerator
       }
     }
 
+  // Maybe insert a compiler launcher like ccache or distcc
+  if (!compileCmds.empty() && (lang == "C" || lang == "CXX"))
+    {
+    std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
+    const char *clauncher = this->Target->GetProperty(clauncher_prop);
+    if (clauncher && *clauncher)
+      {
+      std::vector<std::string> launcher_cmd;
+      cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
+      for (std::vector<std::string>::iterator i = launcher_cmd.begin(),
+             e = launcher_cmd.end(); i != e; ++i)
+        {
+        *i = this->LocalGenerator->EscapeForShell(*i);
+        }
+      std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
+      compileCmds.front().insert(0, run_launcher);
+      }
+    }
+
   if (!compileCmds.empty())
     {
     compileCmds.front().insert(0, cldeps);
@@ -560,7 +528,7 @@ cmNinjaTargetGenerator
     {
     cmCustomCommand const* cc = *cci;
     cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
-                                 this->GetMakefile());
+                                 this->GetLocalGenerator());
     const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
     const std::vector<std::string>& ccbyproducts= ccg.GetByproducts();
     std::transform(ccoutputs.begin(), ccoutputs.end(),
@@ -588,11 +556,6 @@ cmNinjaTargetGenerator
     {
     this->WriteObjectBuildStatement(*si, !orderOnlyDeps.empty());
     }
-  std::string def = this->GeneratorTarget->GetModuleDefinitionFile(config);
-  if(!def.empty())
-    {
-    this->ModuleDefinitionFile = this->ConvertToNinjaPath(def);
-    }
 
   this->GetBuildFileStream() << "\n";
 }
@@ -602,22 +565,39 @@ cmNinjaTargetGenerator
 ::WriteObjectBuildStatement(
   cmSourceFile const* source, bool writeOrderDependsTargetForTarget)
 {
+  std::string const language = source->GetLanguage();
+  std::string const sourceFileName =
+    language=="RC" ? source->GetFullPath() : this->GetSourceFilePath(source);
+  std::string const objectDir = this->Target->GetSupportDirectory();
+  std::string const objectFileName = this->GetObjectFilePath(source);
+  std::string const objectFileDir =
+    cmSystemTools::GetFilenamePath(objectFileName);
+
+  cmNinjaVars vars;
+  vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
+  vars["DEFINES"] = this->ComputeDefines(source, language);
+  vars["INCLUDES"] = this->GetIncludes(language);
+  if (!this->NeedDepTypeMSVC(language))
+    {
+    vars["DEP_FILE"] =
+      cmGlobalNinjaGenerator::EncodeDepfileSpace(objectFileName + ".d");
+    }
+
+  this->ExportObjectCompileCommand(
+    language, sourceFileName,
+    objectDir, objectFileName, objectFileDir,
+    vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]
+    );
+
   std::string comment;
-  const std::string language = source->GetLanguage();
   std::string rule = this->LanguageCompilerRule(language);
 
   cmNinjaDeps outputs;
-  std::string objectFileName = this->GetObjectFilePath(source);
   outputs.push_back(objectFileName);
   // Add this object to the list of object files.
   this->Objects.push_back(objectFileName);
 
   cmNinjaDeps explicitDeps;
-  std::string sourceFileName;
-  if (language == "RC")
-    sourceFileName = source->GetFullPath();
-  else
-    sourceFileName = this->GetSourceFilePath(source);
   explicitDeps.push_back(sourceFileName);
 
   cmNinjaDeps implicitDeps;
@@ -652,20 +632,11 @@ cmNinjaTargetGenerator
                                                              orderOnlyDeps);
   }
 
-  cmNinjaVars vars;
-  vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
-  vars["DEFINES"] = this->ComputeDefines(source, language);
-  if (!this->NeedDepTypeMSVC(language)) {
-    vars["DEP_FILE"] =
-            cmGlobalNinjaGenerator::EncodeDepfileSpace(objectFileName + ".d");
-  }
   EnsureParentDirectoryExists(objectFileName);
 
-  std::string objectDir = this->Target->GetSupportDirectory();
   vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
                          ConvertToNinjaPath(objectDir),
                          cmLocalGenerator::SHELL);
-  std::string objectFileDir = cmSystemTools::GetFilenamePath(objectFileName);
   vars["OBJECT_FILE_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
                               ConvertToNinjaPath(objectFileDir),
                               cmLocalGenerator::SHELL);
@@ -674,53 +645,6 @@ cmNinjaTargetGenerator
 
   this->SetMsvcTargetPdbVariable(vars);
 
-  if(this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS"))
-    {
-    cmLocalGenerator::RuleVariables compileObjectVars;
-    std::string lang = language;
-    compileObjectVars.Language = lang.c_str();
-
-    std::string escapedSourceFileName = sourceFileName;
-
-    if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str()))
-      {
-      escapedSourceFileName = cmSystemTools::CollapseFullPath(
-        escapedSourceFileName,
-        this->GetGlobalGenerator()->GetCMakeInstance()->
-          GetHomeOutputDirectory());
-      }
-
-    escapedSourceFileName =
-      this->LocalGenerator->ConvertToOutputFormat(
-        escapedSourceFileName, cmLocalGenerator::SHELL);
-
-    compileObjectVars.Source = escapedSourceFileName.c_str();
-    compileObjectVars.Object = objectFileName.c_str();
-    compileObjectVars.ObjectDir = objectDir.c_str();
-    compileObjectVars.ObjectFileDir = objectFileDir.c_str();
-    compileObjectVars.Flags = vars["FLAGS"].c_str();
-    compileObjectVars.Defines = vars["DEFINES"].c_str();
-
-    // Rule for compiling object file.
-    std::string compileCmdVar = "CMAKE_";
-    compileCmdVar += language;
-    compileCmdVar += "_COMPILE_OBJECT";
-    std::string compileCmd =
-      this->GetMakefile()->GetRequiredDefinition(compileCmdVar);
-    std::vector<std::string> compileCmds;
-    cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
-
-    for (std::vector<std::string>::iterator i = compileCmds.begin();
-        i != compileCmds.end(); ++i)
-      this->GetLocalGenerator()->ExpandRuleVariables(*i, compileObjectVars);
-
-    std::string cmdLine =
-      this->GetLocalGenerator()->BuildCommandLine(compileCmds);
-
-    this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine,
-                                                     sourceFileName);
-    }
-
   this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(),
                                          comment,
                                          rule,
@@ -742,30 +666,67 @@ cmNinjaTargetGenerator
   }
 }
 
-//----------------------------------------------------------------------------
 void
 cmNinjaTargetGenerator
-::AddModuleDefinitionFlag(std::string& flags)
+::ExportObjectCompileCommand(
+  std::string const& language,
+  std::string const& sourceFileName,
+  std::string const& objectDir,
+  std::string const& objectFileName,
+  std::string const& objectFileDir,
+  std::string const& flags,
+  std::string const& defines,
+  std::string const& includes
+  )
 {
-  if(this->ModuleDefinitionFile.empty())
+  if(!this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS"))
     {
     return;
     }
 
-  // TODO: Create a per-language flag variable.
-  const char* defFileFlag =
-    this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
-  if(!defFileFlag)
+  cmLocalGenerator::RuleVariables compileObjectVars;
+  compileObjectVars.Language = language.c_str();
+
+  std::string escapedSourceFileName = sourceFileName;
+
+  if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str()))
     {
-    return;
+    escapedSourceFileName = cmSystemTools::CollapseFullPath(
+      escapedSourceFileName,
+      this->GetGlobalGenerator()->GetCMakeInstance()->
+      GetHomeOutputDirectory());
     }
 
-  // Append the flag and value.  Use ConvertToLinkReference to help
-  // vs6's "cl -link" pass it to the linker.
-  std::string flag = defFileFlag;
-  flag += (this->LocalGenerator->ConvertToLinkReference(
-             this->ModuleDefinitionFile));
-  this->LocalGenerator->AppendFlags(flags, flag);
+  escapedSourceFileName =
+    this->LocalGenerator->ConvertToOutputFormat(
+      escapedSourceFileName, cmLocalGenerator::SHELL);
+
+  compileObjectVars.Source = escapedSourceFileName.c_str();
+  compileObjectVars.Object = objectFileName.c_str();
+  compileObjectVars.ObjectDir = objectDir.c_str();
+  compileObjectVars.ObjectFileDir = objectFileDir.c_str();
+  compileObjectVars.Flags = flags.c_str();
+  compileObjectVars.Defines = defines.c_str();
+  compileObjectVars.Includes = includes.c_str();
+
+  // Rule for compiling object file.
+  std::string compileCmdVar = "CMAKE_";
+  compileCmdVar += language;
+  compileCmdVar += "_COMPILE_OBJECT";
+  std::string compileCmd =
+    this->GetMakefile()->GetRequiredDefinition(compileCmdVar);
+  std::vector<std::string> compileCmds;
+  cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
+
+  for (std::vector<std::string>::iterator i = compileCmds.begin();
+       i != compileCmds.end(); ++i)
+    this->GetLocalGenerator()->ExpandRuleVariables(*i, compileObjectVars);
+
+  std::string cmdLine =
+    this->GetLocalGenerator()->BuildCommandLine(compileCmds);
+
+  this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine,
+                                                   sourceFileName);
 }
 
 void
@@ -799,7 +760,7 @@ cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
   cmSourceFile const& source, const char* pkgloc)
 {
   // Skip OS X content when not building a Framework or Bundle.
-  if(!this->Generator->GetTarget()->IsBundleOnApple())
+  if(!this->Generator->GetGeneratorTarget()->IsBundleOnApple())
     {
     return;
     }
@@ -810,14 +771,14 @@ cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
   // Get the input file location.
   std::string input = source.GetFullPath();
   input =
-    this->Generator->GetLocalGenerator()->ConvertToNinjaPath(input);
+    this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(input);
 
   // Get the output file location.
   std::string output = macdir;
   output += "/";
   output += cmSystemTools::GetFilenameName(input);
   output =
-    this->Generator->GetLocalGenerator()->ConvertToNinjaPath(output);
+    this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(output);
 
   // Write a build statement to copy the content into the bundle.
   this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input,
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 4e7d8b3..0267f63 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -13,27 +13,29 @@
 #ifndef cmNinjaTargetGenerator_h
 #define cmNinjaTargetGenerator_h
 
+#include "cmCommonTargetGenerator.h"
+
 #include "cmStandardIncludes.h"
 #include "cmNinjaTypes.h"
+#include "cmGlobalNinjaGenerator.h"
 #include "cmLocalNinjaGenerator.h"
 #include "cmOSXBundleGenerator.h"
 
 class cmTarget;
-class cmGlobalNinjaGenerator;
 class cmGeneratedFileStream;
 class cmGeneratorTarget;
 class cmMakefile;
 class cmSourceFile;
 class cmCustomCommand;
 
-class cmNinjaTargetGenerator
+class cmNinjaTargetGenerator: public cmCommonTargetGenerator
 {
 public:
   /// Create a cmNinjaTargetGenerator according to the @a target's type.
   static cmNinjaTargetGenerator* New(cmGeneratorTarget* target);
 
   /// Build a NinjaTargetGenerator.
-  cmNinjaTargetGenerator(cmTarget* target);
+  cmNinjaTargetGenerator(cmGeneratorTarget* target);
 
   /// Destructor.
   virtual ~cmNinjaTargetGenerator();
@@ -65,14 +67,8 @@ protected:
   cmMakefile* GetMakefile() const
   { return this->Makefile; }
 
-  std::string const& GetConfigName() const;
-
   std::string LanguageCompilerRule(const std::string& lang) const;
 
-  const char* GetFeature(const std::string& feature);
-  bool GetFeatureAsBool(const std::string& feature);
-  void AddFeatureFlags(std::string& flags, const std::string& lang);
-
   std::string OrderDependsTargetForTarget();
 
   std::string ComputeOrderDependsForTarget();
@@ -85,14 +81,16 @@ protected:
   std::string ComputeFlagsForObject(cmSourceFile const* source,
                                     const std::string& language);
 
+  void AddIncludeFlags(std::string& flags, std::string const& lang);
+
   std::string ComputeDefines(cmSourceFile const* source,
                              const std::string& language);
 
   std::string ConvertToNinjaPath(const std::string& path) const {
-    return this->GetLocalGenerator()->ConvertToNinjaPath(path);
+    return this->GetGlobalGenerator()->ConvertToNinjaPath(path);
   }
-  cmLocalNinjaGenerator::map_to_ninja_path MapToNinjaPath() const {
-    return this->GetLocalGenerator()->MapToNinjaPath();
+  cmGlobalNinjaGenerator::MapToNinjaPathImpl MapToNinjaPath() const {
+    return this->GetGlobalGenerator()->MapToNinjaPath();
   }
 
   /// @return the list of link dependency for the given target @a target.
@@ -116,12 +114,20 @@ protected:
   void WriteObjectBuildStatement(cmSourceFile const* source,
                                  bool writeOrderDependsTargetForTarget);
 
+  void ExportObjectCompileCommand(
+    std::string const& language,
+    std::string const& sourceFileName,
+    std::string const& objectDir,
+    std::string const& objectFileName,
+    std::string const& objectFileDir,
+    std::string const& flags,
+    std::string const& defines,
+    std::string const& includes
+    );
+
   cmNinjaDeps GetObjects() const
   { return this->Objects; }
 
-  // Helper to add flag for windows .def file.
-  void AddModuleDefinitionFlag(std::string& flags);
-
   void EnsureDirectoryExists(const std::string& dir) const;
   void EnsureParentDirectoryExists(const std::string& path) const;
 
@@ -150,19 +156,10 @@ protected:
                             cmNinjaVars& vars);
 
 private:
-  cmTarget* Target;
-  cmGeneratorTarget* GeneratorTarget;
-  cmMakefile* Makefile;
   cmLocalNinjaGenerator* LocalGenerator;
   /// List of object files for this target.
   cmNinjaDeps Objects;
   std::vector<cmCustomCommand const*> CustomCommands;
-
-  typedef std::map<std::string, std::string> LanguageFlagMap;
-  LanguageFlagMap LanguageFlags;
-
-  // The windows module definition source file (.def), if any.
-  std::string ModuleDefinitionFile;
 };
 
 #endif // ! cmNinjaTargetGenerator_h
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 42d6b46..58b901a 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -21,7 +21,7 @@
 
 cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
     cmGeneratorTarget *target)
-  : cmNinjaTargetGenerator(target->Target) {}
+  : cmNinjaTargetGenerator(target) {}
 
 cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() {}
 
@@ -44,7 +44,7 @@ void cmNinjaUtilityTargetGenerator::Generate()
     for (std::vector<cmCustomCommand>::const_iterator
          ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) {
       cmCustomCommandGenerator ccg(*ci, this->GetConfigName(),
-                                   this->GetMakefile());
+                                   this->GetLocalGenerator());
       this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps);
       this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands);
       std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
@@ -65,7 +65,7 @@ void cmNinjaUtilityTargetGenerator::Generate()
     if(cmCustomCommand* cc = (*source)->GetCustomCommand())
       {
       cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
-                                   this->GetMakefile());
+                                   this->GetLocalGenerator());
       this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
 
       // Depend on all custom command outputs.
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index a8eef82..4fe99e3 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -22,7 +22,7 @@ cmOSXBundleGenerator(cmGeneratorTarget* target,
                      const std::string& configName)
  : GT(target)
  , Makefile(target->Target->GetMakefile())
- , LocalGenerator(Makefile->GetLocalGenerator())
+ , LocalGenerator(target->GetLocalGenerator())
  , ConfigName(configName)
  , MacContentFolders(0)
 {
@@ -47,7 +47,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
   // Compute bundle directory names.
   std::string out = outpath;
   out += "/";
-  out += this->GT->Target->GetAppBundleDirectory(this->ConfigName, false);
+  out += this->GT->GetAppBundleDirectory(this->ConfigName, false);
   cmSystemTools::MakeDirectory(out.c_str());
   this->Makefile->AddCMakeOutputFile(out);
 
@@ -57,7 +57,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
   // to be set.
   std::string plist = outpath;
   plist += "/";
-  plist += this->GT->Target->GetAppBundleDirectory(this->ConfigName, true);
+  plist += this->GT->GetAppBundleDirectory(this->ConfigName, true);
   plist += "/Info.plist";
   this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
                                                targetName,
@@ -77,11 +77,11 @@ void cmOSXBundleGenerator::CreateFramework(
 
   // Compute the location of the top-level foo.framework directory.
   std::string contentdir = outpath + "/" +
-    this->GT->Target->GetFrameworkDirectory(this->ConfigName, true);
+    this->GT->GetFrameworkDirectory(this->ConfigName, true);
   contentdir += "/";
 
   std::string newoutpath = outpath + "/" +
-    this->GT->Target->GetFrameworkDirectory(this->ConfigName, false);
+    this->GT->GetFrameworkDirectory(this->ConfigName, false);
 
   std::string frameworkVersion = this->GT->Target->GetFrameworkVersion();
 
@@ -172,14 +172,14 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
   // Compute bundle directory names.
   std::string out = root;
   out += "/";
-  out += this->GT->Target->GetCFBundleDirectory(this->ConfigName, false);
+  out += this->GT->GetCFBundleDirectory(this->ConfigName, false);
   cmSystemTools::MakeDirectory(out.c_str());
   this->Makefile->AddCMakeOutputFile(out);
 
   // Configure the Info.plist file.  Note that it needs the executable name
   // to be set.
   std::string plist = root + "/" +
-    this->GT->Target->GetCFBundleDirectory(this->ConfigName, true);
+    this->GT->GetCFBundleDirectory(this->ConfigName, true);
   plist += "/Info.plist";
   std::string name = cmSystemTools::GetFilenameName(targetName);
   this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
@@ -217,7 +217,7 @@ cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc)
   // Construct the full path to the content subdirectory.
 
   std::string macdir =
-    this->GT->Target->GetMacContentDirectory(this->ConfigName,
+    this->GT->GetMacContentDirectory(this->ConfigName,
                                          /*implib*/ false);
   macdir += "/";
   macdir += pkgloc;
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index a612437..35ee127 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -280,7 +280,7 @@ bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir)
 
 //----------------------------------------------------------------------------
 cmOrderDirectories::cmOrderDirectories(cmGlobalGenerator* gg,
-                                       cmTarget const* target,
+                                       const cmGeneratorTarget* target,
                                        const char* purpose)
 {
   this->GlobalGenerator = gg;
@@ -554,7 +554,8 @@ void cmOrderDirectories::FindImplicitConflicts()
     << text
     << "Some of these libraries may not be found correctly.";
   this->GlobalGenerator->GetCMakeInstance()
-    ->IssueMessage(cmake::WARNING, w.str(), this->Target->GetBacktrace());
+    ->IssueMessage(cmake::WARNING, w.str(),
+                   this->Target->Target->GetBacktrace());
 }
 
 //----------------------------------------------------------------------------
@@ -635,5 +636,6 @@ void cmOrderDirectories::DiagnoseCycle()
     }
   e << "Some of these libraries may not be found correctly.";
   this->GlobalGenerator->GetCMakeInstance()
-    ->IssueMessage(cmake::WARNING, e.str(), this->Target->GetBacktrace());
+    ->IssueMessage(cmake::WARNING, e.str(),
+                   this->Target->Target->GetBacktrace());
 }
diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h
index 07c85dd..211c786 100644
--- a/Source/cmOrderDirectories.h
+++ b/Source/cmOrderDirectories.h
@@ -19,7 +19,7 @@
 class cmGlobalGenerator;
 class cmOrderDirectoriesConstraint;
 class cmOrderDirectoriesConstraintLibrary;
-class cmTarget;
+class cmGeneratorTarget;
 
 /** \class cmOrderDirectories
  * \brief Compute a safe runtime path order for a set of shared libraries.
@@ -27,7 +27,7 @@ class cmTarget;
 class cmOrderDirectories
 {
 public:
-  cmOrderDirectories(cmGlobalGenerator* gg, cmTarget const* target,
+  cmOrderDirectories(cmGlobalGenerator* gg, cmGeneratorTarget const* target,
                      const char* purpose);
   ~cmOrderDirectories();
   void AddRuntimeLibrary(std::string const& fullPath, const char* soname = 0);
@@ -41,11 +41,9 @@ public:
   std::vector<std::string> const& GetOrderedDirectories();
 private:
   cmGlobalGenerator* GlobalGenerator;
-  cmTarget const* Target;
+  cmGeneratorTarget const* Target;
   std::string Purpose;
 
-  bool Computed;
-
   std::vector<std::string> OrderedDirectories;
 
   std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries;
@@ -68,8 +66,9 @@ private:
   void OrderDirectories();
   void VisitDirectory(unsigned int i);
   void DiagnoseCycle();
-  bool CycleDiagnosed;
   int WalkId;
+  bool CycleDiagnosed;
+  bool Computed;
 
   // Adjacency-list representation of runtime path ordering graph.
   // This maps from directory to those that must come *before* it.
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
new file mode 100644
index 0000000..5acae2f
--- /dev/null
+++ b/Source/cmOutputConverter.cxx
@@ -0,0 +1,1065 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmOutputConverter.h"
+
+#include "cmAlgorithms.h"
+#include "cmake.h"
+
+#include <assert.h>
+
+#include <string.h> /* strlen */
+#include <ctype.h>  /* isalpha */
+
+cmOutputConverter::cmOutputConverter(cmState::Snapshot snapshot)
+  : StateSnapshot(snapshot), LinkScriptShell(false)
+{
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToOutputForExistingCommon(const std::string& remote,
+                                                    std::string const& result,
+                                                    OutputFormat format) const
+{
+  // If this is a windows shell, the result has a space, and the path
+  // already exists, we can use a short-path to reference it without a
+  // space.
+  if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos &&
+     cmSystemTools::FileExists(remote.c_str()))
+    {
+    std::string tmp;
+    if(cmSystemTools::GetShortPath(remote, tmp))
+      {
+      return this->ConvertToOutputFormat(tmp, format);
+      }
+    }
+
+  // Otherwise, leave it unchanged.
+  return result;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToOutputForExisting(const std::string& remote,
+                                              RelativeRoot local,
+                                              OutputFormat format) const
+{
+  static_cast<void>(local);
+
+  // Perform standard conversion.
+  std::string result = this->ConvertToOutputFormat(remote, format);
+
+  // Consider short-path.
+  return this->ConvertToOutputForExistingCommon(remote, result, format);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToOutputForExisting(RelativeRoot remote,
+                                              const std::string& local,
+                                              OutputFormat format) const
+{
+  // Perform standard conversion.
+  std::string result = this->Convert(remote, local, format, true);
+
+  // Consider short-path.
+  const char* remotePath = this->GetRelativeRootPath(remote);
+  return this->ConvertToOutputForExistingCommon(remotePath, result, format);
+}
+
+//----------------------------------------------------------------------------
+const char* cmOutputConverter::GetRelativeRootPath(RelativeRoot relroot) const
+{
+  switch (relroot)
+    {
+  case HOME:
+    return this->GetState()->GetSourceDirectory();
+  case START:
+    return this->StateSnapshot.GetDirectory().GetCurrentSource();
+  case HOME_OUTPUT:
+    return this->GetState()->GetBinaryDirectory();
+  case START_OUTPUT:
+    return this->StateSnapshot.GetDirectory().GetCurrentBinary();
+  default: break;
+    }
+  return 0;
+}
+
+std::string cmOutputConverter::Convert(const std::string& source,
+                                       RelativeRoot relative,
+                                       OutputFormat output) const
+{
+  // Convert the path to a relative path.
+  std::string result = source;
+
+  switch (relative)
+    {
+  case HOME:
+    result = this->ConvertToRelativePath(
+          this->GetState()->GetSourceDirectoryComponents(), result);
+    break;
+  case START:
+    result = this->ConvertToRelativePath(
+          this->StateSnapshot.GetDirectory().GetCurrentSourceComponents(),
+          result);
+    break;
+  case HOME_OUTPUT:
+    result = this->ConvertToRelativePath(
+          this->GetState()->GetBinaryDirectoryComponents(), result);
+    break;
+  case START_OUTPUT:
+    result = this->ConvertToRelativePath(
+          this->StateSnapshot.GetDirectory().GetCurrentBinaryComponents(),
+          result);
+    break;
+  case FULL:
+    result = cmSystemTools::CollapseFullPath(result);
+    break;
+  case NONE:
+    break;
+    }
+  return this->ConvertToOutputFormat(result, output);
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
+                                                     OutputFormat output) const
+{
+  std::string result = source;
+  // Convert it to an output path.
+  if (output == MAKERULE)
+    {
+    result = cmSystemTools::ConvertToOutputPath(result.c_str());
+    }
+  else if(output == SHELL || output == WATCOMQUOTE)
+    {
+    result = this->ConvertDirectorySeparatorsForShell(source);
+    result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
+    }
+  else if(output == RESPONSE)
+    {
+    result = this->EscapeForShell(result, false, false, false);
+    }
+  return result;
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
+                                              const std::string& source) const
+{
+  std::string result = source;
+  // For the MSYS shell convert drive letters to posix paths, so
+  // that c:/some/path becomes /c/some/path.  This is needed to
+  // avoid problems with the shell path translation.
+  if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell)
+    {
+    if(result.size() > 2 && result[1] == ':')
+      {
+      result[1] = result[0];
+      result[0] = '/';
+      }
+    }
+  if(this->GetState()->UseWindowsShell())
+    {
+    std::replace(result.begin(), result.end(), '/', '\\');
+    }
+  return result;
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::Convert(RelativeRoot remote,
+                                      const std::string& local,
+                                      OutputFormat output,
+                                      bool optional) const
+{
+  const char* remotePath = this->GetRelativeRootPath(remote);
+
+  // The relative root must have a path (i.e. not FULL or NONE)
+  assert(remotePath != 0);
+
+  if(!local.empty() && !optional)
+    {
+    std::vector<std::string> components;
+    cmSystemTools::SplitPath(local, components);
+    std::string result = this->ConvertToRelativePath(components, remotePath);
+    return this->ConvertToOutputFormat(result, output);
+    }
+
+  return this->ConvertToOutputFormat(remotePath, output);
+}
+
+//----------------------------------------------------------------------------
+static bool cmOutputConverterNotAbove(const char* a, const char* b)
+{
+  return (cmSystemTools::ComparePath(a, b) ||
+          cmSystemTools::IsSubDirectory(a, b));
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToRelativePath(const std::vector<std::string>& local,
+                                        const std::string& in_remote,
+                                        bool force) const
+{
+  // The path should never be quoted.
+  assert(in_remote[0] != '\"');
+
+  // The local path should never have a trailing slash.
+  assert(!local.empty() && !(local[local.size()-1] == ""));
+
+  // If the path is already relative then just return the path.
+  if(!cmSystemTools::FileIsFullPath(in_remote.c_str()))
+    {
+    return in_remote;
+    }
+
+  if(!force)
+    {
+    // Skip conversion if the path and local are not both in the source
+    // or both in the binary tree.
+    std::string local_path = cmSystemTools::JoinPath(local);
+    if(!((cmOutputConverterNotAbove(local_path.c_str(),
+              this->StateSnapshot.GetDirectory().GetRelativePathTopBinary())
+          && cmOutputConverterNotAbove(in_remote.c_str(),
+              this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()))
+         || (cmOutputConverterNotAbove(local_path.c_str(),
+              this->StateSnapshot.GetDirectory().GetRelativePathTopSource())
+             && cmOutputConverterNotAbove(in_remote.c_str(),
+              this->StateSnapshot.GetDirectory().GetRelativePathTopSource()))))
+      {
+      return in_remote;
+      }
+    }
+
+  // Identify the longest shared path component between the remote
+  // path and the local path.
+  std::vector<std::string> remote;
+  cmSystemTools::SplitPath(in_remote, remote);
+  unsigned int common=0;
+  while(common < remote.size() &&
+        common < local.size() &&
+        cmSystemTools::ComparePath(remote[common],
+                                   local[common]))
+    {
+    ++common;
+    }
+
+  // If no part of the path is in common then return the full path.
+  if(common == 0)
+    {
+    return in_remote;
+    }
+
+  // If the entire path is in common then just return a ".".
+  if(common == remote.size() &&
+     common == local.size())
+    {
+    return ".";
+    }
+
+  // If the entire path is in common except for a trailing slash then
+  // just return a "./".
+  if(common+1 == remote.size() &&
+     remote[common].empty() &&
+     common == local.size())
+    {
+    return "./";
+    }
+
+  // Construct the relative path.
+  std::string relative;
+
+  // First add enough ../ to get up to the level of the shared portion
+  // of the path.  Leave off the trailing slash.  Note that the last
+  // component of local will never be empty because local should never
+  // have a trailing slash.
+  for(unsigned int i=common; i < local.size(); ++i)
+    {
+    relative += "..";
+    if(i < local.size()-1)
+      {
+      relative += "/";
+      }
+    }
+
+  // Now add the portion of the destination path that is not included
+  // in the shared portion of the path.  Add a slash the first time
+  // only if there was already something in the path.  If there was a
+  // trailing slash in the input then the last iteration of the loop
+  // will add a slash followed by an empty string which will preserve
+  // the trailing slash in the output.
+
+  if(!relative.empty() && !remote.empty())
+    {
+    relative += "/";
+    }
+  relative += cmJoin(cmMakeRange(remote).advance(common), "/");
+
+  // Finally return the path.
+  return relative;
+}
+
+//----------------------------------------------------------------------------
+static bool cmOutputConverterIsShellOperator(const std::string& str)
+{
+  static std::set<std::string> shellOperators;
+  if(shellOperators.empty())
+    {
+    shellOperators.insert("<");
+    shellOperators.insert(">");
+    shellOperators.insert("<<");
+    shellOperators.insert(">>");
+    shellOperators.insert("|");
+    shellOperators.insert("||");
+    shellOperators.insert("&&");
+    shellOperators.insert("&>");
+    shellOperators.insert("1>");
+    shellOperators.insert("2>");
+    shellOperators.insert("2>&1");
+    shellOperators.insert("1>&2");
+    }
+  return shellOperators.count(str) > 0;
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::EscapeForShell(const std::string& str,
+                                             bool makeVars,
+                                             bool forEcho,
+                                             bool useWatcomQuote) const
+{
+  // Do not escape shell operators.
+  if(cmOutputConverterIsShellOperator(str))
+    {
+    return str;
+    }
+
+  // Compute the flags for the target shell environment.
+  int flags = 0;
+  if(this->GetState()->UseWindowsVSIDE())
+    {
+    flags |= Shell_Flag_VSIDE;
+    }
+  else if(!this->LinkScriptShell)
+    {
+    flags |= Shell_Flag_Make;
+    }
+  if(makeVars)
+    {
+    flags |= Shell_Flag_AllowMakeVariables;
+    }
+  if(forEcho)
+    {
+    flags |= Shell_Flag_EchoWindows;
+    }
+  if(useWatcomQuote)
+    {
+    flags |= Shell_Flag_WatcomQuote;
+    }
+  if(this->GetState()->UseWatcomWMake())
+    {
+    flags |= Shell_Flag_WatcomWMake;
+    }
+  if(this->GetState()->UseMinGWMake())
+    {
+    flags |= Shell_Flag_MinGWMake;
+    }
+  if(this->GetState()->UseNMake())
+    {
+    flags |= Shell_Flag_NMake;
+    }
+
+  // Compute the buffer size needed.
+  int size = (this->GetState()->UseWindowsShell() ?
+              Shell_GetArgumentSizeForWindows(str.c_str(), flags) :
+              Shell_GetArgumentSizeForUnix(str.c_str(), flags));
+
+  // Compute the shell argument itself.
+  std::vector<char> arg(size);
+  if(this->GetState()->UseWindowsShell())
+    {
+    Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags);
+    }
+  else
+    {
+    Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags);
+    }
+  return std::string(&arg[0]);
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::EscapeForCMake(const std::string& str)
+{
+  // Always double-quote the argument to take care of most escapes.
+  std::string result = "\"";
+  for(const char* c = str.c_str(); *c; ++c)
+    {
+    if(*c == '"')
+      {
+      // Escape the double quote to avoid ending the argument.
+      result += "\\\"";
+      }
+    else if(*c == '$')
+      {
+      // Escape the dollar to avoid expanding variables.
+      result += "\\$";
+      }
+    else if(*c == '\\')
+      {
+      // Escape the backslash to avoid other escapes.
+      result += "\\\\";
+      }
+    else
+      {
+      // Other characters will be parsed correctly.
+      result += *c;
+      }
+    }
+  result += "\"";
+  return result;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::EscapeWindowsShellArgument(const char* arg, int shell_flags)
+{
+  char local_buffer[1024];
+  char* buffer = local_buffer;
+  int size = Shell_GetArgumentSizeForWindows(arg, shell_flags);
+  if(size > 1024)
+    {
+    buffer = new char[size];
+    }
+  Shell_GetArgumentForWindows(arg, buffer, shell_flags);
+  std::string result(buffer);
+  if(buffer != local_buffer)
+    {
+    delete [] buffer;
+    }
+  return result;
+}
+
+//----------------------------------------------------------------------------
+cmOutputConverter::FortranFormat
+cmOutputConverter::GetFortranFormat(const char* value)
+{
+  FortranFormat format = FortranFormatNone;
+  if(value && *value)
+    {
+    std::vector<std::string> fmt;
+    cmSystemTools::ExpandListArgument(value, fmt);
+    for(std::vector<std::string>::iterator fi = fmt.begin();
+        fi != fmt.end(); ++fi)
+      {
+      if(*fi == "FIXED")
+        {
+        format = FortranFormatFixed;
+        }
+      if(*fi == "FREE")
+        {
+        format = FortranFormatFree;
+        }
+      }
+    }
+  return format;
+}
+
+void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
+{
+  this->LinkScriptShell = linkScriptShell;
+}
+
+cmState* cmOutputConverter::GetState() const
+{
+  return this->StateSnapshot.GetState();
+}
+
+//----------------------------------------------------------------------------
+/*
+
+Notes:
+
+Make variable replacements open a can of worms.  Sometimes they should
+be quoted and sometimes not.  Sometimes their replacement values are
+already quoted.
+
+VS variables cause problems.  In order to pass the referenced value
+with spaces the reference must be quoted.  If the variable value ends
+in a backslash then it will escape the ending quote!  In order to make
+the ending backslash appear we need this:
+
+  "$(InputDir)\"
+
+However if there is not a trailing backslash then this will put a
+quote in the value so we need:
+
+  "$(InputDir)"
+
+Make variable references are platform specific so we should probably
+just NOT quote them and let the listfile author deal with it.
+
+*/
+
+/*
+TODO: For windows echo:
+
+To display a pipe (|) or redirection character (< or >) when using the
+echo command, use a caret character immediately before the pipe or
+redirection character (for example, ^>, ^<, or ^| ). If you need to
+use the caret character itself (^), use two in a row (^^).
+*/
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharIsWhitespace(char c)
+{
+  return ((c == ' ') || (c == '\t'));
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharNeedsQuotesOnUnix(char c)
+{
+  return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
+          (c == '&') || (c == '$') || (c == '(') || (c == ')') ||
+          (c == '~') || (c == '<') || (c == '>') || (c == '|') ||
+          (c == '*') || (c == '^') || (c == '\\'));
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharNeedsQuotesOnWindows(char c)
+{
+  return ((c == '\'') || (c == '#') || (c == '&') ||
+          (c == '<') || (c == '>') || (c == '|') || (c == '^'));
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharNeedsQuotes(char c, int isUnix, int flags)
+{
+  /* On Windows the built-in command shell echo never needs quotes.  */
+  if(!isUnix && (flags & Shell_Flag_EchoWindows))
+    {
+    return 0;
+    }
+
+  /* On all platforms quotes are needed to preserve whitespace.  */
+  if(Shell__CharIsWhitespace(c))
+    {
+    return 1;
+    }
+
+  if(isUnix)
+    {
+    /* On UNIX several special characters need quotes to preserve them.  */
+    if(Shell__CharNeedsQuotesOnUnix(c))
+      {
+      return 1;
+      }
+    }
+  else
+    {
+    /* On Windows several special characters need quotes to preserve them.  */
+    if(Shell__CharNeedsQuotesOnWindows(c))
+      {
+      return 1;
+      }
+    }
+  return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharIsMakeVariableName(char c)
+{
+  return c && (c == '_' || isalpha(((int)c)));
+}
+
+/*--------------------------------------------------------------------------*/
+const char* cmOutputConverter::Shell__SkipMakeVariables(const char* c)
+{
+  while(*c == '$' && *(c+1) == '(')
+    {
+    const char* skip = c+2;
+    while(Shell__CharIsMakeVariableName(*skip))
+      {
+      ++skip;
+      }
+    if(*skip == ')')
+      {
+      c = skip+1;
+      }
+    else
+      {
+      break;
+      }
+    }
+  return c;
+}
+
+/*
+Allowing make variable replacements opens a can of worms.  Sometimes
+they should be quoted and sometimes not.  Sometimes their replacement
+values are already quoted or contain escapes.
+
+Some Visual Studio variables cause problems.  In order to pass the
+referenced value with spaces the reference must be quoted.  If the
+variable value ends in a backslash then it will escape the ending
+quote!  In order to make the ending backslash appear we need this:
+
+  "$(InputDir)\"
+
+However if there is not a trailing backslash then this will put a
+quote in the value so we need:
+
+  "$(InputDir)"
+
+This macro decides whether we quote an argument just because it
+contains a make variable reference.  This should be replaced with a
+flag later when we understand applications of this better.
+*/
+#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in,
+                                                  int isUnix, int flags)
+{
+  /* The empty string needs quotes.  */
+  if(!*in)
+    {
+    return 1;
+    }
+
+  /* Scan the string for characters that require quoting.  */
+  {
+  const char* c;
+  for(c=in; *c; ++c)
+    {
+    /* Look for $(MAKEVAR) syntax if requested.  */
+    if(flags & Shell_Flag_AllowMakeVariables)
+      {
+#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
+      const char* skip = Shell__SkipMakeVariables(c);
+      if(skip != c)
+        {
+        /* We need to quote make variable references to preserve the
+           string with contents substituted in its place.  */
+        return 1;
+        }
+#else
+      /* Skip over the make variable references if any are present.  */
+      c = Shell__SkipMakeVariables(c);
+
+      /* Stop if we have reached the end of the string.  */
+      if(!*c)
+        {
+        break;
+        }
+#endif
+      }
+
+    /* Check whether this character needs quotes.  */
+    if(Shell__CharNeedsQuotes(*c, isUnix, flags))
+      {
+      return 1;
+      }
+    }
+  }
+
+  /* On Windows some single character arguments need quotes.  */
+  if(!isUnix && *in && !*(in+1))
+    {
+    char c = *in;
+    if((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#'))
+      {
+      return 1;
+      }
+    }
+
+  return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__GetArgumentSize(const char* in,
+                                              int isUnix, int flags)
+{
+  /* Start with the length of the original argument, plus one for
+     either a terminating null or a separating space.  */
+  int size = (int)strlen(in) + 1;
+
+  /* String iterator.  */
+  const char* c;
+
+  /* Keep track of how many backslashes have been encountered in a row.  */
+  int windows_backslashes = 0;
+
+  /* Scan the string for characters that require escaping or quoting.  */
+  for(c=in; *c; ++c)
+    {
+    /* Look for $(MAKEVAR) syntax if requested.  */
+    if(flags & Shell_Flag_AllowMakeVariables)
+      {
+      /* Skip over the make variable references if any are present.  */
+      c = Shell__SkipMakeVariables(c);
+
+      /* Stop if we have reached the end of the string.  */
+      if(!*c)
+        {
+        break;
+        }
+      }
+
+    /* Check whether this character needs escaping for the shell.  */
+    if(isUnix)
+      {
+      /* On Unix a few special characters need escaping even inside a
+         quoted argument.  */
+      if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
+        {
+        /* This character needs a backslash to escape it.  */
+        ++size;
+        }
+      }
+    else if(flags & Shell_Flag_EchoWindows)
+      {
+      /* On Windows the built-in command shell echo never needs escaping.  */
+      }
+    else
+      {
+      /* On Windows only backslashes and double-quotes need escaping.  */
+      if(*c == '\\')
+        {
+        /* Found a backslash.  It may need to be escaped later.  */
+        ++windows_backslashes;
+        }
+      else if(*c == '"')
+        {
+        /* Found a double-quote.  We need to escape it and all
+           immediately preceding backslashes.  */
+        size += windows_backslashes + 1;
+        windows_backslashes = 0;
+        }
+      else
+        {
+        /* Found another character.  This eliminates the possibility
+           that any immediately preceding backslashes will be
+           escaped.  */
+        windows_backslashes = 0;
+        }
+      }
+
+    /* Check whether this character needs escaping for a make tool.  */
+    if(*c == '$')
+      {
+      if(flags & Shell_Flag_Make)
+        {
+        /* In Makefiles a dollar is written $$ so we need one extra
+           character.  */
+        ++size;
+        }
+      else if(flags & Shell_Flag_VSIDE)
+        {
+        /* In a VS IDE a dollar is written "$" so we need two extra
+           characters.  */
+        size += 2;
+        }
+      }
+    else if(*c == '#')
+      {
+      if((flags & Shell_Flag_Make) &&
+         (flags & Shell_Flag_WatcomWMake))
+        {
+        /* In Watcom WMake makefiles a pound is written $# so we need
+           one extra character.  */
+        ++size;
+        }
+      }
+    else if(*c == '%')
+      {
+      if((flags & Shell_Flag_VSIDE) ||
+         ((flags & Shell_Flag_Make) &&
+          ((flags & Shell_Flag_MinGWMake) ||
+           (flags & Shell_Flag_NMake))))
+        {
+        /* In the VS IDE, NMake, or MinGW make a percent is written %%
+           so we need one extra characters.  */
+        size += 1;
+        }
+      }
+    else if(*c == ';')
+      {
+      if(flags & Shell_Flag_VSIDE)
+        {
+        /* In a VS IDE a semicolon is written ";" so we need two extra
+           characters.  */
+        size += 2;
+        }
+      }
+    }
+
+  /* Check whether the argument needs surrounding quotes.  */
+  if(Shell__ArgumentNeedsQuotes(in, isUnix, flags))
+    {
+    /* Surrounding quotes are needed.  Allocate space for them.  */
+    if((flags & Shell_Flag_WatcomQuote) && (isUnix))
+      {
+        size += 2;
+      }
+    size += 2;
+
+    /* We must escape all ending backslashes when quoting on windows.  */
+    size += windows_backslashes;
+    }
+
+  return size;
+}
+
+/*--------------------------------------------------------------------------*/
+char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
+                                            int isUnix, int flags)
+{
+  /* String iterator.  */
+  const char* c;
+
+  /* Keep track of how many backslashes have been encountered in a row.  */
+  int windows_backslashes = 0;
+
+  /* Whether the argument must be quoted.  */
+  int needQuotes = Shell__ArgumentNeedsQuotes(in, isUnix, flags);
+  if(needQuotes)
+    {
+    /* Add the opening quote for this argument.  */
+    if(flags & Shell_Flag_WatcomQuote)
+      {
+      if(isUnix)
+        {
+        *out++ = '"';
+        }
+      *out++ = '\'';
+      }
+    else
+      {
+      *out++ = '"';
+      }
+    }
+
+  /* Scan the string for characters that require escaping or quoting.  */
+  for(c=in; *c; ++c)
+    {
+    /* Look for $(MAKEVAR) syntax if requested.  */
+    if(flags & Shell_Flag_AllowMakeVariables)
+      {
+      const char* skip = Shell__SkipMakeVariables(c);
+      if(skip != c)
+        {
+        /* Copy to the end of the make variable references.  */
+        while(c != skip)
+          {
+          *out++ = *c++;
+          }
+
+        /* The make variable reference eliminates any escaping needed
+           for preceding backslashes.  */
+        windows_backslashes = 0;
+
+        /* Stop if we have reached the end of the string.  */
+        if(!*c)
+          {
+          break;
+          }
+        }
+      }
+
+    /* Check whether this character needs escaping for the shell.  */
+    if(isUnix)
+      {
+      /* On Unix a few special characters need escaping even inside a
+         quoted argument.  */
+      if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
+        {
+        /* This character needs a backslash to escape it.  */
+        *out++ = '\\';
+        }
+      }
+    else if(flags & Shell_Flag_EchoWindows)
+      {
+      /* On Windows the built-in command shell echo never needs escaping.  */
+      }
+    else
+      {
+      /* On Windows only backslashes and double-quotes need escaping.  */
+      if(*c == '\\')
+        {
+        /* Found a backslash.  It may need to be escaped later.  */
+        ++windows_backslashes;
+        }
+      else if(*c == '"')
+        {
+        /* Found a double-quote.  Escape all immediately preceding
+           backslashes.  */
+        while(windows_backslashes > 0)
+          {
+          --windows_backslashes;
+          *out++ = '\\';
+          }
+
+        /* Add the backslash to escape the double-quote.  */
+        *out++ = '\\';
+        }
+      else
+        {
+        /* We encountered a normal character.  This eliminates any
+           escaping needed for preceding backslashes.  */
+        windows_backslashes = 0;
+        }
+      }
+
+    /* Check whether this character needs escaping for a make tool.  */
+    if(*c == '$')
+      {
+      if(flags & Shell_Flag_Make)
+        {
+        /* In Makefiles a dollar is written $$.  The make tool will
+           replace it with just $ before passing it to the shell.  */
+        *out++ = '$';
+        *out++ = '$';
+        }
+      else if(flags & Shell_Flag_VSIDE)
+        {
+        /* In a VS IDE a dollar is written "$".  If this is written in
+           an un-quoted argument it starts a quoted segment, inserts
+           the $ and ends the segment.  If it is written in a quoted
+           argument it ends quoting, inserts the $ and restarts
+           quoting.  Either way the $ is isolated from surrounding
+           text to avoid looking like a variable reference.  */
+        *out++ = '"';
+        *out++ = '$';
+        *out++ = '"';
+        }
+      else
+        {
+        /* Otherwise a dollar is written just $. */
+        *out++ = '$';
+        }
+      }
+    else if(*c == '#')
+      {
+      if((flags & Shell_Flag_Make) &&
+         (flags & Shell_Flag_WatcomWMake))
+        {
+        /* In Watcom WMake makefiles a pound is written $#.  The make
+           tool will replace it with just # before passing it to the
+           shell.  */
+        *out++ = '$';
+        *out++ = '#';
+        }
+      else
+        {
+        /* Otherwise a pound is written just #. */
+        *out++ = '#';
+        }
+      }
+    else if(*c == '%')
+      {
+      if((flags & Shell_Flag_VSIDE) ||
+         ((flags & Shell_Flag_Make) &&
+          ((flags & Shell_Flag_MinGWMake) ||
+           (flags & Shell_Flag_NMake))))
+        {
+        /* In the VS IDE, NMake, or MinGW make a percent is written %%.  */
+        *out++ = '%';
+        *out++ = '%';
+        }
+      else
+        {
+        /* Otherwise a percent is written just %. */
+        *out++ = '%';
+        }
+      }
+    else if(*c == ';')
+      {
+      if(flags & Shell_Flag_VSIDE)
+        {
+        /* In a VS IDE a semicolon is written ";".  If this is written
+           in an un-quoted argument it starts a quoted segment,
+           inserts the ; and ends the segment.  If it is written in a
+           quoted argument it ends quoting, inserts the ; and restarts
+           quoting.  Either way the ; is isolated.  */
+        *out++ = '"';
+        *out++ = ';';
+        *out++ = '"';
+        }
+      else
+        {
+        /* Otherwise a semicolon is written just ;. */
+        *out++ = ';';
+        }
+      }
+    else
+      {
+      /* Store this character.  */
+      *out++ = *c;
+      }
+    }
+
+  if(needQuotes)
+    {
+    /* Add enough backslashes to escape any trailing ones.  */
+    while(windows_backslashes > 0)
+      {
+      --windows_backslashes;
+      *out++ = '\\';
+      }
+
+    /* Add the closing quote for this argument.  */
+    if(flags & Shell_Flag_WatcomQuote)
+      {
+      *out++ = '\'';
+      if(isUnix)
+        {
+        *out++ = '"';
+        }
+      }
+    else
+      {
+      *out++ = '"';
+      }
+    }
+
+  /* Store a terminating null without incrementing.  */
+  *out = 0;
+
+  return out;
+}
+
+/*--------------------------------------------------------------------------*/
+char* cmOutputConverter::Shell_GetArgumentForWindows(const char* in,
+                                                     char* out, int flags)
+{
+  return Shell__GetArgument(in, out, 0, flags);
+}
+
+/*--------------------------------------------------------------------------*/
+char* cmOutputConverter::Shell_GetArgumentForUnix(const char* in,
+                                                  char* out, int flags)
+{
+  return Shell__GetArgument(in, out, 1, flags);
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell_GetArgumentSizeForWindows(const char* in,
+                                                       int flags)
+{
+  return Shell__GetArgumentSize(in, 0, flags);
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell_GetArgumentSizeForUnix(const char* in,
+                                                    int flags)
+{
+  return Shell__GetArgumentSize(in, 1, flags);
+}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
new file mode 100644
index 0000000..852df5d
--- /dev/null
+++ b/Source/cmOutputConverter.h
@@ -0,0 +1,183 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmOutputConverter_h
+#define cmOutputConverter_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmGlobalGenerator.h"
+#include "cmState.h"
+
+class cmOutputConverter
+{
+public:
+  cmOutputConverter(cmState::Snapshot snapshot);
+
+  /**
+   * Convert something to something else. This is a centralized conversion
+   * routine used by the generators to handle relative paths and the like.
+   * The flags determine what is actually done.
+   *
+   * relative: treat the argument as a directory and convert it to make it
+   * relative or full or unchanged. If relative (HOME, START etc) then that
+   * specifies what it should be relative to.
+   *
+   * output: make the result suitable for output to a...
+   *
+   * optional: should any relative path operation be controlled by the rel
+   * path setting
+   */
+  enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT };
+  enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE };
+  std::string ConvertToOutputFormat(const std::string& source,
+                                    OutputFormat output) const;
+  std::string Convert(const std::string& remote, RelativeRoot local,
+                      OutputFormat output = UNCHANGED) const;
+  std::string Convert(RelativeRoot remote, const std::string& local,
+                      OutputFormat output = UNCHANGED,
+                      bool optional = false) const;
+  std::string ConvertDirectorySeparatorsForShell(
+                                             const std::string& source) const;
+
+  /**
+    * Get path for the specified relative root.
+    */
+  const char* GetRelativeRootPath(RelativeRoot relroot) const;
+
+  ///! for existing files convert to output path and short path if spaces
+  std::string ConvertToOutputForExisting(const std::string& remote,
+                                         RelativeRoot local = START_OUTPUT,
+                                         OutputFormat format = SHELL) const;
+
+  /** For existing path identified by RelativeRoot convert to output
+      path and short path if spaces.  */
+  std::string ConvertToOutputForExisting(RelativeRoot remote,
+                                         const std::string& local = "",
+                                         OutputFormat format = SHELL) const;
+
+  void SetLinkScriptShell(bool linkScriptShell);
+
+  /**
+   * Flags to pass to Shell_GetArgumentForWindows or
+   * Shell_GetArgumentForUnix.  These modify the generated
+   * quoting and escape sequences to work under alternative
+   * environments.
+   */
+  enum Shell_Flag_e
+  {
+    /** The target shell is in a makefile.  */
+    Shell_Flag_Make               = (1<<0),
+
+    /** The target shell is in a VS project file.  Do not use with
+        Shell_Flag_Make.  */
+    Shell_Flag_VSIDE              = (1<<1),
+
+    /** In a windows shell the argument is being passed to "echo".  */
+    Shell_Flag_EchoWindows        = (1<<2),
+
+    /** The target shell is in a Watcom WMake makefile.  */
+    Shell_Flag_WatcomWMake        = (1<<3),
+
+    /** The target shell is in a MinGW Make makefile.  */
+    Shell_Flag_MinGWMake          = (1<<4),
+
+    /** The target shell is in a NMake makefile.  */
+    Shell_Flag_NMake              = (1<<5),
+
+    /** Make variable reference syntax $(MAKEVAR) should not be escaped
+        to allow a build tool to replace it.  Replacement values
+        containing spaces, quotes, backslashes, or other
+        non-alphanumeric characters that have significance to some makes
+        or shells produce undefined behavior.  */
+    Shell_Flag_AllowMakeVariables = (1<<6),
+
+    /** The target shell quoting uses extra single Quotes for Watcom tools.  */
+    Shell_Flag_WatcomQuote        = (1<<7)
+  };
+
+  /**
+   * Transform the given command line argument for use in a Windows or
+   * Unix shell.  Returns a pointer to the end of the command line
+   * argument in the provided output buffer.  Flags may be passed to
+   * modify the generated quoting and escape sequences to work under
+   * alternative environments.
+   */
+  static char* Shell_GetArgumentForWindows(const char* in, char* out,
+                                           int flags);
+  static char* Shell_GetArgumentForUnix(const char* in, char* out, int flags);
+
+  /**
+   * Compute the size of the buffer required to store the output from
+   * Shell_GetArgumentForWindows or Shell_GetArgumentForUnix.  The flags
+   * passed must be identical between the two calls.
+   */
+  static int Shell_GetArgumentSizeForWindows(const char* in, int flags);
+  static int Shell_GetArgumentSizeForUnix(const char* in, int flags);
+
+  std::string EscapeForShell(const std::string& str,
+                                    bool makeVars = false,
+                                    bool forEcho = false,
+                                    bool useWatcomQuote = false) const;
+
+  static std::string EscapeForCMake(const std::string& str);
+
+  /** Compute an escaped version of the given argument for use in a
+      windows shell.  */
+  static std::string EscapeWindowsShellArgument(const char* arg,
+                                                int shell_flags);
+
+  enum FortranFormat
+    {
+    FortranFormatNone,
+    FortranFormatFixed,
+    FortranFormatFree
+    };
+  static FortranFormat GetFortranFormat(const char* value);
+
+  /**
+   * Convert the given remote path to a relative path with respect to
+   * the given local path.  The local path must be given in component
+   * form (see SystemTools::SplitPath) without a trailing slash.  The
+   * remote path must use forward slashes and not already be escaped
+   * or quoted.
+   */
+  std::string ConvertToRelativePath(const std::vector<std::string>& local,
+                                    const std::string& in_remote,
+                                    bool force = false) const;
+
+private:
+  cmState* GetState() const;
+
+  std::string ConvertToOutputForExistingCommon(const std::string& remote,
+                                               std::string const& result,
+                                               OutputFormat format) const;
+
+  static int Shell__CharIsWhitespace(char c);
+  static int Shell__CharNeedsQuotesOnUnix(char c);
+  static int Shell__CharNeedsQuotesOnWindows(char c);
+  static int Shell__CharNeedsQuotes(char c, int isUnix, int flags);
+  static int Shell__CharIsMakeVariableName(char c);
+  static const char* Shell__SkipMakeVariables(const char* c);
+  static int Shell__ArgumentNeedsQuotes(const char* in,
+                                        int isUnix, int flags);
+  static int Shell__GetArgumentSize(const char* in,
+                                    int isUnix, int flags);
+  static char* Shell__GetArgument(const char* in, char* out,
+                                  int isUnix, int flags);
+
+private:
+  cmState::Snapshot StateSnapshot;
+
+  bool LinkScriptShell;
+};
+
+#endif
diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h
index 95eba38..6a09673 100644
--- a/Source/cmOutputRequiredFilesCommand.h
+++ b/Source/cmOutputRequiredFilesCommand.h
@@ -23,7 +23,6 @@ public:
   virtual bool InitialPass(std::vector<std::string> const& args,
                            cmExecutionStatus &status);
   virtual std::string GetName() const { return "output_required_files";}
-  virtual bool IsDiscouraged() const { return true; }
 
   void ListDependencies(cmDependInformation const *info,
                         FILE *fout,
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index f8d61db..3eb19bb 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -255,6 +255,22 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
           {
           return false;
           }
+        if(pid == cmPolicies::CMP0001 &&
+           (status == cmPolicies::WARN || status == cmPolicies::OLD))
+          {
+          if(!(mf->GetState()
+               ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
+            {
+            // Set it to 2.4 because that is the last version where the
+            // variable had meaning.
+            mf->AddCacheDefinition
+              ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
+               "For backwards compatibility, what version of CMake "
+               "commands and "
+               "syntax should this version of CMake try to support.",
+               cmState::STRING);
+            }
+          }
         }
       }
     else
@@ -343,51 +359,38 @@ cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id)
   return e.str();
 }
 
-cmPolicies::PolicyMap::PolicyMap()
-{
-  this->UNDEFINED.set();
-}
-
 cmPolicies::PolicyStatus
 cmPolicies::PolicyMap::Get(cmPolicies::PolicyID id) const
 {
   PolicyStatus status = cmPolicies::WARN;
 
-  if (this->OLD[id])
+  if (this->Status[(POLICY_STATUS_COUNT * id) + OLD])
     {
     status = cmPolicies::OLD;
     }
-  else if (this->NEW[id])
+  else if (this->Status[(POLICY_STATUS_COUNT * id) + NEW])
     {
     status = cmPolicies::NEW;
     }
-  else if (this->REQUIRED_ALWAYS[id])
-    {
-    status = cmPolicies::REQUIRED_ALWAYS;
-    }
-  else if (this->REQUIRED_IF_USED[id])
-    {
-    status = cmPolicies::REQUIRED_IF_USED;
-    }
   return status;
 }
 
 void cmPolicies::PolicyMap::Set(cmPolicies::PolicyID id,
                                 cmPolicies::PolicyStatus status)
 {
-  this->UNDEFINED.reset(id);
-  this->OLD[id] = (status == cmPolicies::OLD);
-  this->NEW[id] = (status == cmPolicies::NEW);
-  this->REQUIRED_ALWAYS[id] = (status == cmPolicies::REQUIRED_ALWAYS);
-  this->REQUIRED_IF_USED[id] = (status == cmPolicies::REQUIRED_IF_USED);
+  this->Status[(POLICY_STATUS_COUNT * id) + OLD] = (status == OLD);
+  this->Status[(POLICY_STATUS_COUNT * id) + WARN] = (status == WARN);
+  this->Status[(POLICY_STATUS_COUNT * id) + NEW] = (status == NEW);
 }
 
 bool cmPolicies::PolicyMap::IsDefined(cmPolicies::PolicyID id) const
 {
-  return !this->UNDEFINED[id];
+  return this->Status[(POLICY_STATUS_COUNT * id) + OLD]
+      || this->Status[(POLICY_STATUS_COUNT * id) + WARN]
+      || this->Status[(POLICY_STATUS_COUNT * id) + NEW];
 }
 
 bool cmPolicies::PolicyMap::IsEmpty() const
 {
-  return !this->UNDEFINED.none();
+  return this->Status.none();
 }
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 00d857a..a549d18 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -12,7 +12,7 @@
 #ifndef cmPolicies_h
 #define cmPolicies_h
 
-#include "cmCustomCommand.h"
+#include "cmStandardIncludes.h"
 
 #include <bitset>
 
@@ -217,7 +217,14 @@ class cmPolicy;
     3, 3, 0, cmPolicies::WARN) \
   SELECT(POLICY, CMP0063, \
     "Honor visibility properties for all target types.", \
-    3, 3, 0, cmPolicies::WARN)
+    3, 3, 0, cmPolicies::WARN) \
+  SELECT(POLICY, CMP0064, \
+    "Support new TEST if() operator.", \
+    3, 4, 0, cmPolicies::WARN) \
+  SELECT(POLICY, CMP0065, \
+    "Do not add flags to export symbols from executables without " \
+    "the ENABLE_EXPORTS target property.", \
+    3, 4, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -228,7 +235,7 @@ class cmPolicy;
  * \brief Handles changes in CMake behavior and policies
  *
  * See the cmake wiki section on
- * <a href="http://www.cmake.org/Wiki/CMake/Policies">policies</a>
+ * <a href="https://cmake.org/Wiki/CMake/Policies">policies</a>
  * for an overview of this class's purpose
  */
 class cmPolicies
@@ -281,18 +288,14 @@ public:
   /** Represent a set of policy values.  */
   struct PolicyMap
   {
-    PolicyMap();
     PolicyStatus Get(PolicyID id) const;
     void Set(PolicyID id, PolicyStatus status);
     bool IsDefined(PolicyID id) const;
     bool IsEmpty() const;
 
   private:
-    std::bitset<cmPolicies::CMPCOUNT> UNDEFINED;
-    std::bitset<cmPolicies::CMPCOUNT> OLD;
-    std::bitset<cmPolicies::CMPCOUNT> NEW;
-    std::bitset<cmPolicies::CMPCOUNT> REQUIRED_IF_USED;
-    std::bitset<cmPolicies::CMPCOUNT> REQUIRED_ALWAYS;
+#define POLICY_STATUS_COUNT 3
+    std::bitset<cmPolicies::CMPCOUNT * POLICY_STATUS_COUNT> Status;
   };
 };
 
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index d2f7bf3..15d9ed0 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -44,7 +44,7 @@ void cmProcessTools::RunProcess(struct cmsysProcess_s* cp,
 
 //----------------------------------------------------------------------------
 cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR):
-  Separator(sep), IgnoreCR(ignoreCR), Log(0), Prefix(0), LineEnd('\0')
+   Log(0), Prefix(0), Separator(sep), LineEnd('\0'), IgnoreCR(ignoreCR)
 {
 }
 
diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h
index 439726d..23833ca 100644
--- a/Source/cmProcessTools.h
+++ b/Source/cmProcessTools.h
@@ -51,12 +51,12 @@ public:
     /** Configure logging of lines as they are extracted.  */
     void SetLog(std::ostream* log, const char* prefix);
   protected:
-    char Separator;
-    bool IgnoreCR;
     std::ostream* Log;
     const char* Prefix;
-    char LineEnd;
     std::string Line;
+    char Separator;
+    char LineEnd;
+    bool IgnoreCR;
     virtual bool ProcessChunk(const char* data, int length);
 
     /** Implement in a subclass to process one line of input.  It
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 176cb0d..7123125 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -20,7 +20,7 @@ bool cmProjectCommand
     this->SetError("PROJECT called with incorrect number of arguments");
     return false;
     }
-  this->Makefile->SetProjectName(args[0].c_str());
+  this->Makefile->SetProjectName(args[0]);
 
   std::string bindir = args[0];
   bindir += "_BINARY_DIR";
@@ -53,7 +53,7 @@ bool cmProjectCommand
   // CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build
   // will work.
   if(!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME")
-     || (this->Makefile->GetLocalGenerator()->IsRootMakefile()))
+     || (this->Makefile->IsRootMakefile()))
     {
     this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", args[0].c_str());
     this->Makefile->AddCacheDefinition
@@ -233,7 +233,6 @@ bool cmProjectCommand
   const char* include = this->Makefile->GetDefinition(extraInclude);
   if(include)
     {
-    std::string fullFilePath;
     bool readit =
       this->Makefile->ReadDependentFile(include);
     if(!readit && !cmSystemTools::GetFatalErrorOccured())
diff --git a/Source/cmProperty.cxx b/Source/cmProperty.cxx
index 40976db..ef57068 100644
--- a/Source/cmProperty.cxx
+++ b/Source/cmProperty.cxx
@@ -12,17 +12,14 @@
 #include "cmProperty.h"
 #include "cmSystemTools.h"
 
-void cmProperty::Set(const std::string& name, const char *value)
+void cmProperty::Set(const char *value)
 {
-  this->Name = name;
   this->Value = value;
   this->ValueHasBeenSet = true;
 }
 
-void cmProperty::Append(const std::string& name, const char *value,
-                        bool asString)
+void cmProperty::Append(const char *value, bool asString)
 {
-  this->Name = name;
   if(!this->Value.empty() && *value && !asString)
     {
     this->Value += ";";
diff --git a/Source/cmProperty.h b/Source/cmProperty.h
index 659c4c3..e026372 100644
--- a/Source/cmProperty.h
+++ b/Source/cmProperty.h
@@ -21,11 +21,10 @@ public:
                    TEST, VARIABLE, CACHED_VARIABLE, INSTALL };
 
   // set this property
-  void Set(const std::string& name, const char *value);
+  void Set(const char *value);
 
   // append to this property
-  void Append(const std::string& name, const char *value,
-              bool asString = false);
+  void Append(const char *value, bool asString = false);
 
   // get the value
   const char *GetValue() const;
@@ -34,7 +33,6 @@ public:
   cmProperty() { this->ValueHasBeenSet = false; }
 
 protected:
-  std::string Name;
   std::string Value;
   bool ValueHasBeenSet;
 };
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
index 3875318..776fad1 100644
--- a/Source/cmPropertyDefinitionMap.cxx
+++ b/Source/cmPropertyDefinitionMap.cxx
@@ -29,9 +29,9 @@ void cmPropertyDefinitionMap
     }
 }
 
-bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name)
+bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const
 {
-  cmPropertyDefinitionMap::iterator it = this->find(name);
+  cmPropertyDefinitionMap::const_iterator it = this->find(name);
   if (it == this->end())
     {
     return false;
@@ -40,9 +40,9 @@ bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name)
   return true;
 }
 
-bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name)
+bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const
 {
-  cmPropertyDefinitionMap::iterator it = this->find(name);
+  cmPropertyDefinitionMap::const_iterator it = this->find(name);
   if (it == this->end())
     {
     return false;
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
index 00c7328..f95c721 100644
--- a/Source/cmPropertyDefinitionMap.h
+++ b/Source/cmPropertyDefinitionMap.h
@@ -27,10 +27,10 @@ public:
                       bool chain);
 
   // has a named property been defined
-  bool IsPropertyDefined(const std::string& name);
+  bool IsPropertyDefined(const std::string& name) const;
 
   // is a named property set to chain
-  bool IsPropertyChained(const std::string& name);
+  bool IsPropertyChained(const std::string& name) const;
 };
 
 #endif
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index 070f6f1..ef09dbc 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -14,6 +14,8 @@
 #include "cmake.h"
 #include "cmState.h"
 
+#include <assert.h>
+
 cmProperty *cmPropertyMap::GetOrCreateProperty(const std::string& name)
 {
   cmPropertyMap::iterator it = this->find(name);
@@ -29,54 +31,39 @@ cmProperty *cmPropertyMap::GetOrCreateProperty(const std::string& name)
   return prop;
 }
 
-void cmPropertyMap::SetProperty(const std::string& name, const char *value,
-                                cmProperty::ScopeType scope)
+void cmPropertyMap::SetProperty(const std::string& name, const char *value)
 {
   if(!value)
     {
     this->erase(name);
     return;
     }
-  (void)scope;
 
   cmProperty *prop = this->GetOrCreateProperty(name);
-  prop->Set(name,value);
+  prop->Set(value);
 }
 
 void cmPropertyMap::AppendProperty(const std::string& name, const char* value,
-                                   cmProperty::ScopeType scope, bool asString)
+                                   bool asString)
 {
   // Skip if nothing to append.
   if(!value || !*value)
     {
     return;
     }
-  (void)scope;
 
   cmProperty *prop = this->GetOrCreateProperty(name);
-  prop->Append(name,value,asString);
+  prop->Append(value,asString);
 }
 
 const char *cmPropertyMap
-::GetPropertyValue(const std::string& name,
-                   cmProperty::ScopeType scope,
-                   bool &chain) const
+::GetPropertyValue(const std::string& name) const
 {
-  chain = false;
-  if (name.empty())
-    {
-    return 0;
-    }
+  assert(!name.empty());
 
   cmPropertyMap::const_iterator it = this->find(name);
   if (it == this->end())
     {
-    // should we chain up?
-    if (this->CMakeInstance)
-      {
-      chain = this->CMakeInstance->GetState()->
-                    IsPropertyChained(name,scope);
-      }
     return 0;
     }
   return it->second.GetValue();
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index 02d4235..a9062db 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -14,29 +14,17 @@
 
 #include "cmProperty.h"
 
-class cmake;
-
 class cmPropertyMap : public std::map<std::string,cmProperty>
 {
 public:
   cmProperty *GetOrCreateProperty(const std::string& name);
 
-  void SetProperty(const std::string& name, const char *value,
-                   cmProperty::ScopeType scope);
+  void SetProperty(const std::string& name, const char *value);
 
   void AppendProperty(const std::string& name, const char* value,
-                      cmProperty::ScopeType scope, bool asString=false);
-
-  const char *GetPropertyValue(const std::string& name,
-                               cmProperty::ScopeType scope,
-                               bool &chain) const;
-
-  void SetCMakeInstance(cmake *cm) { this->CMakeInstance = cm; }
-
-  cmPropertyMap() { this->CMakeInstance = 0;}
+                      bool asString=false);
 
-private:
-  cmake *CMakeInstance;
+  const char *GetPropertyValue(const std::string& name) const;
 };
 
 #endif
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
new file mode 100644
index 0000000..d52ab78
--- /dev/null
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -0,0 +1,1074 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2004-2011 Kitware, Inc.
+  Copyright 2011 Alexander Neundorf (neundorf at kde.org)
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+
+#include "cmQtAutoGeneratorInitializer.h"
+
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+
+#include <sys/stat.h>
+
+#include <cmsys/FStream.hxx>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include "cmGlobalVisualStudioGenerator.h"
+#endif
+
+std::string cmQtAutoGeneratorInitializer::GetAutogenTargetName(
+    cmTarget const* target)
+{
+  std::string autogenTargetName = target->GetName();
+  autogenTargetName += "_automoc";
+  return autogenTargetName;
+}
+
+std::string cmQtAutoGeneratorInitializer::GetAutogenTargetDir(
+    cmTarget const* target)
+{
+  cmMakefile* makefile = target->GetMakefile();
+  std::string targetDir = makefile->GetCurrentBinaryDirectory();
+  targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();
+  targetDir += "/";
+  targetDir += cmQtAutoGeneratorInitializer::GetAutogenTargetName(target);
+  targetDir += ".dir/";
+  return targetDir;
+}
+
+static void copyTargetProperty(cmTarget* destinationTarget,
+                               cmTarget* sourceTarget,
+                               const std::string& propertyName)
+{
+  const char* propertyValue = sourceTarget->GetProperty(propertyName);
+  if (propertyValue)
+    {
+    destinationTarget->SetProperty(propertyName, propertyValue);
+    }
+}
+
+static std::string cmQtAutoGeneratorsStripCR(std::string const& line)
+{
+  // Strip CR characters rcc may have printed (possibly more than one!).
+  std::string::size_type cr = line.find('\r');
+  if (cr != line.npos)
+    {
+    return line.substr(0, cr);
+    }
+  return line;
+}
+
+static std::string ReadAll(const std::string& filename)
+{
+  cmsys::ifstream file(filename.c_str());
+  std::stringstream stream;
+  stream << file.rdbuf();
+  file.close();
+  return stream.str();
+}
+
+std::string cmQtAutoGeneratorInitializer::ListQt5RccInputs(cmSourceFile* sf,
+                                            cmTarget const* target,
+                                            std::vector<std::string>& depends)
+{
+  std::string rccCommand
+      = cmQtAutoGeneratorInitializer::GetRccExecutable(target);
+  std::vector<std::string> qrcEntries;
+
+  std::vector<std::string> command;
+  command.push_back(rccCommand);
+  command.push_back("--list");
+
+  std::string absFile = cmsys::SystemTools::GetRealPath(
+                                              sf->GetFullPath());
+
+  command.push_back(absFile);
+
+  std::string rccStdOut;
+  std::string rccStdErr;
+  int retVal = 0;
+  bool result = cmSystemTools::RunSingleCommand(
+    command, &rccStdOut, &rccStdErr,
+    &retVal, 0, cmSystemTools::OUTPUT_NONE);
+  if (!result || retVal)
+    {
+    std::cerr << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath()
+              << " failed:\n" << rccStdOut << "\n" << rccStdErr << std::endl;
+    return std::string();
+    }
+
+  {
+  std::istringstream ostr(rccStdOut);
+  std::string oline;
+  while(std::getline(ostr, oline))
+    {
+    oline = cmQtAutoGeneratorsStripCR(oline);
+    if(!oline.empty())
+      {
+      qrcEntries.push_back(oline);
+      }
+    }
+  }
+
+  {
+  std::istringstream estr(rccStdErr);
+  std::string eline;
+  while(std::getline(estr, eline))
+    {
+    eline = cmQtAutoGeneratorsStripCR(eline);
+    if (cmHasLiteralPrefix(eline, "RCC: Error in"))
+      {
+      static std::string searchString = "Cannot find file '";
+
+      std::string::size_type pos = eline.find(searchString);
+      if (pos == std::string::npos)
+        {
+        std::cerr << "AUTOGEN: error: Rcc lists unparsable output "
+                  << eline << std::endl;
+        return std::string();
+        }
+      pos += searchString.length();
+      std::string::size_type sz = eline.size() - pos - 1;
+      qrcEntries.push_back(eline.substr(pos, sz));
+      }
+    }
+  }
+
+  depends.insert(depends.end(), qrcEntries.begin(), qrcEntries.end());
+  return cmJoin(qrcEntries, "@list_sep@");
+}
+
+std::string cmQtAutoGeneratorInitializer::ListQt4RccInputs(cmSourceFile* sf,
+                                            std::vector<std::string>& depends)
+{
+  const std::string qrcContents = ReadAll(sf->GetFullPath());
+
+  cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
+
+  std::string entriesList;
+  const char* sep = "";
+
+  size_t offset = 0;
+  while (fileMatchRegex.find(qrcContents.c_str() + offset))
+    {
+    std::string qrcEntry = fileMatchRegex.match(1);
+
+    offset += qrcEntry.size();
+
+    cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
+    fileReplaceRegex.find(qrcEntry);
+    std::string tag = fileReplaceRegex.match(1);
+
+    qrcEntry = qrcEntry.substr(tag.size());
+
+    if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str()))
+      {
+      qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry;
+      }
+
+    entriesList += sep;
+    entriesList += qrcEntry;
+    sep = "@list_sep@";
+    depends.push_back(qrcEntry);
+    }
+  return entriesList;
+}
+
+
+void cmQtAutoGeneratorInitializer::InitializeAutogenSources(cmTarget* target)
+{
+  cmMakefile* makefile = target->GetMakefile();
+
+  if (target->GetPropertyAsBool("AUTOMOC"))
+    {
+    std::string automocTargetName =
+        cmQtAutoGeneratorInitializer::GetAutogenTargetName(target);
+    std::string mocCppFile = makefile->GetCurrentBinaryDirectory();
+    mocCppFile += "/";
+    mocCppFile += automocTargetName;
+    mocCppFile += ".cpp";
+    makefile->GetOrCreateSource(mocCppFile, true);
+    makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+                            mocCppFile.c_str(), false);
+
+    target->AddSource(mocCppFile);
+    }
+}
+
+void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
+                                                 cmLocalGenerator* lg,
+                                                 cmTarget* target)
+{
+  cmMakefile* makefile = target->GetMakefile();
+
+  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
+  if (qtMajorVersion == "")
+    {
+    qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
+    }
+
+  // create a custom target for running generators at buildtime:
+  std::string autogenTargetName =
+      cmQtAutoGeneratorInitializer::GetAutogenTargetName(target);
+
+  std::string targetDir =
+      cmQtAutoGeneratorInitializer::GetAutogenTargetDir(target);
+
+  cmCustomCommandLine currentLine;
+  currentLine.push_back(cmSystemTools::GetCMakeCommand());
+  currentLine.push_back("-E");
+  currentLine.push_back("cmake_autogen");
+  currentLine.push_back(targetDir);
+  currentLine.push_back("$<CONFIGURATION>");
+
+  cmCustomCommandLines commandLines;
+  commandLines.push_back(currentLine);
+
+  std::string workingDirectory = cmSystemTools::CollapseFullPath(
+                                    "", makefile->GetCurrentBinaryDirectory());
+
+  std::vector<std::string> depends;
+  if (const char *autogenDepends =
+                                target->GetProperty("AUTOGEN_TARGET_DEPENDS"))
+    {
+    cmSystemTools::ExpandListArgument(autogenDepends, depends);
+    }
+  std::vector<std::string> toolNames;
+  if (target->GetPropertyAsBool("AUTOMOC"))
+    {
+    toolNames.push_back("moc");
+    }
+  if (target->GetPropertyAsBool("AUTOUIC"))
+    {
+    toolNames.push_back("uic");
+    }
+  if (target->GetPropertyAsBool("AUTORCC"))
+    {
+    toolNames.push_back("rcc");
+    }
+
+  std::string tools = toolNames[0];
+  toolNames.erase(toolNames.begin());
+  while (toolNames.size() > 1)
+    {
+    tools += ", " + toolNames[0];
+    toolNames.erase(toolNames.begin());
+    }
+  if (toolNames.size() == 1)
+    {
+    tools += " and " + toolNames[0];
+    }
+  std::string autogenComment = "Automatic " + tools + " for target ";
+  autogenComment += target->GetName();
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  bool usePRE_BUILD = false;
+  cmGlobalGenerator* gg = lg->GetGlobalGenerator();
+  if(gg->GetName().find("Visual Studio") != std::string::npos)
+    {
+    cmGlobalVisualStudioGenerator* vsgg =
+      static_cast<cmGlobalVisualStudioGenerator*>(gg);
+    // Under VS >= 7 use a PRE_BUILD event instead of a separate target to
+    // reduce the number of targets loaded into the IDE.
+    // This also works around a VS 11 bug that may skip updating the target:
+    //  https://connect.microsoft.com/VisualStudio/feedback/details/769495
+    usePRE_BUILD = vsgg->GetVersion() >= cmGlobalVisualStudioGenerator::VS7;
+    if(usePRE_BUILD)
+      {
+      for (std::vector<std::string>::iterator it = depends.begin();
+            it != depends.end(); ++it)
+        {
+        if(!makefile->FindTargetToUse(it->c_str()))
+          {
+          usePRE_BUILD = false;
+          break;
+          }
+        }
+      }
+    }
+#endif
+
+  std::vector<std::string> rcc_output;
+  bool const isNinja =
+    lg->GetGlobalGenerator()->GetName() == "Ninja";
+  if(isNinja
+#if defined(_WIN32) && !defined(__CYGWIN__)
+        || usePRE_BUILD
+#endif
+        )
+    {
+    std::vector<cmSourceFile*> srcFiles;
+    cmGeneratorTarget* gtgt =
+        lg->GetGlobalGenerator()->GetGeneratorTarget(target);
+    gtgt->GetConfigCommonSourceFiles(srcFiles);
+    for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
+        fileIt != srcFiles.end();
+        ++fileIt)
+      {
+      cmSourceFile* sf = *fileIt;
+      std::string absFile = cmsys::SystemTools::GetRealPath(
+                                                sf->GetFullPath());
+
+      std::string ext = sf->GetExtension();
+
+      if (target->GetPropertyAsBool("AUTORCC"))
+        {
+        if (ext == "qrc"
+            && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))
+          {
+          std::string basename = cmsys::SystemTools::
+                                  GetFilenameWithoutLastExtension(absFile);
+
+          std::string rcc_output_dir = target->GetSupportDirectory();
+          cmSystemTools::MakeDirectory(rcc_output_dir.c_str());
+          std::string rcc_output_file = rcc_output_dir;
+          rcc_output_file += "/qrc_" + basename + ".cpp";
+          rcc_output.push_back(rcc_output_file);
+
+          if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))
+            {
+            if (qtMajorVersion == "5")
+              {
+              cmQtAutoGeneratorInitializer::ListQt5RccInputs(sf, target,
+                                                              depends);
+              }
+            else
+              {
+              cmQtAutoGeneratorInitializer::ListQt4RccInputs(sf, depends);
+              }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+            // Cannot use PRE_BUILD because the resource files themselves
+            // may not be sources within the target so VS may not know the
+            // target needs to re-build at all.
+            usePRE_BUILD = false;
+#endif
+            }
+          }
+        }
+      }
+    }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  if(usePRE_BUILD)
+    {
+    // Add the pre-build command directly to bypass the OBJECT_LIBRARY
+    // rejection in cmMakefile::AddCustomCommandToTarget because we know
+    // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case.
+    std::vector<std::string> no_output;
+    std::vector<std::string> no_byproducts;
+    cmCustomCommand cc(makefile, no_output, no_byproducts, depends,
+                       commandLines, autogenComment.c_str(),
+                       workingDirectory.c_str());
+    cc.SetEscapeOldStyle(false);
+    cc.SetEscapeAllowMakeVars(true);
+    target->AddPreBuildCommand(cc);
+    }
+  else
+#endif
+    {
+    cmTarget* autogenTarget = makefile->AddUtilityCommand(
+                                autogenTargetName, true,
+                                workingDirectory.c_str(),
+                                /*byproducts=*/rcc_output, depends,
+                                commandLines, false, autogenComment.c_str());
+
+    cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg);
+    makefile->AddGeneratorTarget(autogenTarget, gt);
+
+    // Set target folder
+    const char* autogenFolder = makefile->GetState()
+                                ->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
+    if (!autogenFolder)
+      {
+      autogenFolder = makefile->GetState()
+                                ->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
+      }
+    if (autogenFolder && *autogenFolder)
+      {
+      autogenTarget->SetProperty("FOLDER", autogenFolder);
+      }
+    else
+      {
+      // inherit FOLDER property from target (#13688)
+      copyTargetProperty(autogenTarget, target, "FOLDER");
+      }
+
+    target->AddUtility(autogenTargetName);
+    }
+}
+
+static void GetCompileDefinitionsAndDirectories(cmTarget const* target,
+                                                const std::string& config,
+                                                std::string &incs,
+                                                std::string &defs)
+{
+  cmMakefile* makefile = target->GetMakefile();
+  cmGlobalGenerator* globalGen = makefile->GetGlobalGenerator();
+  std::vector<std::string> includeDirs;
+  cmGeneratorTarget *gtgt = globalGen->GetGeneratorTarget(target);
+  cmLocalGenerator *localGen = gtgt->GetLocalGenerator();
+  // Get the include dirs for this target, without stripping the implicit
+  // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667
+  localGen->GetIncludeDirectories(includeDirs, gtgt, "CXX", config, false);
+
+  incs = cmJoin(includeDirs, ";");
+
+  std::set<std::string> defines;
+  localGen->AddCompileDefinitions(defines, target, config, "CXX");
+
+  defs += cmJoin(defines, ";");
+}
+
+void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
+    cmTarget const* target)
+{
+  cmMakefile* makefile = target->GetMakefile();
+
+  // forget the variables added here afterwards again:
+  cmMakefile::ScopePushPop varScope(makefile);
+  static_cast<void>(varScope);
+
+  // create a custom target for running generators at buildtime:
+  std::string autogenTargetName =
+      cmQtAutoGeneratorInitializer::GetAutogenTargetName(target);
+
+  makefile->AddDefinition("_moc_target_name",
+          cmOutputConverter::EscapeForCMake(autogenTargetName).c_str());
+  makefile->AddDefinition("_origin_target_name",
+          cmOutputConverter::EscapeForCMake(target->GetName()).c_str());
+
+  std::string targetDir =
+      cmQtAutoGeneratorInitializer::GetAutogenTargetDir(target);
+
+  const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
+  if (!qtVersion)
+    {
+    qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
+    }
+  cmGeneratorTarget *gtgt = target->GetMakefile()
+                                  ->GetGlobalGenerator()
+                                  ->GetGeneratorTarget(target);
+  if (const char *targetQtVersion =
+      gtgt->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
+    {
+    qtVersion = targetQtVersion;
+    }
+  if (qtVersion)
+    {
+    makefile->AddDefinition("_target_qt_version", qtVersion);
+    }
+
+  std::vector<std::string> skipUic;
+  std::vector<std::string> skipMoc;
+  std::vector<std::string> mocSources;
+  std::vector<std::string> mocHeaders;
+  std::map<std::string, std::string> configIncludes;
+  std::map<std::string, std::string> configDefines;
+  std::map<std::string, std::string> configUicOptions;
+
+  if (target->GetPropertyAsBool("AUTOMOC")
+      || target->GetPropertyAsBool("AUTOUIC")
+      || target->GetPropertyAsBool("AUTORCC"))
+    {
+    cmQtAutoGeneratorInitializer::SetupSourceFiles(target, skipMoc,
+                                         mocSources, mocHeaders, skipUic);
+    }
+  makefile->AddDefinition("_cpp_files",
+          cmOutputConverter::EscapeForCMake(cmJoin(mocSources, ";")).c_str());
+  if (target->GetPropertyAsBool("AUTOMOC"))
+    {
+    cmQtAutoGeneratorInitializer::SetupAutoMocTarget(target, autogenTargetName,
+                             skipMoc, mocHeaders,
+                             configIncludes, configDefines);
+    }
+  if (target->GetPropertyAsBool("AUTOUIC"))
+    {
+    cmQtAutoGeneratorInitializer::SetupAutoUicTarget(target, skipUic,
+                                                      configUicOptions);
+    }
+  if (target->GetPropertyAsBool("AUTORCC"))
+    {
+    cmQtAutoGeneratorInitializer::SetupAutoRccTarget(target);
+    }
+
+  const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT");
+  std::string inputFile = cmakeRoot;
+  inputFile += "/Modules/AutogenInfo.cmake.in";
+  std::string outputFile = targetDir;
+  outputFile += "/AutogenInfo.cmake";
+  makefile->AddDefinition("_qt_rcc_inputs",
+              makefile->GetDefinition("_qt_rcc_inputs_" + target->GetName()));
+  makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),
+                          false, true, false);
+
+  // Ensure we have write permission in case .in was read-only.
+  mode_t perm = 0;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  mode_t mode_write = S_IWRITE;
+#else
+  mode_t mode_write = S_IWUSR;
+#endif
+  cmSystemTools::GetPermissions(outputFile, perm);
+  if (!(perm & mode_write))
+    {
+    cmSystemTools::SetPermissions(outputFile, perm | mode_write);
+    }
+  if (!configDefines.empty()
+      || !configIncludes.empty()
+      || !configUicOptions.empty())
+    {
+    cmsys::ofstream infoFile(outputFile.c_str(), std::ios::app);
+    if ( !infoFile )
+      {
+      std::string error = "Internal CMake error when trying to open file: ";
+      error += outputFile.c_str();
+      error += " for writing.";
+      cmSystemTools::Error(error.c_str());
+      return;
+      }
+    if (!configDefines.empty())
+      {
+      for (std::map<std::string, std::string>::iterator
+            it = configDefines.begin(), end = configDefines.end();
+            it != end; ++it)
+        {
+        infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first <<
+          " " << it->second << ")\n";
+        }
+      }
+    if (!configIncludes.empty())
+      {
+      for (std::map<std::string, std::string>::iterator
+            it = configIncludes.begin(), end = configIncludes.end();
+            it != end; ++it)
+        {
+        infoFile << "set(AM_MOC_INCLUDES_" << it->first <<
+          " " << it->second << ")\n";
+        }
+      }
+    if (!configUicOptions.empty())
+      {
+      for (std::map<std::string, std::string>::iterator
+            it = configUicOptions.begin(), end = configUicOptions.end();
+            it != end; ++it)
+        {
+        infoFile << "set(AM_UIC_TARGET_OPTIONS_" << it->first <<
+          " " << it->second << ")\n";
+        }
+      }
+    }
+}
+
+void cmQtAutoGeneratorInitializer::SetupSourceFiles(cmTarget const* target,
+                                   std::vector<std::string>& skipMoc,
+                                   std::vector<std::string>& mocSources,
+                                   std::vector<std::string>& mocHeaders,
+                                   std::vector<std::string>& skipUic)
+{
+  cmMakefile* makefile = target->GetMakefile();
+
+  std::vector<cmSourceFile*> srcFiles;
+  cmGeneratorTarget *gtgt = target->GetMakefile()
+                                  ->GetGlobalGenerator()
+                                  ->GetGeneratorTarget(target);
+  gtgt->GetConfigCommonSourceFiles(srcFiles);
+
+  std::vector<std::string> newRccFiles;
+
+  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
+      fileIt != srcFiles.end();
+      ++fileIt)
+    {
+    cmSourceFile* sf = *fileIt;
+    std::string absFile = cmsys::SystemTools::GetRealPath(
+                                                    sf->GetFullPath());
+    bool skipFileForMoc =
+        cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
+    bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));
+
+    if(cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC")))
+      {
+      skipUic.push_back(absFile);
+      }
+
+    std::string ext = sf->GetExtension();
+
+    if (target->GetPropertyAsBool("AUTORCC"))
+      {
+      if (ext == "qrc"
+          && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))
+        {
+        std::string basename = cmsys::SystemTools::
+                                      GetFilenameWithoutLastExtension(absFile);
+
+        std::string rcc_output_dir = target->GetSupportDirectory();
+        cmSystemTools::MakeDirectory(rcc_output_dir.c_str());
+        std::string rcc_output_file = rcc_output_dir;
+        rcc_output_file += "/qrc_" + basename + ".cpp";
+        makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+                                rcc_output_file.c_str(), false);
+        makefile->GetOrCreateSource(rcc_output_file, true);
+        newRccFiles.push_back(rcc_output_file);
+        }
+      }
+
+    if (!generated)
+      {
+      if (skipFileForMoc)
+        {
+        skipMoc.push_back(absFile);
+        }
+      else
+        {
+        cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(
+                                                                ext.c_str());
+        if (fileType == cmSystemTools::CXX_FILE_FORMAT)
+          {
+          mocSources.push_back(absFile);
+          }
+        else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)
+          {
+          mocHeaders.push_back(absFile);
+          }
+        }
+      }
+    }
+
+  for(std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();
+      fileIt != newRccFiles.end();
+      ++fileIt)
+    {
+    const_cast<cmTarget*>(target)->AddSource(*fileIt);
+    }
+}
+
+void cmQtAutoGeneratorInitializer::SetupAutoMocTarget(cmTarget const* target,
+                          const std::string &autogenTargetName,
+                          std::vector<std::string> const& skipMoc,
+                          std::vector<std::string> const& mocHeaders,
+                          std::map<std::string, std::string> &configIncludes,
+                          std::map<std::string, std::string> &configDefines)
+{
+  cmMakefile* makefile = target->GetMakefile();
+
+  const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");
+  std::string _moc_options = (tmp!=0 ? tmp : "");
+  makefile->AddDefinition("_moc_options",
+          cmOutputConverter::EscapeForCMake(_moc_options).c_str());
+  makefile->AddDefinition("_skip_moc",
+          cmOutputConverter::EscapeForCMake(cmJoin(skipMoc, ";")).c_str());
+  makefile->AddDefinition("_moc_headers",
+          cmOutputConverter::EscapeForCMake(cmJoin(mocHeaders, ";")).c_str());
+  bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");
+  makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE");
+
+  std::string _moc_incs;
+  std::string _moc_compile_defs;
+  std::vector<std::string> configs;
+  const std::string& config = makefile->GetConfigurations(configs);
+  GetCompileDefinitionsAndDirectories(target, config,
+                                      _moc_incs, _moc_compile_defs);
+
+  makefile->AddDefinition("_moc_incs",
+          cmOutputConverter::EscapeForCMake(_moc_incs).c_str());
+  makefile->AddDefinition("_moc_compile_defs",
+          cmOutputConverter::EscapeForCMake(_moc_compile_defs).c_str());
+
+  for (std::vector<std::string>::const_iterator li = configs.begin();
+       li != configs.end(); ++li)
+    {
+    std::string config_moc_incs;
+    std::string config_moc_compile_defs;
+    GetCompileDefinitionsAndDirectories(target, *li,
+                                        config_moc_incs,
+                                        config_moc_compile_defs);
+    if (config_moc_incs != _moc_incs)
+      {
+      configIncludes[*li] =
+                    cmOutputConverter::EscapeForCMake(config_moc_incs);
+      if(_moc_incs.empty())
+        {
+        _moc_incs = config_moc_incs;
+        }
+      }
+    if (config_moc_compile_defs != _moc_compile_defs)
+      {
+      configDefines[*li] =
+            cmOutputConverter::EscapeForCMake(config_moc_compile_defs);
+      if(_moc_compile_defs.empty())
+        {
+        _moc_compile_defs = config_moc_compile_defs;
+        }
+      }
+    }
+
+  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+  if (strcmp(qtVersion, "5") == 0)
+    {
+    cmTarget *qt5Moc = makefile->FindTargetToUse("Qt5::moc");
+    if (!qt5Moc)
+      {
+      cmSystemTools::Error("Qt5::moc target not found ",
+                          autogenTargetName.c_str());
+      return;
+      }
+    makefile->AddDefinition("_qt_moc_executable",
+                            qt5Moc->ImportedGetLocation(""));
+    }
+  else if (strcmp(qtVersion, "4") == 0)
+    {
+    cmTarget *qt4Moc = makefile->FindTargetToUse("Qt4::moc");
+    if (!qt4Moc)
+      {
+      cmSystemTools::Error("Qt4::moc target not found ",
+                          autogenTargetName.c_str());
+      return;
+      }
+    makefile->AddDefinition("_qt_moc_executable",
+                            qt4Moc->ImportedGetLocation(""));
+    }
+  else
+    {
+    cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "
+                        "Qt 5 ", autogenTargetName.c_str());
+    }
+}
+
+static void GetUicOpts(cmTarget const* target, const std::string& config,
+                       std::string &optString)
+{
+  cmGeneratorTarget *gtgt = target->GetMakefile()
+                                  ->GetGlobalGenerator()
+                                  ->GetGeneratorTarget(target);
+  std::vector<std::string> opts;
+  gtgt->GetAutoUicOptions(opts, config);
+  optString = cmJoin(opts, ";");
+}
+
+void cmQtAutoGeneratorInitializer::SetupAutoUicTarget(cmTarget const* target,
+                          std::vector<std::string> const& skipUic,
+                          std::map<std::string, std::string> &configUicOptions)
+{
+  cmMakefile *makefile = target->GetMakefile();
+
+  std::set<std::string> skipped;
+  skipped.insert(skipUic.begin(), skipUic.end());
+
+  makefile->AddDefinition("_skip_uic",
+          cmOutputConverter::EscapeForCMake(cmJoin(skipUic, ";")).c_str());
+
+  std::vector<cmSourceFile*> uiFilesWithOptions
+                                        = makefile->GetQtUiFilesWithOptions();
+
+  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+
+  std::string _uic_opts;
+  std::vector<std::string> configs;
+  const std::string& config = makefile->GetConfigurations(configs);
+  GetUicOpts(target, config, _uic_opts);
+
+  if (!_uic_opts.empty())
+    {
+    _uic_opts = cmOutputConverter::EscapeForCMake(_uic_opts);
+    makefile->AddDefinition("_uic_target_options", _uic_opts.c_str());
+    }
+  for (std::vector<std::string>::const_iterator li = configs.begin();
+       li != configs.end(); ++li)
+    {
+    std::string config_uic_opts;
+    GetUicOpts(target, *li, config_uic_opts);
+    if (config_uic_opts != _uic_opts)
+      {
+      configUicOptions[*li] =
+                    cmOutputConverter::EscapeForCMake(config_uic_opts);
+      if(_uic_opts.empty())
+        {
+        _uic_opts = config_uic_opts;
+        }
+      }
+    }
+
+  std::string uiFileFiles;
+  std::string uiFileOptions;
+  const char* sep = "";
+
+  for(std::vector<cmSourceFile*>::const_iterator fileIt =
+      uiFilesWithOptions.begin();
+      fileIt != uiFilesWithOptions.end();
+      ++fileIt)
+    {
+    cmSourceFile* sf = *fileIt;
+    std::string absFile = cmsys::SystemTools::GetRealPath(
+                                                    sf->GetFullPath());
+
+    if (!skipped.insert(absFile).second)
+      {
+      continue;
+      }
+    uiFileFiles += sep;
+    uiFileFiles += absFile;
+    uiFileOptions += sep;
+    std::string opts = sf->GetProperty("AUTOUIC_OPTIONS");
+    cmSystemTools::ReplaceString(opts, ";", "@list_sep@");
+    uiFileOptions += opts;
+    sep = ";";
+    }
+
+  makefile->AddDefinition("_qt_uic_options_files",
+              cmOutputConverter::EscapeForCMake(uiFileFiles).c_str());
+  makefile->AddDefinition("_qt_uic_options_options",
+            cmOutputConverter::EscapeForCMake(uiFileOptions).c_str());
+
+  std::string targetName = target->GetName();
+  if (strcmp(qtVersion, "5") == 0)
+    {
+    cmTarget *qt5Uic = makefile->FindTargetToUse("Qt5::uic");
+    if (!qt5Uic)
+      {
+      // Project does not use Qt5Widgets, but has AUTOUIC ON anyway
+      }
+    else
+      {
+      makefile->AddDefinition("_qt_uic_executable",
+                              qt5Uic->ImportedGetLocation(""));
+      }
+    }
+  else if (strcmp(qtVersion, "4") == 0)
+    {
+    cmTarget *qt4Uic = makefile->FindTargetToUse("Qt4::uic");
+    if (!qt4Uic)
+      {
+      cmSystemTools::Error("Qt4::uic target not found ",
+                          targetName.c_str());
+      return;
+      }
+    makefile->AddDefinition("_qt_uic_executable",
+                            qt4Uic->ImportedGetLocation(""));
+    }
+  else
+    {
+    cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and "
+                        "Qt 5 ", targetName.c_str());
+    }
+}
+
+void cmQtAutoGeneratorInitializer::MergeRccOptions(
+                         std::vector<std::string> &opts,
+                         const std::vector<std::string> &fileOpts,
+                         bool isQt5)
+{
+  static const char* valueOptions[] = {
+    "name",
+    "root",
+    "compress",
+    "threshold"
+  };
+  std::vector<std::string> extraOpts;
+  for(std::vector<std::string>::const_iterator it = fileOpts.begin();
+      it != fileOpts.end(); ++it)
+    {
+    std::vector<std::string>::iterator existingIt
+                                  = std::find(opts.begin(), opts.end(), *it);
+    if (existingIt != opts.end())
+      {
+      const char *o = it->c_str();
+      if (*o == '-')
+        {
+        ++o;
+        }
+      if (isQt5 && *o == '-')
+        {
+        ++o;
+        }
+      if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions),
+                  cmStrCmp(*it)) != cmArrayEnd(valueOptions))
+        {
+        assert(existingIt + 1 != opts.end());
+        *(existingIt + 1) = *(it + 1);
+        ++it;
+        }
+      }
+    else
+      {
+      extraOpts.push_back(*it);
+      }
+    }
+  opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
+}
+
+void cmQtAutoGeneratorInitializer::SetupAutoRccTarget(cmTarget const* target)
+{
+  std::string _rcc_files;
+  const char* sepRccFiles = "";
+  cmMakefile *makefile = target->GetMakefile();
+
+  std::vector<cmSourceFile*> srcFiles;
+  cmGeneratorTarget *gtgt = target->GetMakefile()
+                                  ->GetGlobalGenerator()
+                                  ->GetGeneratorTarget(target);
+  gtgt->GetConfigCommonSourceFiles(srcFiles);
+
+  std::string qrcInputs;
+  const char* qrcInputsSep = "";
+
+  std::string rccFileFiles;
+  std::string rccFileOptions;
+  const char *optionSep = "";
+
+  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+
+  std::vector<std::string> rccOptions;
+  if (const char* opts = target->GetProperty("AUTORCC_OPTIONS"))
+    {
+    cmSystemTools::ExpandListArgument(opts, rccOptions);
+    }
+  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
+  if (qtMajorVersion == "")
+    {
+    qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
+    }
+
+  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
+      fileIt != srcFiles.end();
+      ++fileIt)
+    {
+    cmSourceFile* sf = *fileIt;
+    std::string ext = sf->GetExtension();
+    if (ext == "qrc")
+      {
+      std::string absFile = cmsys::SystemTools::GetRealPath(
+                                                  sf->GetFullPath());
+      bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));
+
+      if (!skip)
+        {
+        _rcc_files += sepRccFiles;
+        _rcc_files += absFile;
+        sepRccFiles = ";";
+
+        if (const char *prop = sf->GetProperty("AUTORCC_OPTIONS"))
+          {
+          std::vector<std::string> optsVec;
+          cmSystemTools::ExpandListArgument(prop, optsVec);
+          cmQtAutoGeneratorInitializer::MergeRccOptions(rccOptions, optsVec,
+                                strcmp(qtVersion, "5") == 0);
+          }
+
+        if (!rccOptions.empty())
+          {
+          rccFileFiles += optionSep;
+          rccFileFiles += absFile;
+          rccFileOptions += optionSep;
+          }
+        const char *listSep = "";
+        for(std::vector<std::string>::const_iterator it = rccOptions.begin();
+            it != rccOptions.end();
+            ++it)
+          {
+          rccFileOptions += listSep;
+          rccFileOptions += *it;
+          listSep = "@list_sep@";
+          }
+        optionSep = ";";
+
+        std::vector<std::string> depends;
+
+        std::string entriesList;
+        if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))
+          {
+          if (qtMajorVersion == "5")
+            {
+            entriesList = cmQtAutoGeneratorInitializer::ListQt5RccInputs(sf,
+                                                               target,
+                                                               depends);
+            }
+          else
+            {
+            entriesList =
+                cmQtAutoGeneratorInitializer::ListQt4RccInputs(sf, depends);
+            }
+          if (entriesList.empty())
+            {
+            return;
+            }
+          }
+        qrcInputs += qrcInputsSep;
+        qrcInputs += entriesList;
+        qrcInputsSep = ";";
+        }
+      }
+    }
+  makefile->AddDefinition("_qt_rcc_inputs_" + target->GetName(),
+                      cmOutputConverter::EscapeForCMake(qrcInputs).c_str());
+
+  makefile->AddDefinition("_rcc_files",
+          cmOutputConverter::EscapeForCMake(_rcc_files).c_str());
+
+  makefile->AddDefinition("_qt_rcc_options_files",
+              cmOutputConverter::EscapeForCMake(rccFileFiles).c_str());
+  makefile->AddDefinition("_qt_rcc_options_options",
+            cmOutputConverter::EscapeForCMake(rccFileOptions).c_str());
+
+  makefile->AddDefinition("_qt_rcc_executable",
+              cmQtAutoGeneratorInitializer::GetRccExecutable(target).c_str());
+}
+
+std::string cmQtAutoGeneratorInitializer::GetRccExecutable(
+    cmTarget const* target)
+{
+  cmGeneratorTarget *gtgt = target->GetMakefile()
+                                  ->GetGlobalGenerator()
+                                  ->GetGeneratorTarget(target);
+  cmMakefile *makefile = target->GetMakefile();
+  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+  if (!qtVersion)
+    {
+    qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
+    if (!qtVersion)
+      {
+      qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
+      }
+    if (const char *targetQtVersion =
+        gtgt->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
+      {
+      qtVersion = targetQtVersion;
+      }
+    }
+
+  std::string targetName = target->GetName();
+  if (strcmp(qtVersion, "5") == 0)
+    {
+    cmTarget *qt5Rcc = makefile->FindTargetToUse("Qt5::rcc");
+    if (!qt5Rcc)
+      {
+      cmSystemTools::Error("Qt5::rcc target not found ",
+                          targetName.c_str());
+      return std::string();
+      }
+    return qt5Rcc->ImportedGetLocation("");
+    }
+  else if (strcmp(qtVersion, "4") == 0)
+    {
+    cmTarget *qt4Rcc = makefile->FindTargetToUse("Qt4::rcc");
+    if (!qt4Rcc)
+      {
+      cmSystemTools::Error("Qt4::rcc target not found ",
+                          targetName.c_str());
+      return std::string();
+      }
+    return qt4Rcc->ImportedGetLocation("");
+    }
+
+  cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "
+                      "Qt 5 ", targetName.c_str());
+  return std::string();
+}
diff --git a/Source/cmQtAutoGeneratorInitializer.h b/Source/cmQtAutoGeneratorInitializer.h
new file mode 100644
index 0000000..c22f172
--- /dev/null
+++ b/Source/cmQtAutoGeneratorInitializer.h
@@ -0,0 +1,67 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2004-2011 Kitware, Inc.
+  Copyright 2011 Alexander Neundorf (neundorf at kde.org)
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+
+#ifndef cmQtAutoGeneratorInitializer_h
+#define cmQtAutoGeneratorInitializer_h
+
+#include "cmStandardIncludes.h"
+
+#include <string>
+#include <vector>
+#include <map>
+
+class cmSourceFile;
+class cmTarget;
+class cmLocalGenerator;
+
+class cmQtAutoGeneratorInitializer
+{
+public:
+  static void InitializeAutogenSources(cmTarget* target);
+  static void InitializeAutogenTarget(cmLocalGenerator* lg, cmTarget* target);
+  static void SetupAutoGenerateTarget(cmTarget const* target);
+
+  static std::string GetAutogenTargetName(cmTarget const* target);
+  static std::string GetAutogenTargetDir(cmTarget const* target);
+
+private:
+  static void SetupSourceFiles(cmTarget const* target,
+                        std::vector<std::string>& skipMoc,
+                        std::vector<std::string>& mocSources,
+                        std::vector<std::string>& mocHeaders,
+                        std::vector<std::string>& skipUic);
+
+  static void SetupAutoMocTarget(cmTarget const* target,
+                          const std::string &autogenTargetName,
+                          const std::vector<std::string>& skipMoc,
+                          const std::vector<std::string>& mocHeaders,
+                          std::map<std::string, std::string> &configIncludes,
+                          std::map<std::string, std::string> &configDefines);
+  static void SetupAutoUicTarget(cmTarget const* target,
+                        const std::vector<std::string>& skipUic,
+                        std::map<std::string, std::string> &configUicOptions);
+  static void SetupAutoRccTarget(cmTarget const* target);
+
+  static void MergeRccOptions(std::vector<std::string> &opts,
+                       const std::vector<std::string> &fileOpts, bool isQt5);
+
+  static std::string GetRccExecutable(cmTarget const* target);
+
+  static std::string ListQt5RccInputs(cmSourceFile* sf, cmTarget const* target,
+                               std::vector<std::string>& depends);
+
+  static std::string ListQt4RccInputs(cmSourceFile* sf,
+                               std::vector<std::string>& depends);
+};
+
+#endif
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index cbb06cd..bbeb3dc 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -12,21 +12,15 @@
 ============================================================================*/
 
 #include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
 #include "cmMakefile.h"
-#include "cmSourceFile.h"
 #include "cmSystemTools.h"
 #include "cmState.h"
 #include "cmAlgorithms.h"
 
-#if defined(_WIN32) && !defined(__CYGWIN__)
-# include "cmGlobalVisualStudioGenerator.h"
-#endif
-
 #include <sys/stat.h>
 
 #include <cmsys/Terminal.h>
-#include <cmsys/ios/sstream>
 #include <cmsys/FStream.hxx>
 #include <assert.h>
 
@@ -37,7 +31,6 @@
 
 #include "cmQtAutoGenerators.h"
 
-
 static bool requiresMocing(const std::string& text, std::string &macroName)
 {
   // this simple check is much much faster than the regexp
@@ -106,28 +99,6 @@ static std::string extractSubDir(const std::string& absPath,
   return subDir;
 }
 
-
-static void copyTargetProperty(cmTarget* destinationTarget,
-                               cmTarget* sourceTarget,
-                               const std::string& propertyName)
-{
-  const char* propertyValue = sourceTarget->GetProperty(propertyName);
-  if (propertyValue)
-    {
-    destinationTarget->SetProperty(propertyName, propertyValue);
-    }
-}
-
-
-static std::string ReadAll(const std::string& filename)
-{
-  cmsys::ifstream file(filename.c_str());
-  cmsys_ios::stringstream stream;
-  stream << file.rdbuf();
-  file.close();
-  return stream.str();
-}
-
 cmQtAutoGenerators::cmQtAutoGenerators()
 :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
 ,ColorOutput(true)
@@ -152,696 +123,6 @@ cmQtAutoGenerators::cmQtAutoGenerators()
     }
 }
 
-static std::string getAutogenTargetName(cmTarget const* target)
-{
-  std::string autogenTargetName = target->GetName();
-  autogenTargetName += "_automoc";
-  return autogenTargetName;
-}
-
-static std::string getAutogenTargetDir(cmTarget const* target)
-{
-  cmMakefile* makefile = target->GetMakefile();
-  std::string targetDir = makefile->GetCurrentBinaryDirectory();
-  targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();
-  targetDir += "/";
-  targetDir += getAutogenTargetName(target);
-  targetDir += ".dir/";
-  return targetDir;
-}
-
-static std::string cmQtAutoGeneratorsStripCR(std::string const& line)
-{
-  // Strip CR characters rcc may have printed (possibly more than one!).
-  std::string::size_type cr = line.find('\r');
-  if (cr != line.npos)
-    {
-    return line.substr(0, cr);
-    }
-  return line;
-}
-
-std::string cmQtAutoGenerators::ListQt5RccInputs(cmSourceFile* sf,
-                                            cmTarget const* target,
-                                            std::vector<std::string>& depends)
-{
-  std::string rccCommand = this->GetRccExecutable(target);
-  std::vector<std::string> qrcEntries;
-
-  std::vector<std::string> command;
-  command.push_back(rccCommand);
-  command.push_back("--list");
-
-  std::string absFile = cmsys::SystemTools::GetRealPath(
-                                              sf->GetFullPath());
-
-  command.push_back(absFile);
-
-  std::string rccStdOut;
-  std::string rccStdErr;
-  int retVal = 0;
-  bool result = cmSystemTools::RunSingleCommand(
-    command, &rccStdOut, &rccStdErr,
-    &retVal, 0, cmSystemTools::OUTPUT_NONE);
-  if (!result || retVal)
-    {
-    std::cerr << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath()
-              << " failed:\n" << rccStdOut << "\n" << rccStdErr << std::endl;
-    return std::string();
-    }
-
-  {
-  std::istringstream ostr(rccStdOut);
-  std::string oline;
-  while(std::getline(ostr, oline))
-    {
-    oline = cmQtAutoGeneratorsStripCR(oline);
-    if(!oline.empty())
-      {
-      qrcEntries.push_back(oline);
-      }
-    }
-  }
-
-  {
-  std::istringstream estr(rccStdErr);
-  std::string eline;
-  while(std::getline(estr, eline))
-    {
-    eline = cmQtAutoGeneratorsStripCR(eline);
-    if (cmHasLiteralPrefix(eline, "RCC: Error in"))
-      {
-      static std::string searchString = "Cannot find file '";
-
-      std::string::size_type pos = eline.find(searchString);
-      if (pos == std::string::npos)
-        {
-        std::cerr << "AUTOGEN: error: Rcc lists unparsable output "
-                  << eline << std::endl;
-        return std::string();
-        }
-      pos += searchString.length();
-      std::string::size_type sz = eline.size() - pos - 1;
-      qrcEntries.push_back(eline.substr(pos, sz));
-      }
-    }
-  }
-
-  depends.insert(depends.end(), qrcEntries.begin(), qrcEntries.end());
-  return cmJoin(qrcEntries, "@list_sep@");
-}
-
-std::string cmQtAutoGenerators::ListQt4RccInputs(cmSourceFile* sf,
-                                            std::vector<std::string>& depends)
-{
-  const std::string qrcContents = ReadAll(sf->GetFullPath());
-
-  cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
-
-  std::string entriesList;
-  const char* sep = "";
-
-  size_t offset = 0;
-  while (fileMatchRegex.find(qrcContents.c_str() + offset))
-    {
-    std::string qrcEntry = fileMatchRegex.match(1);
-
-    offset += qrcEntry.size();
-
-    cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
-    fileReplaceRegex.find(qrcEntry);
-    std::string tag = fileReplaceRegex.match(1);
-
-    qrcEntry = qrcEntry.substr(tag.size());
-
-    if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str()))
-      {
-      qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry;
-      }
-
-    entriesList += sep;
-    entriesList += qrcEntry;
-    sep = "@list_sep@";
-    depends.push_back(qrcEntry);
-    }
-  return entriesList;
-}
-
-bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
-{
-  cmMakefile* makefile = target->GetMakefile();
-  // don't do anything if there is no Qt4 or Qt5Core (which contains moc):
-  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
-  if (qtMajorVersion == "")
-    {
-    qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
-    }
-  if (qtMajorVersion != "4" && qtMajorVersion != "5")
-    {
-    return false;
-    }
-
-  if (target->GetPropertyAsBool("AUTOMOC"))
-    {
-    std::string automocTargetName = getAutogenTargetName(target);
-    std::string mocCppFile = makefile->GetCurrentBinaryDirectory();
-    mocCppFile += "/";
-    mocCppFile += automocTargetName;
-    mocCppFile += ".cpp";
-    makefile->GetOrCreateSource(mocCppFile, true);
-    makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
-                            mocCppFile.c_str(), false);
-
-    target->AddSource(mocCppFile);
-    }
-  // create a custom target for running generators at buildtime:
-  std::string autogenTargetName = getAutogenTargetName(target);
-
-  std::string targetDir = getAutogenTargetDir(target);
-
-  cmCustomCommandLine currentLine;
-  currentLine.push_back(cmSystemTools::GetCMakeCommand());
-  currentLine.push_back("-E");
-  currentLine.push_back("cmake_autogen");
-  currentLine.push_back(targetDir);
-  currentLine.push_back("$<CONFIGURATION>");
-
-  cmCustomCommandLines commandLines;
-  commandLines.push_back(currentLine);
-
-  std::string workingDirectory = cmSystemTools::CollapseFullPath(
-                                    "", makefile->GetCurrentBinaryDirectory());
-
-  std::vector<std::string> depends;
-  if (const char *autogenDepends =
-                                target->GetProperty("AUTOGEN_TARGET_DEPENDS"))
-    {
-    cmSystemTools::ExpandListArgument(autogenDepends, depends);
-    }
-  std::vector<std::string> toolNames;
-  if (target->GetPropertyAsBool("AUTOMOC"))
-    {
-    toolNames.push_back("moc");
-    }
-  if (target->GetPropertyAsBool("AUTOUIC"))
-    {
-    toolNames.push_back("uic");
-    }
-  if (target->GetPropertyAsBool("AUTORCC"))
-    {
-    toolNames.push_back("rcc");
-    }
-
-  std::string tools = toolNames[0];
-  toolNames.erase(toolNames.begin());
-  while (toolNames.size() > 1)
-    {
-    tools += ", " + toolNames[0];
-    toolNames.erase(toolNames.begin());
-    }
-  if (toolNames.size() == 1)
-    {
-    tools += " and " + toolNames[0];
-    }
-  std::string autogenComment = "Automatic " + tools + " for target ";
-  autogenComment += target->GetName();
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-  bool usePRE_BUILD = false;
-  cmLocalGenerator* localGen = makefile->GetLocalGenerator();
-  cmGlobalGenerator* gg = localGen->GetGlobalGenerator();
-  if(gg->GetName().find("Visual Studio") != std::string::npos)
-    {
-    cmGlobalVisualStudioGenerator* vsgg =
-      static_cast<cmGlobalVisualStudioGenerator*>(gg);
-    // Under VS >= 7 use a PRE_BUILD event instead of a separate target to
-    // reduce the number of targets loaded into the IDE.
-    // This also works around a VS 11 bug that may skip updating the target:
-    //  https://connect.microsoft.com/VisualStudio/feedback/details/769495
-    usePRE_BUILD = vsgg->GetVersion() >= cmGlobalVisualStudioGenerator::VS7;
-    if(usePRE_BUILD)
-      {
-      for (std::vector<std::string>::iterator it = depends.begin();
-            it != depends.end(); ++it)
-        {
-        if(!makefile->FindTargetToUse(it->c_str()))
-          {
-          usePRE_BUILD = false;
-          break;
-          }
-        }
-      }
-    }
-#endif
-
-  std::vector<std::string> rcc_output;
-  bool const isNinja =
-    makefile->GetGlobalGenerator()->GetName() == "Ninja";
-  if(isNinja
-#if defined(_WIN32) && !defined(__CYGWIN__)
-        || usePRE_BUILD
-#endif
-        )
-    {
-    std::vector<cmSourceFile*> srcFiles;
-    target->GetConfigCommonSourceFiles(srcFiles);
-    for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
-        fileIt != srcFiles.end();
-        ++fileIt)
-      {
-      cmSourceFile* sf = *fileIt;
-      std::string absFile = cmsys::SystemTools::GetRealPath(
-                                                sf->GetFullPath());
-
-      std::string ext = sf->GetExtension();
-
-      if (target->GetPropertyAsBool("AUTORCC"))
-        {
-        if (ext == "qrc"
-            && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))
-          {
-          std::string basename = cmsys::SystemTools::
-                                  GetFilenameWithoutLastExtension(absFile);
-
-          std::string rcc_output_dir = target->GetSupportDirectory();
-          cmSystemTools::MakeDirectory(rcc_output_dir.c_str());
-          std::string rcc_output_file = rcc_output_dir;
-          rcc_output_file += "/qrc_" + basename + ".cpp";
-          rcc_output.push_back(rcc_output_file);
-
-          if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))
-            {
-            if (qtMajorVersion == "5")
-              {
-              this->ListQt5RccInputs(sf, target, depends);
-              }
-            else
-              {
-              this->ListQt4RccInputs(sf, depends);
-              }
-#if defined(_WIN32) && !defined(__CYGWIN__)
-            usePRE_BUILD = false;
-#endif
-            }
-          }
-        }
-      }
-    }
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-  if(usePRE_BUILD)
-    {
-    // Add the pre-build command directly to bypass the OBJECT_LIBRARY
-    // rejection in cmMakefile::AddCustomCommandToTarget because we know
-    // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case.
-    std::vector<std::string> no_output;
-    std::vector<std::string> no_byproducts;
-    cmCustomCommand cc(makefile, no_output, no_byproducts, depends,
-                       commandLines, autogenComment.c_str(),
-                       workingDirectory.c_str());
-    cc.SetEscapeOldStyle(false);
-    cc.SetEscapeAllowMakeVars(true);
-    target->AddPreBuildCommand(cc);
-    }
-  else
-#endif
-    {
-    cmTarget* autogenTarget = 0;
-    if (!rcc_output.empty() && !isNinja)
-      {
-      std::vector<std::string> no_byproducts;
-      makefile->AddCustomCommandToOutput(rcc_output, no_byproducts,
-                                         depends, "",
-                                         commandLines, 0,
-                                         workingDirectory.c_str(),
-                                         false, false);
-
-      cmCustomCommandLines no_commands;
-      autogenTarget = makefile->AddUtilityCommand(
-                          autogenTargetName, true,
-                          workingDirectory.c_str(), rcc_output,
-                          no_commands, false, autogenComment.c_str());
-
-      }
-    else
-      {
-      autogenTarget = makefile->AddUtilityCommand(
-                                autogenTargetName, true,
-                                workingDirectory.c_str(),
-                                /*byproducts=*/rcc_output, depends,
-                                commandLines, false, autogenComment.c_str());
-      }
-
-    // Set target folder
-    const char* autogenFolder = makefile->GetState()
-                                ->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
-    if (!autogenFolder)
-      {
-      autogenFolder = makefile->GetState()
-                                ->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
-      }
-    if (autogenFolder && *autogenFolder)
-      {
-      autogenTarget->SetProperty("FOLDER", autogenFolder);
-      }
-    else
-      {
-      // inherit FOLDER property from target (#13688)
-      copyTargetProperty(autogenTarget, target, "FOLDER");
-      }
-
-    target->AddUtility(autogenTargetName);
-    }
-
-  return true;
-}
-
-static void GetCompileDefinitionsAndDirectories(cmTarget const* target,
-                                                const std::string& config,
-                                                std::string &incs,
-                                                std::string &defs)
-{
-  cmMakefile* makefile = target->GetMakefile();
-  cmLocalGenerator* localGen = makefile->GetLocalGenerator();
-  std::vector<std::string> includeDirs;
-  cmGeneratorTarget *gtgt = localGen->GetGlobalGenerator()
-                                    ->GetGeneratorTarget(target);
-  // Get the include dirs for this target, without stripping the implicit
-  // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667
-  localGen->GetIncludeDirectories(includeDirs, gtgt, "CXX", config, false);
-
-  incs = cmJoin(includeDirs, ";");
-
-  std::set<std::string> defines;
-  localGen->AddCompileDefinitions(defines, target, config, "CXX");
-
-  defs += cmJoin(defines, ";");
-}
-
-void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target)
-{
-  cmMakefile* makefile = target->GetMakefile();
-
-  // forget the variables added here afterwards again:
-  cmMakefile::ScopePushPop varScope(makefile);
-  static_cast<void>(varScope);
-
-  // create a custom target for running generators at buildtime:
-  std::string autogenTargetName = getAutogenTargetName(target);
-
-  makefile->AddDefinition("_moc_target_name",
-          cmLocalGenerator::EscapeForCMake(autogenTargetName).c_str());
-  makefile->AddDefinition("_origin_target_name",
-          cmLocalGenerator::EscapeForCMake(target->GetName()).c_str());
-
-  std::string targetDir = getAutogenTargetDir(target);
-
-  const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
-  if (!qtVersion)
-    {
-    qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
-    }
-  if (const char *targetQtVersion =
-      target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
-    {
-    qtVersion = targetQtVersion;
-    }
-  if (qtVersion)
-    {
-    makefile->AddDefinition("_target_qt_version", qtVersion);
-    }
-
-  std::map<std::string, std::string> configIncludes;
-  std::map<std::string, std::string> configDefines;
-  std::map<std::string, std::string> configUicOptions;
-
-  if (target->GetPropertyAsBool("AUTOMOC")
-      || target->GetPropertyAsBool("AUTOUIC")
-      || target->GetPropertyAsBool("AUTORCC"))
-    {
-    this->SetupSourceFiles(target);
-    }
-  makefile->AddDefinition("_cpp_files",
-          cmLocalGenerator::EscapeForCMake(this->Sources).c_str());
-  if (target->GetPropertyAsBool("AUTOMOC"))
-    {
-    this->SetupAutoMocTarget(target, autogenTargetName,
-                             configIncludes, configDefines);
-    }
-  if (target->GetPropertyAsBool("AUTOUIC"))
-    {
-    this->SetupAutoUicTarget(target, configUicOptions);
-    }
-  if (target->GetPropertyAsBool("AUTORCC"))
-    {
-    this->SetupAutoRccTarget(target);
-    }
-
-  const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT");
-  std::string inputFile = cmakeRoot;
-  inputFile += "/Modules/AutogenInfo.cmake.in";
-  std::string outputFile = targetDir;
-  outputFile += "/AutogenInfo.cmake";
-  makefile->AddDefinition("_qt_rcc_inputs",
-              makefile->GetDefinition("_qt_rcc_inputs_" + target->GetName()));
-  makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),
-                          false, true, false);
-
-  // Ensure we have write permission in case .in was read-only.
-  mode_t perm = 0;
-#if defined(WIN32) && !defined(__CYGWIN__)
-  mode_t mode_write = S_IWRITE;
-#else
-  mode_t mode_write = S_IWUSR;
-#endif
-  cmSystemTools::GetPermissions(outputFile, perm);
-  if (!(perm & mode_write))
-    {
-    cmSystemTools::SetPermissions(outputFile, perm | mode_write);
-    }
-  if (!configDefines.empty()
-      || !configIncludes.empty()
-      || !configUicOptions.empty())
-    {
-    cmsys::ofstream infoFile(outputFile.c_str(), std::ios::app);
-    if ( !infoFile )
-      {
-      std::string error = "Internal CMake error when trying to open file: ";
-      error += outputFile.c_str();
-      error += " for writing.";
-      cmSystemTools::Error(error.c_str());
-      return;
-      }
-    if (!configDefines.empty())
-      {
-      for (std::map<std::string, std::string>::iterator
-            it = configDefines.begin(), end = configDefines.end();
-            it != end; ++it)
-        {
-        infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first <<
-          " " << it->second << ")\n";
-        }
-      }
-    if (!configIncludes.empty())
-      {
-      for (std::map<std::string, std::string>::iterator
-            it = configIncludes.begin(), end = configIncludes.end();
-            it != end; ++it)
-        {
-        infoFile << "set(AM_MOC_INCLUDES_" << it->first <<
-          " " << it->second << ")\n";
-        }
-      }
-    if (!configUicOptions.empty())
-      {
-      for (std::map<std::string, std::string>::iterator
-            it = configUicOptions.begin(), end = configUicOptions.end();
-            it != end; ++it)
-        {
-        infoFile << "set(AM_UIC_TARGET_OPTIONS_" << it->first <<
-          " " << it->second << ")\n";
-        }
-      }
-    }
-}
-
-void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
-{
-  cmMakefile* makefile = target->GetMakefile();
-
-  const char* sepFiles = "";
-  const char* sepHeaders = "";
-
-  std::vector<cmSourceFile*> srcFiles;
-  target->GetConfigCommonSourceFiles(srcFiles);
-
-  const char *skipMocSep = "";
-  const char *skipUicSep = "";
-
-  std::vector<std::string> newRccFiles;
-
-  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
-      fileIt != srcFiles.end();
-      ++fileIt)
-    {
-    cmSourceFile* sf = *fileIt;
-    std::string absFile = cmsys::SystemTools::GetRealPath(
-                                                    sf->GetFullPath());
-    bool skipMoc = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
-    bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));
-
-    if(cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC")))
-      {
-      this->SkipUic += skipUicSep;
-      this->SkipUic += absFile;
-      skipUicSep = ";";
-      }
-
-    std::string ext = sf->GetExtension();
-
-    if (target->GetPropertyAsBool("AUTORCC"))
-      {
-      if (ext == "qrc"
-          && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))
-        {
-        std::string basename = cmsys::SystemTools::
-                                      GetFilenameWithoutLastExtension(absFile);
-
-        std::string rcc_output_dir = target->GetSupportDirectory();
-        cmSystemTools::MakeDirectory(rcc_output_dir.c_str());
-        std::string rcc_output_file = rcc_output_dir;
-        rcc_output_file += "/qrc_" + basename + ".cpp";
-        makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
-                                rcc_output_file.c_str(), false);
-        makefile->GetOrCreateSource(rcc_output_file, true);
-        newRccFiles.push_back(rcc_output_file);
-        }
-      }
-
-    if (!generated)
-      {
-      if (skipMoc)
-        {
-        this->SkipMoc += skipMocSep;
-        this->SkipMoc += absFile;
-        skipMocSep = ";";
-        }
-      else
-        {
-        cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(
-                                                                ext.c_str());
-        if (fileType == cmSystemTools::CXX_FILE_FORMAT)
-          {
-          this->Sources += sepFiles;
-          this->Sources += absFile;
-          sepFiles = ";";
-          }
-        else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)
-          {
-          this->Headers += sepHeaders;
-          this->Headers += absFile;
-          sepHeaders = ";";
-          }
-        }
-      }
-    }
-
-  for(std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();
-      fileIt != newRccFiles.end();
-      ++fileIt)
-    {
-    const_cast<cmTarget*>(target)->AddSource(*fileIt);
-    }
-}
-
-void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
-                          const std::string &autogenTargetName,
-                          std::map<std::string, std::string> &configIncludes,
-                          std::map<std::string, std::string> &configDefines)
-{
-  cmMakefile* makefile = target->GetMakefile();
-
-  const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");
-  std::string _moc_options = (tmp!=0 ? tmp : "");
-  makefile->AddDefinition("_moc_options",
-          cmLocalGenerator::EscapeForCMake(_moc_options).c_str());
-  makefile->AddDefinition("_skip_moc",
-          cmLocalGenerator::EscapeForCMake(this->SkipMoc).c_str());
-  makefile->AddDefinition("_moc_headers",
-          cmLocalGenerator::EscapeForCMake(this->Headers).c_str());
-  bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");
-  makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE");
-
-  std::string _moc_incs;
-  std::string _moc_compile_defs;
-  std::vector<std::string> configs;
-  const std::string& config = makefile->GetConfigurations(configs);
-  GetCompileDefinitionsAndDirectories(target, config,
-                                      _moc_incs, _moc_compile_defs);
-
-  makefile->AddDefinition("_moc_incs",
-          cmLocalGenerator::EscapeForCMake(_moc_incs).c_str());
-  makefile->AddDefinition("_moc_compile_defs",
-          cmLocalGenerator::EscapeForCMake(_moc_compile_defs).c_str());
-
-  for (std::vector<std::string>::const_iterator li = configs.begin();
-       li != configs.end(); ++li)
-    {
-    std::string config_moc_incs;
-    std::string config_moc_compile_defs;
-    GetCompileDefinitionsAndDirectories(target, *li,
-                                        config_moc_incs,
-                                        config_moc_compile_defs);
-    if (config_moc_incs != _moc_incs)
-      {
-      configIncludes[*li] =
-                    cmLocalGenerator::EscapeForCMake(config_moc_incs);
-      if(_moc_incs.empty())
-        {
-        _moc_incs = config_moc_incs;
-        }
-      }
-    if (config_moc_compile_defs != _moc_compile_defs)
-      {
-      configDefines[*li] =
-            cmLocalGenerator::EscapeForCMake(config_moc_compile_defs);
-      if(_moc_compile_defs.empty())
-        {
-        _moc_compile_defs = config_moc_compile_defs;
-        }
-      }
-    }
-
-  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
-  if (strcmp(qtVersion, "5") == 0)
-    {
-    cmTarget *qt5Moc = makefile->FindTargetToUse("Qt5::moc");
-    if (!qt5Moc)
-      {
-      cmSystemTools::Error("Qt5::moc target not found ",
-                          autogenTargetName.c_str());
-      return;
-      }
-    makefile->AddDefinition("_qt_moc_executable", qt5Moc->GetLocation(""));
-    }
-  else if (strcmp(qtVersion, "4") == 0)
-    {
-    cmTarget *qt4Moc = makefile->FindTargetToUse("Qt4::moc");
-    if (!qt4Moc)
-      {
-      cmSystemTools::Error("Qt4::moc target not found ",
-                          autogenTargetName.c_str());
-      return;
-      }
-    makefile->AddDefinition("_qt_moc_executable", qt4Moc->GetLocation(""));
-    }
-  else
-    {
-    cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "
-                        "Qt 5 ", autogenTargetName.c_str());
-    }
-}
-
 void cmQtAutoGenerators::MergeUicOptions(std::vector<std::string> &opts,
                          const std::vector<std::string> &fileOpts,
                          bool isQt5)
@@ -887,322 +168,6 @@ void cmQtAutoGenerators::MergeUicOptions(std::vector<std::string> &opts,
   opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
 }
 
-static void GetUicOpts(cmTarget const* target, const std::string& config,
-                       std::string &optString)
-{
-  std::vector<std::string> opts;
-  target->GetAutoUicOptions(opts, config);
-  optString = cmJoin(opts, ";");
-}
-
-void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
-                          std::map<std::string, std::string> &configUicOptions)
-{
-  cmMakefile *makefile = target->GetMakefile();
-
-  std::set<std::string> skipped;
-  std::vector<std::string> skipVec;
-  cmSystemTools::ExpandListArgument(this->SkipUic, skipVec);
-  skipped.insert(skipVec.begin(), skipVec.end());
-
-  makefile->AddDefinition("_skip_uic",
-          cmLocalGenerator::EscapeForCMake(this->SkipUic).c_str());
-
-  std::vector<cmSourceFile*> uiFilesWithOptions
-                                        = makefile->GetQtUiFilesWithOptions();
-
-  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
-
-  std::string _uic_opts;
-  std::vector<std::string> configs;
-  const std::string& config = makefile->GetConfigurations(configs);
-  GetUicOpts(target, config, _uic_opts);
-
-  if (!_uic_opts.empty())
-    {
-    _uic_opts = cmLocalGenerator::EscapeForCMake(_uic_opts);
-    makefile->AddDefinition("_uic_target_options", _uic_opts.c_str());
-    }
-  for (std::vector<std::string>::const_iterator li = configs.begin();
-       li != configs.end(); ++li)
-    {
-    std::string config_uic_opts;
-    GetUicOpts(target, *li, config_uic_opts);
-    if (config_uic_opts != _uic_opts)
-      {
-      configUicOptions[*li] =
-                    cmLocalGenerator::EscapeForCMake(config_uic_opts);
-      if(_uic_opts.empty())
-        {
-        _uic_opts = config_uic_opts;
-        }
-      }
-    }
-
-  std::string uiFileFiles;
-  std::string uiFileOptions;
-  const char* sep = "";
-
-  for(std::vector<cmSourceFile*>::const_iterator fileIt =
-      uiFilesWithOptions.begin();
-      fileIt != uiFilesWithOptions.end();
-      ++fileIt)
-    {
-    cmSourceFile* sf = *fileIt;
-    std::string absFile = cmsys::SystemTools::GetRealPath(
-                                                    sf->GetFullPath());
-
-    if (!skipped.insert(absFile).second)
-      {
-      continue;
-      }
-    uiFileFiles += sep;
-    uiFileFiles += absFile;
-    uiFileOptions += sep;
-    std::string opts = sf->GetProperty("AUTOUIC_OPTIONS");
-    cmSystemTools::ReplaceString(opts, ";", "@list_sep@");
-    uiFileOptions += opts;
-    sep = ";";
-    }
-
-  makefile->AddDefinition("_qt_uic_options_files",
-              cmLocalGenerator::EscapeForCMake(uiFileFiles).c_str());
-  makefile->AddDefinition("_qt_uic_options_options",
-            cmLocalGenerator::EscapeForCMake(uiFileOptions).c_str());
-
-  std::string targetName = target->GetName();
-  if (strcmp(qtVersion, "5") == 0)
-    {
-    cmTarget *qt5Uic = makefile->FindTargetToUse("Qt5::uic");
-    if (!qt5Uic)
-      {
-      // Project does not use Qt5Widgets, but has AUTOUIC ON anyway
-      }
-    else
-      {
-      makefile->AddDefinition("_qt_uic_executable", qt5Uic->GetLocation(""));
-      }
-    }
-  else if (strcmp(qtVersion, "4") == 0)
-    {
-    cmTarget *qt4Uic = makefile->FindTargetToUse("Qt4::uic");
-    if (!qt4Uic)
-      {
-      cmSystemTools::Error("Qt4::uic target not found ",
-                          targetName.c_str());
-      return;
-      }
-    makefile->AddDefinition("_qt_uic_executable", qt4Uic->GetLocation(""));
-    }
-  else
-    {
-    cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and "
-                        "Qt 5 ", targetName.c_str());
-    }
-}
-
-void cmQtAutoGenerators::MergeRccOptions(std::vector<std::string> &opts,
-                         const std::vector<std::string> &fileOpts,
-                         bool isQt5)
-{
-  static const char* valueOptions[] = {
-    "name",
-    "root",
-    "compress",
-    "threshold"
-  };
-  std::vector<std::string> extraOpts;
-  for(std::vector<std::string>::const_iterator it = fileOpts.begin();
-      it != fileOpts.end(); ++it)
-    {
-    std::vector<std::string>::iterator existingIt
-                                  = std::find(opts.begin(), opts.end(), *it);
-    if (existingIt != opts.end())
-      {
-      const char *o = it->c_str();
-      if (*o == '-')
-        {
-        ++o;
-        }
-      if (isQt5 && *o == '-')
-        {
-        ++o;
-        }
-      if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions),
-                  cmStrCmp(*it)) != cmArrayEnd(valueOptions))
-        {
-        assert(existingIt + 1 != opts.end());
-        *(existingIt + 1) = *(it + 1);
-        ++it;
-        }
-      }
-    else
-      {
-      extraOpts.push_back(*it);
-      }
-    }
-  opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
-}
-
-void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
-{
-  std::string _rcc_files;
-  const char* sepRccFiles = "";
-  cmMakefile *makefile = target->GetMakefile();
-
-  std::vector<cmSourceFile*> srcFiles;
-  target->GetConfigCommonSourceFiles(srcFiles);
-
-  std::string qrcInputs;
-  const char* qrcInputsSep = "";
-
-  std::string rccFileFiles;
-  std::string rccFileOptions;
-  const char *optionSep = "";
-
-  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
-
-  std::vector<std::string> rccOptions;
-  if (const char* opts = target->GetProperty("AUTORCC_OPTIONS"))
-    {
-    cmSystemTools::ExpandListArgument(opts, rccOptions);
-    }
-  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
-  if (qtMajorVersion == "")
-    {
-    qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
-    }
-
-  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
-      fileIt != srcFiles.end();
-      ++fileIt)
-    {
-    cmSourceFile* sf = *fileIt;
-    std::string ext = sf->GetExtension();
-    if (ext == "qrc")
-      {
-      std::string absFile = cmsys::SystemTools::GetRealPath(
-                                                  sf->GetFullPath());
-      bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));
-
-      if (!skip)
-        {
-        _rcc_files += sepRccFiles;
-        _rcc_files += absFile;
-        sepRccFiles = ";";
-
-        if (const char *prop = sf->GetProperty("AUTORCC_OPTIONS"))
-          {
-          std::vector<std::string> optsVec;
-          cmSystemTools::ExpandListArgument(prop, optsVec);
-          this->MergeRccOptions(rccOptions, optsVec,
-                                strcmp(qtVersion, "5") == 0);
-          }
-
-        if (!rccOptions.empty())
-          {
-          rccFileFiles += optionSep;
-          rccFileFiles += absFile;
-          rccFileOptions += optionSep;
-          }
-        const char *listSep = "";
-        for(std::vector<std::string>::const_iterator it = rccOptions.begin();
-            it != rccOptions.end();
-            ++it)
-          {
-          rccFileOptions += listSep;
-          rccFileOptions += *it;
-          listSep = "@list_sep@";
-          }
-        optionSep = ";";
-
-        std::vector<std::string> depends;
-
-        std::string entriesList;
-        if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))
-          {
-          if (qtMajorVersion == "5")
-            {
-            entriesList = this->ListQt5RccInputs(sf, target, depends);
-            }
-          else
-            {
-            entriesList = this->ListQt4RccInputs(sf, depends);
-            }
-          if (entriesList.empty())
-            {
-            return;
-            }
-          }
-        qrcInputs += qrcInputsSep;
-        qrcInputs += entriesList;
-        qrcInputsSep = ";";
-        }
-      }
-    }
-  makefile->AddDefinition("_qt_rcc_inputs_" + target->GetName(),
-                      cmLocalGenerator::EscapeForCMake(qrcInputs).c_str());
-
-  makefile->AddDefinition("_rcc_files",
-          cmLocalGenerator::EscapeForCMake(_rcc_files).c_str());
-
-  makefile->AddDefinition("_qt_rcc_options_files",
-              cmLocalGenerator::EscapeForCMake(rccFileFiles).c_str());
-  makefile->AddDefinition("_qt_rcc_options_options",
-            cmLocalGenerator::EscapeForCMake(rccFileOptions).c_str());
-
-  makefile->AddDefinition("_qt_rcc_executable",
-                          this->GetRccExecutable(target).c_str());
-}
-
-std::string cmQtAutoGenerators::GetRccExecutable(cmTarget const* target)
-{
-  cmMakefile *makefile = target->GetMakefile();
-  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
-  if (!qtVersion)
-    {
-    qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
-    if (!qtVersion)
-      {
-      qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
-      }
-    if (const char *targetQtVersion =
-        target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION",
-                                                        ""))
-      {
-      qtVersion = targetQtVersion;
-      }
-    }
-
-  std::string targetName = target->GetName();
-  if (strcmp(qtVersion, "5") == 0)
-    {
-    cmTarget *qt5Rcc = makefile->FindTargetToUse("Qt5::rcc");
-    if (!qt5Rcc)
-      {
-      cmSystemTools::Error("Qt5::rcc target not found ",
-                          targetName.c_str());
-      return std::string();
-      }
-    return qt5Rcc->GetLocation("");
-    }
-  else if (strcmp(qtVersion, "4") == 0)
-    {
-    cmTarget *qt4Rcc = makefile->FindTargetToUse("Qt4::rcc");
-    if (!qt4Rcc)
-      {
-      cmSystemTools::Error("Qt4::rcc target not found ",
-                          targetName.c_str());
-      return std::string();
-      }
-    return qt4Rcc->GetLocation("");
-    }
-
-  cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "
-                      "Qt 5 ", targetName.c_str());
-  return std::string();
-}
-
 bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
                              const std::string& config)
 {
@@ -1212,24 +177,24 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
   cm.SetHomeDirectory(targetDirectory);
   cmGlobalGenerator gg(&cm);
 
-  cmLocalGenerator* lg = gg.MakeLocalGenerator();
-  lg->GetMakefile()->SetCurrentBinaryDirectory(targetDirectory);
-  lg->GetMakefile()->SetCurrentSourceDirectory(targetDirectory);
-  gg.SetCurrentLocalGenerator(lg);
+  cmState::Snapshot snapshot = cm.GetCurrentSnapshot();
+  cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, snapshot));
+  mf->SetCurrentBinaryDirectory(targetDirectory);
+  mf->SetCurrentSourceDirectory(targetDirectory);
+  gg.SetCurrentMakefile(mf.get());
 
-  this->ReadAutogenInfoFile(lg->GetMakefile(), targetDirectory, config);
-  this->ReadOldMocDefinitionsFile(lg->GetMakefile(), targetDirectory);
+  this->ReadAutogenInfoFile(mf.get(), targetDirectory, config);
+  this->ReadOldMocDefinitionsFile(mf.get(), targetDirectory);
 
   this->Init();
 
   if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5")
     {
-    success = this->RunAutogen(lg->GetMakefile());
+    success = this->RunAutogen(mf.get());
     }
 
   this->WriteOldMocDefinitionsFile(targetDirectory);
 
-  delete lg;
   return success;
 }
 
@@ -1434,7 +399,7 @@ cmQtAutoGenerators::WriteOldMocDefinitionsFile(
   outfile.open(filename.c_str(),
                std::ios::trunc);
   outfile << "set(AM_OLD_COMPILE_SETTINGS "
-              << cmLocalGenerator::EscapeForCMake(
+              << cmOutputConverter::EscapeForCMake(
                  this->CurrentCompileSettingsStr) << ")\n";
 
   outfile.close();
@@ -1527,6 +492,14 @@ void cmQtAutoGenerators::Init()
 
 }
 
+static std::string ReadAll(const std::string& filename)
+{
+  cmsys::ifstream file(filename.c_str());
+  std::stringstream stream;
+  stream << file.rdbuf();
+  file.close();
+  return stream.str();
+}
 
 bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
 {
@@ -1640,7 +613,7 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
     this->GenerateQrc();
     }
 
-  cmsys_ios::stringstream outStream;
+  std::stringstream outStream;
   outStream << "/* This file is autogenerated, do not edit*/\n";
 
   bool automocCppChanged = false;
@@ -2245,7 +1218,8 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& realName,
       {
       std::vector<std::string> fileOpts;
       cmSystemTools::ExpandListArgument(optionIt->second, fileOpts);
-      this->MergeUicOptions(opts, fileOpts, this->QtMajorVersion == "5");
+      cmQtAutoGenerators::MergeUicOptions(opts, fileOpts,
+                                          this->QtMajorVersion == "5");
       }
     command.insert(command.end(), opts.begin(), opts.end());
 
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index f74e3c5..ab7b6ed 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -15,8 +15,10 @@
 #define cmQtAutoGenerators_h
 
 #include <list>
+#include <vector>
+#include <string>
+#include <map>
 
-class cmGlobalGenerator;
 class cmMakefile;
 
 class cmQtAutoGenerators
@@ -25,18 +27,7 @@ public:
   cmQtAutoGenerators();
   bool Run(const std::string& targetDirectory, const std::string& config);
 
-  bool InitializeAutogenTarget(cmTarget* target);
-  void SetupAutoGenerateTarget(cmTarget const* target);
-  void SetupSourceFiles(cmTarget const* target);
-
 private:
-  void SetupAutoMocTarget(cmTarget const* target,
-                          const std::string &autogenTargetName,
-                          std::map<std::string, std::string> &configIncludes,
-                          std::map<std::string, std::string> &configDefines);
-  void SetupAutoUicTarget(cmTarget const* target,
-                        std::map<std::string, std::string> &configUicOptions);
-  void SetupAutoRccTarget(cmTarget const* target);
 
   bool ReadAutogenInfoFile(cmMakefile* makefile,
                            const std::string& targetDirectory,
@@ -82,20 +73,9 @@ private:
   bool EndsWith(const std::string& str, const std::string& with);
   bool StartsWith(const std::string& str, const std::string& with);
 
-  void MergeUicOptions(std::vector<std::string> &opts,
-                       const std::vector<std::string> &fileOpts, bool isQt5);
-
-  void MergeRccOptions(std::vector<std::string> &opts,
+  static void MergeUicOptions(std::vector<std::string> &opts,
                        const std::vector<std::string> &fileOpts, bool isQt5);
 
-  std::string GetRccExecutable(cmTarget const* target);
-
-  std::string ListQt5RccInputs(cmSourceFile* sf, cmTarget const* target,
-                               std::vector<std::string>& depends);
-
-  std::string ListQt4RccInputs(cmSourceFile* sf,
-                               std::vector<std::string>& depends);
-
   bool InputFilesNewerThanQrc(const std::string& qrcFile,
                               const std::string& rccOutput);
 
@@ -105,7 +85,6 @@ private:
   std::string SkipMoc;
   std::string SkipUic;
   std::string Headers;
-  bool IncludeProjectDirsBefore;
   std::string Srcdir;
   std::string Builddir;
   std::string MocExecutable;
@@ -131,6 +110,7 @@ private:
   std::map<std::string, std::string> RccOptions;
   std::map<std::string, std::vector<std::string> > RccInputs;
 
+  bool IncludeProjectDirsBefore;
   bool Verbose;
   bool ColorOutput;
   bool RunMocFailed;
@@ -138,7 +118,6 @@ private:
   bool RunRccFailed;
   bool GenerateAll;
   bool RelaxedMode;
-
 };
 
 #endif
diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h
index 94161f8..410b370 100644
--- a/Source/cmRemoveCommand.h
+++ b/Source/cmRemoveCommand.h
@@ -47,12 +47,6 @@ public:
    */
   virtual std::string GetName() const {return "remove";}
 
-  /** This command is kept for compatibility with older CMake versions. */
-  virtual bool IsDiscouraged() const
-    {
-    return true;
-    }
-
   cmTypeMacro(cmRemoveCommand, cmCommand);
 };
 
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
index 9ab04f1..bc9372f 100644
--- a/Source/cmScriptGenerator.h
+++ b/Source/cmScriptGenerator.h
@@ -54,9 +54,6 @@ public:
   void Generate(std::ostream& os, const std::string& config,
                 std::vector<std::string> const& configurationTypes);
 
-  const std::vector<std::string>& GetConfigurations() const
-    { return this->Configurations; }
-
 protected:
   typedef cmScriptGeneratorIndent Indent;
   virtual void GenerateScript(std::ostream& os);
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index bf9f42c..1d70ad6 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -48,7 +48,7 @@ bool cmSetCommand
       return true;
       }
 
-    // if it will be cleared, then clear it if it isn;t already clear
+    // if it will be cleared, then clear it if it isn't already clear
     if (currValue)
       {
       cmSystemTools::PutEnv(putEnvArg);
@@ -59,7 +59,7 @@ bool cmSetCommand
   // SET (VAR) // Removes the definition of VAR.
   if (args.size() == 1)
     {
-    this->Makefile->RemoveDefinition(args[0]);
+    this->Makefile->RemoveDefinition(variable);
     return true;
     }
   // SET (VAR PARENT_SCOPE) // Removes the definition of VAR
@@ -108,7 +108,7 @@ bool cmSetCommand
     }
 
   // collect any values into a single semi-colon separated value list
-  value = cmJoin(cmRange(args).advance(1).retreat(ignoreLastArgs), ";");
+  value = cmJoin(cmMakeRange(args).advance(1).retreat(ignoreLastArgs), ";");
 
   if (parentScope)
     {
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 31e460f..17ad475 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -205,14 +205,8 @@ bool cmSetPropertyCommand::HandleDirectoryMode()
     // The local generators are associated with collapsed paths.
     dir = cmSystemTools::CollapseFullPath(dir);
 
-    // Lookup the generator.
-    if(cmLocalGenerator* lg =
-       this->Makefile->GetGlobalGenerator()->FindLocalGenerator(dir))
-      {
-      // Use the makefile for the directory found.
-      mf = lg->GetMakefile();
-      }
-    else
+    mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+    if (!mf)
       {
       // Could not find the directory.
       this->SetError
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index e9cfacc..53dc5a8 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -85,8 +85,10 @@ bool cmSetTestsPropertiesCommand
     unsigned int k;
     for (k = 0; k < propertyPairs.size(); k = k + 2)
       {
-      test->SetProperty(propertyPairs[k],
-                        propertyPairs[k+1].c_str());
+      if (!propertyPairs[k].empty())
+        {
+        test->SetProperty(propertyPairs[k], propertyPairs[k+1].c_str());
+        }
       }
     }
   else
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 724ab39..86f0a7a 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -22,7 +22,6 @@ cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name):
   Location(mf, name)
 {
   this->CustomCommand = 0;
-  this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
   this->FindFullPathFailed = false;
   this->IsUiFile = (".ui" ==
           cmSystemTools::GetFilenameLastExtension(this->Location.GetName()));
@@ -299,7 +298,7 @@ bool cmSourceFile::Matches(cmSourceFileLocation const& loc)
 //----------------------------------------------------------------------------
 void cmSourceFile::SetProperty(const std::string& prop, const char* value)
 {
-  this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
+  this->Properties.SetProperty(prop, value);
 
   if (this->IsUiFile)
     {
@@ -315,8 +314,7 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value)
 void cmSourceFile::AppendProperty(const std::string& prop, const char* value,
                                   bool asString)
 {
-  this->Properties.AppendProperty(prop, value, cmProperty::SOURCE_FILE,
-                                  asString);
+  this->Properties.AppendProperty(prop, value, asString);
 }
 
 //----------------------------------------------------------------------------
@@ -362,13 +360,16 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
       }
     }
 
-  bool chain = false;
-  const char *retVal =
-    this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, chain);
-  if (chain)
+  const char *retVal = this->Properties.GetPropertyValue(prop);
+  if (!retVal)
     {
     cmMakefile const* mf = this->Location.GetMakefile();
-    return mf->GetProperty(prop,cmProperty::SOURCE_FILE);
+    const bool chain = mf->GetState()->
+                      IsPropertyChained(prop, cmProperty::SOURCE_FILE);
+    if (chain)
+      {
+      return mf->GetProperty(prop, chain);
+      }
     }
 
   return retVal;
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index f898260..1433b54 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -107,8 +107,9 @@ private:
   std::string Extension;
   std::string Language;
   std::string FullPath;
-  bool FindFullPathFailed;
   std::string ObjectLibrary;
+  std::vector<std::string> Depends;
+  bool FindFullPathFailed;
   bool IsUiFile;
 
   bool FindFullPath(std::string* error);
@@ -116,7 +117,6 @@ private:
   void CheckExtension();
   void CheckLanguage(std::string const& ext);
 
-  std::vector<std::string> Depends;
 
   static const std::string propLANGUAGE;
 };
diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h
index a9796b9..468a589 100644
--- a/Source/cmStandardIncludes.h
+++ b/Source/cmStandardIncludes.h
@@ -33,14 +33,6 @@
 // Provide fixed-size integer types.
 #include <cmIML/INT.h>
 
-// Include stream compatibility layer from KWSys.
-// This is needed to work with large file support
-// on some platforms whose stream operators do not
-// support the large integer types.
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-# include <cmsys/IOStream.hxx>
-#endif
-
 #include <fstream>
 #include <iostream>
 #include <iomanip>
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 042fabe..ce9ff32 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -15,9 +15,73 @@
 #include "cmCacheManager.h"
 #include "cmCommand.h"
 #include "cmAlgorithms.h"
+#include "cmDefinitions.h"
 
 #include <assert.h>
 
+struct cmState::SnapshotDataType
+{
+  cmState::PositionType ScopeParent;
+  cmState::PositionType DirectoryParent;
+  cmLinkedTree<cmState::PolicyStackEntry>::iterator Policies;
+  cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyRoot;
+  cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyScope;
+  cmState::SnapshotType SnapshotType;
+  cmLinkedTree<std::string>::iterator ExecutionListFile;
+  cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator
+                                                          BuildSystemDirectory;
+  cmLinkedTree<cmDefinitions>::iterator Vars;
+  cmLinkedTree<cmDefinitions>::iterator Root;
+  cmLinkedTree<cmDefinitions>::iterator Parent;
+  std::string EntryPointCommand;
+  long EntryPointLine;
+  std::vector<std::string>::size_type IncludeDirectoryPosition;
+  std::vector<std::string>::size_type CompileDefinitionsPosition;
+  std::vector<std::string>::size_type CompileOptionsPosition;
+};
+
+struct cmState::PolicyStackEntry: public cmPolicies::PolicyMap
+{
+  typedef cmPolicies::PolicyMap derived;
+  PolicyStackEntry(bool w = false): derived(), Weak(w) {}
+  PolicyStackEntry(derived const& d, bool w): derived(d), Weak(w) {}
+  PolicyStackEntry(PolicyStackEntry const& r): derived(r), Weak(r.Weak) {}
+  bool Weak;
+};
+
+struct cmState::BuildsystemDirectoryStateType
+{
+  cmState::PositionType DirectoryEnd;
+
+  std::string Location;
+  std::string OutputLocation;
+
+  std::vector<std::string> CurrentSourceDirectoryComponents;
+  std::vector<std::string> CurrentBinaryDirectoryComponents;
+  // The top-most directories for relative path conversion.  Both the
+  // source and destination location of a relative path conversion
+  // must be underneath one of these directories (both under source or
+  // both under binary) in order for the relative path to be evaluated
+  // safely by the build tools.
+  std::string RelativePathTopSource;
+  std::string RelativePathTopBinary;
+
+  std::vector<std::string> IncludeDirectories;
+  std::vector<cmListFileBacktrace> IncludeDirectoryBacktraces;
+
+  std::vector<std::string> CompileDefinitions;
+  std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
+
+  std::vector<std::string> CompileOptions;
+  std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
+
+  std::string ProjectName;
+
+  cmPropertyMap Properties;
+
+  std::vector<cmState::Snapshot> Children;
+};
+
 cmState::cmState(cmake* cm)
   : CMakeInstance(cm),
     IsInTryCompile(false),
@@ -195,34 +259,38 @@ void cmState::RemoveCacheEntryProperty(std::string const& key,
        ->GetCacheIterator(key.c_str()).SetProperty(propertyName, (void*)0);
 }
 
-void cmState::Reset()
+cmState::Snapshot cmState::Reset()
 {
   this->GlobalProperties.clear();
   this->PropertyDefinitions.clear();
 
-  assert(this->Locations.size() > 0);
-  assert(this->OutputLocations.size() > 0);
-  assert(this->ParentPositions.size() > 0);
-  assert(this->CurrentSourceDirectoryComponents.size() > 0);
-  assert(this->CurrentBinaryDirectoryComponents.size() > 0);
-  assert(this->RelativePathTopSource.size() > 0);
-  assert(this->RelativePathTopBinary.size() > 0);
-
-  this->Locations.erase(this->Locations.begin() + 1, this->Locations.end());
-  this->OutputLocations.erase(this->OutputLocations.begin() + 1,
-                              this->OutputLocations.end());
-  this->ParentPositions.erase(this->ParentPositions.begin() + 1,
-                              this->ParentPositions.end());
-  this->CurrentSourceDirectoryComponents.erase(
-        this->CurrentSourceDirectoryComponents.begin() + 1,
-        this->CurrentSourceDirectoryComponents.end());
-  this->CurrentBinaryDirectoryComponents.erase(
-        this->CurrentBinaryDirectoryComponents.begin() + 1,
-        this->CurrentBinaryDirectoryComponents.end());
-  this->RelativePathTopSource.erase(this->RelativePathTopSource.begin() + 1,
-                                    this->RelativePathTopSource.end());
-  this->RelativePathTopBinary.erase(this->RelativePathTopBinary.begin() + 1,
-                                    this->RelativePathTopBinary.end());
+  PositionType pos = this->SnapshotData.Truncate();
+  this->ExecutionListFiles.Truncate();
+
+  {
+  cmLinkedTree<BuildsystemDirectoryStateType>::iterator it =
+      this->BuildsystemDirectory.Truncate();
+  it->IncludeDirectories.clear();
+  it->IncludeDirectoryBacktraces.clear();
+  it->CompileDefinitions.clear();
+  it->CompileDefinitionsBacktraces.clear();
+  it->CompileOptions.clear();
+  it->CompileOptionsBacktraces.clear();
+  it->DirectoryEnd = pos;
+  it->Properties.clear();
+  it->Children.clear();
+  }
+
+  this->PolicyStack.Clear();
+  pos->Policies = this->PolicyStack.Root();
+  pos->PolicyRoot = this->PolicyStack.Root();
+  pos->PolicyScope = this->PolicyStack.Root();
+  assert(pos->Policies.IsValid());
+  assert(pos->PolicyRoot.IsValid());
+  this->VarTree.Clear();
+  pos->Vars = this->VarTree.Extend(this->VarTree.Root());
+  pos->Parent = this->VarTree.Root();
+  pos->Root = this->VarTree.Root();
 
   this->DefineProperty
     ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
@@ -243,6 +311,8 @@ void cmState::Reset()
   this->DefineProperty
     ("RULE_LAUNCH_CUSTOM", cmProperty::TARGET,
      "", "", true);
+
+  return Snapshot(this, pos);
 }
 
 void cmState::DefineProperty(const std::string& name,
@@ -256,27 +326,41 @@ void cmState::DefineProperty(const std::string& name,
                                                   chained);
 }
 
-cmPropertyDefinition *cmState
+cmPropertyDefinition const* cmState
 ::GetPropertyDefinition(const std::string& name,
-                        cmProperty::ScopeType scope)
+                        cmProperty::ScopeType scope) const
 {
   if (this->IsPropertyDefined(name,scope))
     {
-    return &(this->PropertyDefinitions[scope][name]);
+    cmPropertyDefinitionMap const& defs =
+        this->PropertyDefinitions.find(scope)->second;
+    return &defs.find(name)->second;
     }
   return 0;
 }
 
 bool cmState::IsPropertyDefined(const std::string& name,
-                              cmProperty::ScopeType scope)
+                                cmProperty::ScopeType scope) const
 {
-  return this->PropertyDefinitions[scope].IsPropertyDefined(name);
+  std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it
+      = this->PropertyDefinitions.find(scope);
+  if (it == this->PropertyDefinitions.end())
+    {
+    return false;
+    }
+  return it->second.IsPropertyDefined(name);
 }
 
 bool cmState::IsPropertyChained(const std::string& name,
-                              cmProperty::ScopeType scope)
+                                cmProperty::ScopeType scope) const
 {
-  return this->PropertyDefinitions[scope].IsPropertyChained(name);
+  std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it
+      = this->PropertyDefinitions.find(scope);
+  if (it == this->PropertyDefinitions.end())
+    {
+    return false;
+    }
+  return it->second.IsPropertyChained(name);
 }
 
 void cmState::SetLanguageEnabled(std::string const& l)
@@ -435,20 +519,17 @@ void cmState::RemoveUserDefinedCommands()
 
 void cmState::SetGlobalProperty(const std::string& prop, const char* value)
 {
-  this->GlobalProperties.SetProperty(prop, value, cmProperty::GLOBAL);
+  this->GlobalProperties.SetProperty(prop, value);
 }
 
 void cmState::AppendGlobalProperty(const std::string& prop,
                                    const char* value, bool asString)
 {
-  this->GlobalProperties.AppendProperty(prop, value,
-                                        cmProperty::GLOBAL, asString);
+  this->GlobalProperties.AppendProperty(prop, value, asString);
 }
 
 const char *cmState::GetGlobalProperty(const std::string& prop)
 {
-  // watch for special properties
-  std::string output = "";
   if ( prop == "CACHE_VARIABLES" )
     {
     std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
@@ -480,9 +561,7 @@ const char *cmState::GetGlobalProperty(const std::string& prop)
     return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
     }
 #undef STRING_LIST_ELEMENT
-  bool dummy = false;
-  return this->GlobalProperties.GetPropertyValue(prop, cmProperty::GLOBAL,
-                                                 dummy);
+  return this->GlobalProperties.GetPropertyValue(prop);
 }
 
 bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
@@ -590,18 +669,18 @@ std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const
   return this->BinaryDirectoryComponents;
 }
 
-void cmState::Snapshot::ComputeRelativePathTopSource()
+void cmState::Directory::ComputeRelativePathTopSource()
 {
   // Relative path conversion inside the source tree is not used to
   // construct relative paths passed to build tools so it is safe to use
   // even when the source is a network path.
 
-  cmState::Snapshot snapshot = *this;
+  cmState::Snapshot snapshot = this->Snapshot_;
   std::vector<cmState::Snapshot> snapshots;
   snapshots.push_back(snapshot);
   while (true)
     {
-    snapshot = snapshot.GetParent();
+    snapshot = snapshot.GetBuildsystemDirectoryParent();
     if (snapshot.IsValid())
       {
       snapshots.push_back(snapshot);
@@ -612,28 +691,28 @@ void cmState::Snapshot::ComputeRelativePathTopSource()
       }
     }
 
-  std::string result = snapshots.front().GetCurrentSourceDirectory();
+  std::string result = snapshots.front().GetDirectory().GetCurrentSource();
 
   for (std::vector<cmState::Snapshot>::const_iterator it =
        snapshots.begin() + 1; it != snapshots.end(); ++it)
     {
-    std::string currentSource = it->GetCurrentSourceDirectory();
+    std::string currentSource = it->GetDirectory().GetCurrentSource();
     if(cmSystemTools::IsSubDirectory(result, currentSource))
       {
       result = currentSource;
       }
     }
-  this->State->RelativePathTopSource[this->Position] = result;
+  this->DirectoryState->RelativePathTopSource = result;
 }
 
-void cmState::Snapshot::ComputeRelativePathTopBinary()
+void cmState::Directory::ComputeRelativePathTopBinary()
 {
-  cmState::Snapshot snapshot = *this;
+  cmState::Snapshot snapshot = this->Snapshot_;
   std::vector<cmState::Snapshot> snapshots;
   snapshots.push_back(snapshot);
   while (true)
     {
-    snapshot = snapshot.GetParent();
+    snapshot = snapshot.GetBuildsystemDirectoryParent();
     if (snapshot.IsValid())
       {
       snapshots.push_back(snapshot);
@@ -645,12 +724,12 @@ void cmState::Snapshot::ComputeRelativePathTopBinary()
     }
 
   std::string result =
-      snapshots.front().GetCurrentBinaryDirectory();
+      snapshots.front().GetDirectory().GetCurrentBinary();
 
   for (std::vector<cmState::Snapshot>::const_iterator it =
        snapshots.begin() + 1; it != snapshots.end(); ++it)
     {
-    std::string currentBinary = it->GetCurrentBinaryDirectory();
+    std::string currentBinary = it->GetDirectory().GetCurrentBinary();
     if(cmSystemTools::IsSubDirectory(result, currentBinary))
       {
       result = currentBinary;
@@ -662,33 +741,215 @@ void cmState::Snapshot::ComputeRelativePathTopBinary()
   // is a network path.
   if(result.size() < 2 || result.substr(0, 2) != "//")
     {
-    this->State->RelativePathTopBinary[this->Position] = result;
+    this->DirectoryState->RelativePathTopBinary = result;
     }
   else
     {
-    this->State->RelativePathTopBinary[this->Position] = "";
+    this->DirectoryState->RelativePathTopBinary = "";
     }
 }
 
-cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot)
+cmState::Snapshot cmState::CreateBaseSnapshot()
+{
+  PositionType pos = this->SnapshotData.Extend(this->SnapshotData.Root());
+  pos->DirectoryParent = this->SnapshotData.Root();
+  pos->ScopeParent = this->SnapshotData.Root();
+  pos->SnapshotType = BaseType;
+  pos->BuildSystemDirectory =
+      this->BuildsystemDirectory.Extend(this->BuildsystemDirectory.Root());
+  pos->ExecutionListFile =
+      this->ExecutionListFiles.Extend(this->ExecutionListFiles.Root());
+  pos->IncludeDirectoryPosition = 0;
+  pos->CompileDefinitionsPosition = 0;
+  pos->CompileOptionsPosition = 0;
+  pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->Policies = this->PolicyStack.Root();
+  pos->PolicyRoot = this->PolicyStack.Root();
+  pos->PolicyScope = this->PolicyStack.Root();
+  assert(pos->Policies.IsValid());
+  assert(pos->PolicyRoot.IsValid());
+  pos->Vars = this->VarTree.Extend(this->VarTree.Root());
+  assert(pos->Vars.IsValid());
+  pos->Parent = this->VarTree.Root();
+  pos->Root = this->VarTree.Root();
+  return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
+                                    std::string const& entryPointCommand,
+                                    long entryPointLine)
+{
+  assert(originSnapshot.IsValid());
+  PositionType pos = this->SnapshotData.Extend(originSnapshot.Position);
+  pos->EntryPointLine = entryPointLine;
+  pos->EntryPointCommand = entryPointCommand;
+  pos->DirectoryParent = originSnapshot.Position;
+  pos->ScopeParent = originSnapshot.Position;
+  pos->SnapshotType = BuildsystemDirectoryType;
+  pos->BuildSystemDirectory =
+      this->BuildsystemDirectory.Extend(
+        originSnapshot.Position->BuildSystemDirectory);
+  pos->ExecutionListFile =
+      this->ExecutionListFiles.Extend(
+        originSnapshot.Position->ExecutionListFile);
+  pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->Policies = originSnapshot.Position->Policies;
+  pos->PolicyRoot = originSnapshot.Position->Policies;
+  pos->PolicyScope = originSnapshot.Position->Policies;
+  assert(pos->Policies.IsValid());
+  assert(pos->PolicyRoot.IsValid());
+
+  cmLinkedTree<cmDefinitions>::iterator origin =
+      originSnapshot.Position->Vars;
+  pos->Parent = origin;
+  pos->Root = origin;
+  pos->Vars = this->VarTree.Extend(origin);
+  cmState::Snapshot snapshot = cmState::Snapshot(this, pos);
+  originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
+  return snapshot;
+}
+
+cmState::Snapshot
+cmState::CreateFunctionCallSnapshot(cmState::Snapshot originSnapshot,
+                                    std::string const& entryPointCommand,
+                                    long entryPointLine,
+                                    std::string const& fileName)
+{
+  PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+                                               *originSnapshot.Position);
+  pos->ScopeParent = originSnapshot.Position;
+  pos->EntryPointLine = entryPointLine;
+  pos->EntryPointCommand = entryPointCommand;
+  pos->SnapshotType = FunctionCallType;
+  pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+        originSnapshot.Position->ExecutionListFile, fileName);
+  pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
+  assert(originSnapshot.Position->Vars.IsValid());
+  cmLinkedTree<cmDefinitions>::iterator origin =
+      originSnapshot.Position->Vars;
+  pos->Parent = origin;
+  pos->Vars = this->VarTree.Extend(origin);
+  return cmState::Snapshot(this, pos);
+}
+
+
+cmState::Snapshot
+cmState::CreateMacroCallSnapshot(cmState::Snapshot originSnapshot,
+                                    std::string const& entryPointCommand,
+                                    long entryPointLine,
+                                    std::string const& fileName)
 {
-  if (!originSnapshot.IsValid())
-    {
-    originSnapshot.State = this;
-    }
-  PositionType pos = this->ParentPositions.size();
-  this->ParentPositions.push_back(originSnapshot.Position);
-  this->Locations.resize(this->Locations.size() + 1);
-  this->OutputLocations.resize(this->OutputLocations.size() + 1);
-  this->CurrentSourceDirectoryComponents.resize(
-      this->CurrentSourceDirectoryComponents.size() + 1);
-  this->CurrentBinaryDirectoryComponents.resize(
-      this->CurrentBinaryDirectoryComponents.size() + 1);
-  this->RelativePathTopSource.resize(this->RelativePathTopSource.size() + 1);
-  this->RelativePathTopBinary.resize(this->RelativePathTopBinary.size() + 1);
+  PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+                                               *originSnapshot.Position);
+  pos->EntryPointLine = entryPointLine;
+  pos->EntryPointCommand = entryPointCommand;
+  pos->SnapshotType = MacroCallType;
+  pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+        originSnapshot.Position->ExecutionListFile, fileName);
+  assert(originSnapshot.Position->Vars.IsValid());
+  pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
+  return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateCallStackSnapshot(cmState::Snapshot originSnapshot,
+                                 const std::string& entryPointCommand,
+                                 long entryPointLine,
+                                 const std::string& fileName)
+{
+  PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+                                               *originSnapshot.Position);
+  pos->EntryPointLine = entryPointLine;
+  pos->EntryPointCommand = entryPointCommand;
+  pos->SnapshotType = CallStackType;
+  pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+        originSnapshot.Position->ExecutionListFile, fileName);
+  assert(originSnapshot.Position->Vars.IsValid());
+  pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
+  return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateVariableScopeSnapshot(cmState::Snapshot originSnapshot,
+                                     std::string const& entryPointCommand,
+                                     long entryPointLine)
+{
+  PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+                                               *originSnapshot.Position);
+  pos->ScopeParent = originSnapshot.Position;
+  pos->EntryPointLine = entryPointLine;
+  pos->EntryPointCommand = entryPointCommand;
+  pos->SnapshotType = VariableScopeType;
+  assert(originSnapshot.Position->Vars.IsValid());
+
+  cmLinkedTree<cmDefinitions>::iterator origin =
+      originSnapshot.Position->Vars;
+  pos->Parent = origin;
+  pos->Vars = this->VarTree.Extend(origin);
+  assert(pos->Vars.IsValid());
+  return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateInlineListFileSnapshot(cmState::Snapshot originSnapshot,
+                                      const std::string& entryPointCommand,
+                                      long entryPointLine,
+                                      const std::string& fileName)
+{
+  PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+                                               *originSnapshot.Position);
+  pos->EntryPointLine = entryPointLine;
+  pos->EntryPointCommand = entryPointCommand;
+  pos->SnapshotType = InlineListFileType;
+  pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+        originSnapshot.Position->ExecutionListFile, fileName);
+  pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
+  return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreatePolicyScopeSnapshot(cmState::Snapshot originSnapshot)
+{
+  PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+                                               *originSnapshot.Position);
+  pos->SnapshotType = PolicyScopeType;
+  pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
   return cmState::Snapshot(this, pos);
 }
 
+cmState::Snapshot cmState::Pop(cmState::Snapshot originSnapshot)
+{
+  PositionType pos = originSnapshot.Position;
+  PositionType prevPos = pos;
+  ++prevPos;
+  prevPos->IncludeDirectoryPosition =
+      prevPos->BuildSystemDirectory->IncludeDirectories.size();
+  prevPos->CompileDefinitionsPosition =
+      prevPos->BuildSystemDirectory->CompileDefinitions.size();
+  prevPos->CompileOptionsPosition =
+      prevPos->BuildSystemDirectory->CompileOptions.size();
+  prevPos->BuildSystemDirectory->DirectoryEnd = prevPos;
+
+  return Snapshot(this, prevPos);
+}
+
+cmState::Snapshot::Snapshot(cmState* state)
+  : State(state)
+  , Position()
+{
+}
+
+std::vector<cmState::Snapshot> cmState::Snapshot::GetChildren()
+{
+  return this->Position->BuildSystemDirectory->Children;
+}
+
 cmState::Snapshot::Snapshot(cmState* state, PositionType position)
   : State(state),
   Position(position)
@@ -696,94 +957,785 @@ cmState::Snapshot::Snapshot(cmState* state, PositionType position)
 
 }
 
-const char* cmState::Snapshot::GetCurrentSourceDirectory() const
+cmState::SnapshotType cmState::Snapshot::GetType() const
 {
-  return this->State->Locations[this->Position].c_str();
+  return this->Position->SnapshotType;
 }
 
-void cmState::Snapshot::SetCurrentSourceDirectory(std::string const& dir)
+const char* cmState::Directory::GetCurrentSource() const
 {
-  assert(this->State);
-  assert(this->State->Locations.size() > this->Position);
-  this->State->Locations[this->Position] = dir;
-  cmSystemTools::ConvertToUnixSlashes(
-      this->State->Locations[this->Position]);
-  this->State->Locations[this->Position] =
-    cmSystemTools::CollapseFullPath(this->State->Locations[this->Position]);
+  return this->DirectoryState->Location.c_str();
+}
+
+void cmState::Directory::SetCurrentSource(std::string const& dir)
+{
+  std::string& loc = this->DirectoryState->Location;
+  loc = dir;
+  cmSystemTools::ConvertToUnixSlashes(loc);
+  loc = cmSystemTools::CollapseFullPath(loc);
 
   cmSystemTools::SplitPath(
-      this->State->Locations[this->Position],
-      this->State->CurrentSourceDirectoryComponents[this->Position]);
+      loc,
+      this->DirectoryState->CurrentSourceDirectoryComponents);
   this->ComputeRelativePathTopSource();
 }
 
-const char* cmState::Snapshot::GetCurrentBinaryDirectory() const
+const char* cmState::Directory::GetCurrentBinary() const
 {
-  return this->State->OutputLocations[this->Position].c_str();
+  return this->DirectoryState->OutputLocation.c_str();
 }
 
-void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir)
+void cmState::Directory::SetCurrentBinary(std::string const& dir)
 {
-  assert(this->State->OutputLocations.size() > this->Position);
-  this->State->OutputLocations[this->Position] = dir;
-  cmSystemTools::ConvertToUnixSlashes(
-      this->State->OutputLocations[this->Position]);
-  this->State->OutputLocations[this->Position] =
-    cmSystemTools::CollapseFullPath(
-        this->State->OutputLocations[this->Position]);
+  std::string& loc = this->DirectoryState->OutputLocation;
+  loc = dir;
+  cmSystemTools::ConvertToUnixSlashes(loc);
+  loc = cmSystemTools::CollapseFullPath(loc);
 
   cmSystemTools::SplitPath(
-      this->State->OutputLocations[this->Position],
-      this->State->CurrentBinaryDirectoryComponents[this->Position]);
+      loc,
+      this->DirectoryState->CurrentBinaryDirectoryComponents);
   this->ComputeRelativePathTopBinary();
 }
 
+void cmState::Snapshot::SetListFile(const std::string& listfile)
+{
+  *this->Position->ExecutionListFile = listfile;
+}
+
 std::vector<std::string> const&
-cmState::Snapshot::GetCurrentSourceDirectoryComponents()
+cmState::Directory::GetCurrentSourceComponents() const
 {
-  return this->State->CurrentSourceDirectoryComponents[this->Position];
+  return this->DirectoryState->CurrentSourceDirectoryComponents;
 }
 
 std::vector<std::string> const&
-cmState::Snapshot::GetCurrentBinaryDirectoryComponents()
+cmState::Directory::GetCurrentBinaryComponents() const
 {
-  return this->State->CurrentBinaryDirectoryComponents[this->Position];
+  return this->DirectoryState->CurrentBinaryDirectoryComponents;
 }
 
-const char* cmState::Snapshot::GetRelativePathTopSource() const
+const char* cmState::Directory::GetRelativePathTopSource() const
 {
-  return this->State->RelativePathTopSource[this->Position].c_str();
+  return this->DirectoryState->RelativePathTopSource.c_str();
 }
 
-const char* cmState::Snapshot::GetRelativePathTopBinary() const
+const char* cmState::Directory::GetRelativePathTopBinary() const
 {
-  return this->State->RelativePathTopBinary[this->Position].c_str();
+  return this->DirectoryState->RelativePathTopBinary.c_str();
 }
 
-void cmState::Snapshot::SetRelativePathTopSource(const char* dir)
+void cmState::Directory::SetRelativePathTopSource(const char* dir)
 {
-  this->State->RelativePathTopSource[this->Position] = dir;
+  this->DirectoryState->RelativePathTopSource = dir;
 }
 
-void cmState::Snapshot::SetRelativePathTopBinary(const char* dir)
+void cmState::Directory::SetRelativePathTopBinary(const char* dir)
 {
-  this->State->RelativePathTopBinary[this->Position] = dir;
+  this->DirectoryState->RelativePathTopBinary = dir;
+}
+
+std::string cmState::Snapshot::GetExecutionListFile() const
+{
+  return *this->Position->ExecutionListFile;
+}
+
+std::string cmState::Snapshot::GetEntryPointCommand() const
+{
+  return this->Position->EntryPointCommand;
+}
+
+long cmState::Snapshot::GetEntryPointLine() const
+{
+  return this->Position->EntryPointLine;
 }
 
 bool cmState::Snapshot::IsValid() const
 {
-  return this->State ? true : false;
+  return this->State && this->Position.IsValid()
+      ? this->Position != this->State->SnapshotData.Root()
+      : false;
 }
 
-cmState::Snapshot cmState::Snapshot::GetParent() const
+cmState::Snapshot cmState::Snapshot::GetBuildsystemDirectoryParent() const
 {
   Snapshot snapshot;
-  if (!this->State || this->Position == 0)
+  if (!this->State || this->Position == this->State->SnapshotData.Root())
     {
     return snapshot;
     }
-  PositionType parentPos = this->State->ParentPositions[this->Position];
-  snapshot = Snapshot(this->State, parentPos);
+  PositionType parentPos = this->Position->DirectoryParent;
+  if (parentPos != this->State->SnapshotData.Root())
+    {
+    snapshot = Snapshot(this->State,
+                        parentPos->BuildSystemDirectory->DirectoryEnd);
+    }
 
   return snapshot;
 }
+
+cmState::Snapshot cmState::Snapshot::GetCallStackParent() const
+{
+  assert(this->State);
+  assert(this->Position != this->State->SnapshotData.Root());
+
+  Snapshot snapshot;
+  PositionType parentPos = this->Position;
+  while(parentPos->SnapshotType == cmState::PolicyScopeType)
+    {
+    ++parentPos;
+    }
+  if (parentPos->SnapshotType == cmState::BuildsystemDirectoryType
+      || parentPos->SnapshotType == cmState::BaseType)
+    {
+    return snapshot;
+    }
+
+  ++parentPos;
+  while(parentPos->SnapshotType == cmState::PolicyScopeType)
+    {
+    ++parentPos;
+    }
+
+  if (parentPos == this->State->SnapshotData.Root())
+    {
+    return snapshot;
+    }
+
+  snapshot = Snapshot(this->State, parentPos);
+  return snapshot;
+}
+
+void cmState::Snapshot::PushPolicy(cmPolicies::PolicyMap entry, bool weak)
+{
+  PositionType pos = this->Position;
+  pos->Policies =
+      this->State->PolicyStack.Extend(pos->Policies,
+                                      PolicyStackEntry(entry, weak));
+}
+
+bool cmState::Snapshot::PopPolicy()
+{
+  PositionType pos = this->Position;
+  if (pos->Policies == pos->PolicyScope)
+    {
+    return false;
+    }
+  ++pos->Policies;
+  return true;
+}
+
+bool cmState::Snapshot::CanPopPolicyScope()
+{
+  return this->Position->Policies == this->Position->PolicyScope;
+}
+
+void cmState::Snapshot::SetPolicy(cmPolicies::PolicyID id,
+                                  cmPolicies::PolicyStatus status)
+{
+  // Update the policy stack from the top to the top-most strong entry.
+  bool previous_was_weak = true;
+  for(cmLinkedTree<PolicyStackEntry>::iterator psi = this->Position->Policies;
+      previous_was_weak && psi != this->Position->PolicyRoot; ++psi)
+    {
+    psi->Set(id, status);
+    previous_was_weak = psi->Weak;
+    }
+}
+
+cmPolicies::PolicyStatus
+cmState::Snapshot::GetPolicy(cmPolicies::PolicyID id) const
+{
+  cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id);
+
+  if(status == cmPolicies::REQUIRED_ALWAYS ||
+     status == cmPolicies::REQUIRED_IF_USED)
+    {
+    return status;
+    }
+
+  cmLinkedTree<BuildsystemDirectoryStateType>::iterator dir =
+      this->Position->BuildSystemDirectory;
+
+  while (true)
+    {
+    assert(dir.IsValid());
+    cmLinkedTree<PolicyStackEntry>::iterator leaf =
+        dir->DirectoryEnd->Policies;
+    cmLinkedTree<PolicyStackEntry>::iterator root =
+        dir->DirectoryEnd->PolicyRoot;
+    for( ; leaf != root; ++leaf)
+      {
+      if(leaf->IsDefined(id))
+        {
+        status = leaf->Get(id);
+        return status;
+        }
+      }
+    cmState::PositionType e = dir->DirectoryEnd;
+    cmState::PositionType p = e->DirectoryParent;
+    if (p == this->State->SnapshotData.Root())
+      {
+      break;
+      }
+    dir = p->BuildSystemDirectory;
+    }
+  return status;
+}
+
+bool cmState::Snapshot::HasDefinedPolicyCMP0011()
+{
+  return !this->Position->Policies->IsEmpty();
+}
+
+const char* cmState::Snapshot::GetDefinition(std::string const& name) const
+{
+  assert(this->Position->Vars.IsValid());
+  return cmDefinitions::Get(name, this->Position->Vars,
+                    this->Position->Root);
+}
+
+bool cmState::Snapshot::IsInitialized(std::string const& name) const
+{
+  return cmDefinitions::HasKey(name, this->Position->Vars,
+                               this->Position->Root);
+}
+
+void cmState::Snapshot::SetDefinition(std::string const& name,
+                                      std::string const& value)
+{
+  this->Position->Vars->Set(name, value.c_str());
+}
+
+void cmState::Snapshot::RemoveDefinition(std::string const& name)
+{
+  this->Position->Vars->Set(name, 0);
+}
+
+std::vector<std::string> cmState::Snapshot::UnusedKeys() const
+{
+  return this->Position->Vars->UnusedKeys();
+}
+
+std::vector<std::string> cmState::Snapshot::ClosureKeys() const
+{
+  return cmDefinitions::ClosureKeys(this->Position->Vars,
+                                    this->Position->Root);
+}
+
+bool cmState::Snapshot::RaiseScope(std::string const& var, const char* varDef)
+{
+  if(this->Position->ScopeParent == this->Position->DirectoryParent)
+    {
+    Snapshot parentDir = this->GetBuildsystemDirectoryParent();
+    if(!parentDir.IsValid())
+      {
+      return false;
+      }
+    // Update the definition in the parent directory top scope.  This
+    // directory's scope was initialized by the closure of the parent
+    // scope, so we do not need to localize the definition first.
+    if (varDef)
+      {
+      parentDir.SetDefinition(var, varDef);
+      }
+    else
+      {
+      parentDir.RemoveDefinition(var);
+      }
+    return true;
+    }
+  // First localize the definition in the current scope.
+  cmDefinitions::Raise(var, this->Position->Vars,
+                       this->Position->Root);
+
+  // Now update the definition in the parent scope.
+  this->Position->Parent->Set(var, varDef);
+  return true;
+}
+
+static const std::string cmPropertySentinal = std::string();
+
+template<typename T, typename U, typename V>
+void InitializeContentFromParent(T& parentContent,
+                          T& thisContent,
+                          U& parentBacktraces,
+                          U& thisBacktraces,
+                          V& contentEndPosition)
+{
+  std::vector<std::string>::const_iterator parentBegin =
+      parentContent.begin();
+  std::vector<std::string>::const_iterator parentEnd =
+      parentContent.end();
+
+  std::vector<std::string>::const_reverse_iterator parentRbegin =
+      cmMakeReverseIterator(parentEnd);
+  std::vector<std::string>::const_reverse_iterator parentRend =
+      parentContent.rend();
+  parentRbegin = std::find(parentRbegin, parentRend, cmPropertySentinal);
+  std::vector<std::string>::const_iterator parentIt = parentRbegin.base();
+
+  thisContent = std::vector<std::string>(parentIt, parentEnd);
+
+  std::vector<cmListFileBacktrace>::const_iterator btIt =
+      parentBacktraces.begin() + std::distance(parentBegin, parentIt);
+  std::vector<cmListFileBacktrace>::const_iterator btEnd =
+      parentBacktraces.end();
+
+  thisBacktraces = std::vector<cmListFileBacktrace>(btIt, btEnd);
+
+  contentEndPosition = thisContent.size();
+}
+
+void cmState::Snapshot::InitializeFromParent()
+{
+  PositionType parent = this->Position->DirectoryParent;
+  assert(this->Position->Vars.IsValid());
+  assert(parent->Vars.IsValid());
+
+  *this->Position->Vars =
+      cmDefinitions::MakeClosure(parent->Vars, parent->Root);
+
+  InitializeContentFromParent(parent->BuildSystemDirectory->IncludeDirectories,
+              this->Position->BuildSystemDirectory->IncludeDirectories,
+              parent->BuildSystemDirectory->IncludeDirectoryBacktraces,
+              this->Position->BuildSystemDirectory->IncludeDirectoryBacktraces,
+              this->Position->IncludeDirectoryPosition);
+
+  InitializeContentFromParent(parent->BuildSystemDirectory->CompileDefinitions,
+            this->Position->BuildSystemDirectory->CompileDefinitions,
+            parent->BuildSystemDirectory->CompileDefinitionsBacktraces,
+            this->Position->BuildSystemDirectory->CompileDefinitionsBacktraces,
+            this->Position->CompileDefinitionsPosition);
+
+  InitializeContentFromParent(parent->BuildSystemDirectory->CompileOptions,
+                this->Position->BuildSystemDirectory->CompileOptions,
+                parent->BuildSystemDirectory->CompileOptionsBacktraces,
+                this->Position->BuildSystemDirectory->CompileOptionsBacktraces,
+                this->Position->CompileOptionsPosition);
+}
+
+cmState* cmState::Snapshot::GetState() const
+{
+  return this->State;
+}
+
+cmState::Directory cmState::Snapshot::GetDirectory() const
+{
+  return Directory(this->Position->BuildSystemDirectory, *this);
+}
+
+void cmState::Snapshot::SetProjectName(const std::string& name)
+{
+  this->Position->BuildSystemDirectory->ProjectName = name;
+}
+
+std::string cmState::Snapshot::GetProjectName() const
+{
+  return this->Position->BuildSystemDirectory->ProjectName;
+}
+
+cmState::Directory::Directory(
+    cmLinkedTree<BuildsystemDirectoryStateType>::iterator iter,
+    const cmState::Snapshot& snapshot)
+  : DirectoryState(iter), Snapshot_(snapshot)
+{
+
+}
+
+template <typename T, typename U>
+cmStringRange GetPropertyContent(T const& content, U contentEndPosition)
+{
+  std::vector<std::string>::const_iterator end =
+      content.begin() + contentEndPosition;
+
+  std::vector<std::string>::const_reverse_iterator rbegin =
+      cmMakeReverseIterator(end);
+  rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
+
+  return cmMakeRange(rbegin.base(), end);
+}
+
+template <typename T, typename U, typename V>
+cmBacktraceRange GetPropertyBacktraces(T const& content,
+                                    U const& backtraces,
+                                    V contentEndPosition)
+{
+  std::vector<std::string>::const_iterator entryEnd =
+      content.begin() + contentEndPosition;
+
+  std::vector<std::string>::const_reverse_iterator rbegin =
+      cmMakeReverseIterator(entryEnd);
+  rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
+
+  std::vector<cmListFileBacktrace>::const_iterator it =
+      backtraces.begin() + std::distance(content.begin(), rbegin.base());
+
+  std::vector<cmListFileBacktrace>::const_iterator end = backtraces.end();
+  return cmMakeRange(it, end);
+}
+
+template <typename T, typename U, typename V>
+void AppendEntry(T& content, U& backtraces, V& endContentPosition,
+    const std::string& value, const cmListFileBacktrace& lfbt)
+{
+  if (value.empty())
+    {
+    return;
+    }
+
+  assert(endContentPosition == content.size());
+
+  content.push_back(value);
+  backtraces.push_back(lfbt);
+
+  endContentPosition = content.size();
+}
+
+template <typename T, typename U, typename V>
+void SetContent(T& content, U& backtraces, V& endContentPosition,
+                const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+  assert(endContentPosition == content.size());
+
+  content.resize(content.size() + 2);
+  backtraces.resize(backtraces.size() + 2);
+
+  content.back() = vec;
+  backtraces.back() = lfbt;
+
+  endContentPosition = content.size();
+}
+
+template <typename T, typename U, typename V>
+void ClearContent(T& content, U& backtraces, V& endContentPosition)
+{
+  assert(endContentPosition == content.size());
+
+  content.resize(content.size() + 1);
+  backtraces.resize(backtraces.size() + 1);
+
+  endContentPosition = content.size();
+}
+
+cmStringRange
+cmState::Directory::GetIncludeDirectoriesEntries() const
+{
+  return GetPropertyContent(this->DirectoryState->IncludeDirectories,
+                       this->Snapshot_.Position->IncludeDirectoryPosition);
+}
+
+cmBacktraceRange
+cmState::Directory::GetIncludeDirectoriesEntryBacktraces() const
+{
+  return GetPropertyBacktraces(this->DirectoryState->IncludeDirectories,
+                       this->DirectoryState->IncludeDirectoryBacktraces,
+                       this->Snapshot_.Position->IncludeDirectoryPosition);
+}
+
+void cmState::Directory::AppendIncludeDirectoriesEntry(
+    const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+  AppendEntry(this->DirectoryState->IncludeDirectories,
+              this->DirectoryState->IncludeDirectoryBacktraces,
+              this->Snapshot_.Position->IncludeDirectoryPosition,
+              vec, lfbt);
+}
+
+void cmState::Directory::PrependIncludeDirectoriesEntry(
+    const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+  std::vector<std::string>::iterator entryEnd =
+      this->DirectoryState->IncludeDirectories.begin()
+      + this->Snapshot_.Position->IncludeDirectoryPosition;
+
+  std::vector<std::string>::reverse_iterator rend =
+      this->DirectoryState->IncludeDirectories.rend();
+  std::vector<std::string>::reverse_iterator rbegin =
+      cmMakeReverseIterator(entryEnd);
+  rbegin = std::find(rbegin, rend, cmPropertySentinal);
+
+  std::vector<std::string>::iterator entryIt = rbegin.base();
+  std::vector<std::string>::iterator entryBegin =
+      this->DirectoryState->IncludeDirectories.begin();
+
+  std::vector<cmListFileBacktrace>::iterator btIt =
+      this->DirectoryState->IncludeDirectoryBacktraces.begin()
+      + std::distance(entryBegin, entryIt);
+
+  this->DirectoryState->IncludeDirectories.insert(entryIt, vec);
+  this->DirectoryState->IncludeDirectoryBacktraces.insert(btIt, lfbt);
+
+  this->Snapshot_.Position->IncludeDirectoryPosition =
+      this->DirectoryState->IncludeDirectories.size();
+}
+
+void cmState::Directory::SetIncludeDirectories(
+    const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+  SetContent(this->DirectoryState->IncludeDirectories,
+             this->DirectoryState->IncludeDirectoryBacktraces,
+             this->Snapshot_.Position->IncludeDirectoryPosition,
+             vec, lfbt);
+}
+
+void cmState::Directory::ClearIncludeDirectories()
+{
+  ClearContent(this->DirectoryState->IncludeDirectories,
+               this->DirectoryState->IncludeDirectoryBacktraces,
+               this->Snapshot_.Position->IncludeDirectoryPosition);
+}
+
+cmStringRange cmState::Directory::GetCompileDefinitionsEntries() const
+{
+  return GetPropertyContent(this->DirectoryState->CompileDefinitions,
+                     this->Snapshot_.Position->CompileDefinitionsPosition);
+}
+
+cmBacktraceRange
+cmState::Directory::GetCompileDefinitionsEntryBacktraces() const
+{
+  return GetPropertyBacktraces(this->DirectoryState->CompileDefinitions,
+                     this->DirectoryState->CompileDefinitionsBacktraces,
+                     this->Snapshot_.Position->CompileDefinitionsPosition);
+}
+
+void cmState::Directory::AppendCompileDefinitionsEntry(const std::string& vec,
+                                               const cmListFileBacktrace& lfbt)
+{
+  AppendEntry(this->DirectoryState->CompileDefinitions,
+              this->DirectoryState->CompileDefinitionsBacktraces,
+              this->Snapshot_.Position->CompileDefinitionsPosition,
+              vec, lfbt);
+}
+
+void cmState::Directory::SetCompileDefinitions(const std::string& vec,
+                                               const cmListFileBacktrace& lfbt)
+{
+  SetContent(this->DirectoryState->CompileDefinitions,
+             this->DirectoryState->CompileDefinitionsBacktraces,
+             this->Snapshot_.Position->CompileDefinitionsPosition,
+             vec, lfbt);
+}
+
+void cmState::Directory::ClearCompileDefinitions()
+{
+  ClearContent(this->DirectoryState->CompileDefinitions,
+               this->DirectoryState->CompileDefinitionsBacktraces,
+               this->Snapshot_.Position->CompileDefinitionsPosition);
+}
+
+cmStringRange cmState::Directory::GetCompileOptionsEntries() const
+{
+  return GetPropertyContent(this->DirectoryState->CompileOptions,
+                         this->Snapshot_.Position->CompileOptionsPosition);
+}
+
+cmBacktraceRange cmState::Directory::GetCompileOptionsEntryBacktraces() const
+{
+  return GetPropertyBacktraces(this->DirectoryState->CompileOptions,
+                         this->DirectoryState->CompileOptionsBacktraces,
+                         this->Snapshot_.Position->CompileOptionsPosition);
+}
+
+void
+cmState::Directory::AppendCompileOptionsEntry(const std::string& vec,
+                                              const cmListFileBacktrace& lfbt)
+{
+  AppendEntry(this->DirectoryState->CompileOptions,
+              this->DirectoryState->CompileOptionsBacktraces,
+              this->Snapshot_.Position->CompileOptionsPosition,
+              vec, lfbt);
+}
+
+void cmState::Directory::SetCompileOptions(const std::string& vec,
+                                           const cmListFileBacktrace& lfbt)
+{
+  SetContent(this->DirectoryState->CompileOptions,
+             this->DirectoryState->CompileOptionsBacktraces,
+             this->Snapshot_.Position->CompileOptionsPosition,
+             vec, lfbt);
+}
+
+void cmState::Directory::ClearCompileOptions()
+{
+  ClearContent(this->DirectoryState->CompileOptions,
+               this->DirectoryState->CompileOptionsBacktraces,
+               this->Snapshot_.Position->CompileOptionsPosition);
+}
+
+bool cmState::Snapshot::StrictWeakOrder::operator()(
+    const cmState::Snapshot& lhs, const cmState::Snapshot& rhs) const
+{
+  return lhs.Position.StrictWeakOrdered(rhs.Position);
+}
+
+void cmState::Directory::SetProperty(const std::string& prop,
+                                     const char* value,
+                                     cmListFileBacktrace lfbt)
+{
+  if (prop == "INCLUDE_DIRECTORIES")
+    {
+    if (!value)
+      {
+      this->ClearIncludeDirectories();
+      return;
+      }
+    this->SetIncludeDirectories(value, lfbt);
+    return;
+    }
+  if (prop == "COMPILE_OPTIONS")
+    {
+    if (!value)
+      {
+      this->ClearCompileOptions();
+      return;
+      }
+    this->SetCompileOptions(value, lfbt);
+    return;
+    }
+  if (prop == "COMPILE_DEFINITIONS")
+    {
+    if (!value)
+      {
+      this->ClearCompileDefinitions();
+      return;
+      }
+    this->SetCompileDefinitions(value, lfbt);
+    return;
+    }
+
+  this->DirectoryState->Properties.SetProperty(prop, value);
+}
+
+void cmState::Directory::AppendProperty(const std::string& prop,
+                                        const char* value,
+                                        bool asString,
+                                        cmListFileBacktrace lfbt)
+{
+  if (prop == "INCLUDE_DIRECTORIES")
+    {
+    this->AppendIncludeDirectoriesEntry(value, lfbt);
+    return;
+    }
+  if (prop == "COMPILE_OPTIONS")
+    {
+    this->AppendCompileOptionsEntry(value, lfbt);
+    return;
+    }
+  if (prop == "COMPILE_DEFINITIONS")
+    {
+    this->AppendCompileDefinitionsEntry(value, lfbt);
+    return;
+    }
+
+  this->DirectoryState->Properties.AppendProperty(prop, value, asString);
+}
+
+const char*cmState::Directory::GetProperty(const std::string& prop) const
+{
+  const bool chain = this->Snapshot_.State->
+      IsPropertyChained(prop, cmProperty::DIRECTORY);
+  return this->GetProperty(prop, chain);
+}
+
+const char*
+cmState::Directory::GetProperty(const std::string& prop, bool chain) const
+{
+  static std::string output;
+  output = "";
+  if (prop == "PARENT_DIRECTORY")
+    {
+    cmState::Snapshot parent =
+        this->Snapshot_.GetBuildsystemDirectoryParent();
+    if(parent.IsValid())
+      {
+      return parent.GetDirectory().GetCurrentSource();
+      }
+    return "";
+    }
+  else if (prop == "LISTFILE_STACK")
+    {
+    std::vector<std::string> listFiles;
+    cmState::Snapshot snp = this->Snapshot_;
+    while (snp.IsValid())
+      {
+      listFiles.push_back(snp.GetExecutionListFile());
+      snp = snp.GetCallStackParent();
+      }
+    std::reverse(listFiles.begin(), listFiles.end());
+    output = cmJoin(listFiles, ";");
+    return output.c_str();
+    }
+  else if ( prop == "CACHE_VARIABLES" )
+    {
+    output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
+    return output.c_str();
+    }
+  else if (prop == "VARIABLES")
+    {
+    std::vector<std::string> res = this->Snapshot_.ClosureKeys();
+    std::vector<std::string> cacheKeys =
+        this->Snapshot_.State->GetCacheEntryKeys();
+    res.insert(res.end(), cacheKeys.begin(), cacheKeys.end());
+    std::sort(res.begin(), res.end());
+    output = cmJoin(res, ";");
+    return output.c_str();
+    }
+  else if (prop == "INCLUDE_DIRECTORIES")
+    {
+    output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
+    return output.c_str();
+    }
+  else if (prop == "COMPILE_OPTIONS")
+    {
+    output = cmJoin(this->GetCompileOptionsEntries(), ";");
+    return output.c_str();
+    }
+  else if (prop == "COMPILE_DEFINITIONS")
+    {
+    output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
+    return output.c_str();
+    }
+
+  const char *retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
+  if (!retVal && chain)
+    {
+    Snapshot parentSnapshot = this->Snapshot_.GetBuildsystemDirectoryParent();
+    if (parentSnapshot.IsValid())
+      {
+      return parentSnapshot.GetDirectory().GetProperty(prop, chain);
+      }
+    return this->Snapshot_.State->GetGlobalProperty(prop);
+    }
+
+  return retVal;
+}
+
+bool cmState::Directory::GetPropertyAsBool(const std::string& prop) const
+{
+  return cmSystemTools::IsOn(this->GetProperty(prop));
+}
+
+std::vector<std::string> cmState::Directory::GetPropertyKeys() const
+{
+  std::vector<std::string> keys;
+  keys.reserve(this->DirectoryState->Properties.size());
+  for(cmPropertyMap::const_iterator it =
+      this->DirectoryState->Properties.begin();
+      it != this->DirectoryState->Properties.end(); ++it)
+    {
+    keys.push_back(it->first);
+    }
+  return keys;
+}
+
+bool operator==(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs)
+{
+  return lhs.Position == rhs.Position;
+}
+
+bool operator!=(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs)
+{
+  return lhs.Position != rhs.Position;
+}
diff --git a/Source/cmState.h b/Source/cmState.h
index 77a066f..99e537c 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -15,49 +15,191 @@
 #include "cmStandardIncludes.h"
 #include "cmPropertyDefinitionMap.h"
 #include "cmPropertyMap.h"
+#include "cmLinkedTree.h"
+#include "cmAlgorithms.h"
+#include "cmPolicies.h"
 
 class cmake;
 class cmCommand;
+class cmDefinitions;
+class cmListFileBacktrace;
 
 class cmState
 {
-  typedef std::vector<std::string>::size_type PositionType;
+  struct SnapshotDataType;
+  struct PolicyStackEntry;
+  struct BuildsystemDirectoryStateType;
+  typedef cmLinkedTree<SnapshotDataType>::iterator PositionType;
   friend class Snapshot;
 public:
   cmState(cmake* cm);
   ~cmState();
 
+  enum SnapshotType
+  {
+    BaseType,
+    BuildsystemDirectoryType,
+    FunctionCallType,
+    MacroCallType,
+    CallStackType,
+    InlineListFileType,
+    PolicyScopeType,
+    VariableScopeType
+  };
+
+  class Directory;
+
   class Snapshot {
   public:
-    Snapshot(cmState* state = 0, PositionType position = 0);
+    Snapshot(cmState* state = 0);
+    Snapshot(cmState* state, PositionType position);
+
+    const char* GetDefinition(std::string const& name) const;
+    bool IsInitialized(std::string const& name) const;
+    void SetDefinition(std::string const& name, std::string const& value);
+    void RemoveDefinition(std::string const& name);
+    std::vector<std::string> UnusedKeys() const;
+    std::vector<std::string> ClosureKeys() const;
+    bool RaiseScope(std::string const& var, const char* varDef);
+
+    void SetListFile(std::string const& listfile);
+
+    std::string GetExecutionListFile() const;
+
+    std::vector<Snapshot> GetChildren();
+    std::string GetEntryPointCommand() const;
+    long GetEntryPointLine() const;
+
+    bool IsValid() const;
+    Snapshot GetBuildsystemDirectoryParent() const;
+    Snapshot GetCallStackParent() const;
+    SnapshotType GetType() const;
 
-    const char* GetCurrentSourceDirectory() const;
-    void SetCurrentSourceDirectory(std::string const& dir);
-    const char* GetCurrentBinaryDirectory() const;
-    void SetCurrentBinaryDirectory(std::string const& dir);
+    void InitializeFromParent();
 
-    std::vector<std::string> const& GetCurrentSourceDirectoryComponents();
-    std::vector<std::string> const& GetCurrentBinaryDirectoryComponents();
+    void SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
+    cmPolicies::PolicyStatus GetPolicy(cmPolicies::PolicyID id) const;
+    bool HasDefinedPolicyCMP0011();
+    void PushPolicy(cmPolicies::PolicyMap entry, bool weak);
+    bool PopPolicy();
+    bool CanPopPolicyScope();
+
+    cmState* GetState() const;
+
+    Directory GetDirectory() const;
+
+    void SetProjectName(std::string const& name);
+    std::string GetProjectName() const;
+
+    struct StrictWeakOrder
+    {
+      bool operator()(const cmState::Snapshot& lhs,
+                      const cmState::Snapshot& rhs) const;
+    };
+
+  private:
+    friend bool operator==(const cmState::Snapshot& lhs,
+                           const cmState::Snapshot& rhs);
+    friend bool operator!=(const cmState::Snapshot& lhs,
+                           const cmState::Snapshot& rhs);
+    friend class cmState;
+    friend class Directory;
+    friend struct StrictWeakOrder;
+    cmState* State;
+    cmState::PositionType Position;
+  };
+
+  class Directory
+  {
+    Directory(cmLinkedTree<BuildsystemDirectoryStateType>::iterator iter,
+              Snapshot const& snapshot);
+  public:
+    const char* GetCurrentSource() const;
+    void SetCurrentSource(std::string const& dir);
+    const char* GetCurrentBinary() const;
+    void SetCurrentBinary(std::string const& dir);
+
+    std::vector<std::string> const&
+    GetCurrentSourceComponents() const;
+    std::vector<std::string> const&
+    GetCurrentBinaryComponents() const;
 
     const char* GetRelativePathTopSource() const;
     const char* GetRelativePathTopBinary() const;
     void SetRelativePathTopSource(const char* dir);
     void SetRelativePathTopBinary(const char* dir);
 
-    bool IsValid() const;
-    Snapshot GetParent() const;
+    cmStringRange GetIncludeDirectoriesEntries() const;
+    cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const;
+    void AppendIncludeDirectoriesEntry(std::string const& vec,
+                                       cmListFileBacktrace const& lfbt);
+    void PrependIncludeDirectoriesEntry(std::string const& vec,
+                                        cmListFileBacktrace const& lfbt);
+    void SetIncludeDirectories(std::string const& vec,
+                               cmListFileBacktrace const& lfbt);
+    void ClearIncludeDirectories();
+
+    cmStringRange GetCompileDefinitionsEntries() const;
+    cmBacktraceRange GetCompileDefinitionsEntryBacktraces() const;
+    void AppendCompileDefinitionsEntry(std::string const& vec,
+                                       cmListFileBacktrace const& lfbt);
+    void SetCompileDefinitions(std::string const& vec,
+                               cmListFileBacktrace const& lfbt);
+    void ClearCompileDefinitions();
+
+    cmStringRange GetCompileOptionsEntries() const;
+    cmBacktraceRange GetCompileOptionsEntryBacktraces() const;
+    void AppendCompileOptionsEntry(std::string const& vec,
+                                       cmListFileBacktrace const& lfbt);
+    void SetCompileOptions(std::string const& vec,
+                               cmListFileBacktrace const& lfbt);
+    void ClearCompileOptions();
+
+    void SetProperty(const std::string& prop, const char *value,
+                     cmListFileBacktrace lfbt);
+    void AppendProperty(const std::string& prop, const char *value,
+                        bool asString, cmListFileBacktrace lfbt);
+    const char *GetProperty(const std::string& prop) const;
+    const char *GetProperty(const std::string& prop, bool chain) const;
+    bool GetPropertyAsBool(const std::string& prop) const;
+    std::vector<std::string> GetPropertyKeys() const;
 
   private:
     void ComputeRelativePathTopSource();
     void ComputeRelativePathTopBinary();
 
   private:
-    friend class cmState;
-    cmState* State;
-    cmState::PositionType Position;
+    cmLinkedTree<BuildsystemDirectoryStateType>::iterator DirectoryState;
+    Snapshot Snapshot_;
+    friend class Snapshot;
   };
 
-  Snapshot CreateSnapshot(Snapshot originSnapshot);
+  Snapshot CreateBaseSnapshot();
+  Snapshot
+  CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
+                                     std::string const& entryPointCommand,
+                                     long entryPointLine);
+  Snapshot CreateFunctionCallSnapshot(Snapshot originSnapshot,
+                                      std::string const& entryPointCommand,
+                                      long entryPointLine,
+                                      std::string const& fileName);
+  Snapshot CreateMacroCallSnapshot(Snapshot originSnapshot,
+                                   std::string const& entryPointCommand,
+                                   long entryPointLine,
+                                   std::string const& fileName);
+  Snapshot CreateCallStackSnapshot(Snapshot originSnapshot,
+                                   std::string const& entryPointCommand,
+                                   long entryPointLine,
+                                   std::string const& fileName);
+  Snapshot CreateVariableScopeSnapshot(Snapshot originSnapshot,
+                                       std::string const& entryPointCommand,
+                                       long entryPointLine);
+  Snapshot CreateInlineListFileSnapshot(Snapshot originSnapshot,
+                                        const std::string& entryPointCommand,
+                                        long entryPointLine,
+                                        std::string const& fileName);
+  Snapshot CreatePolicyScopeSnapshot(Snapshot originSnapshot);
+  Snapshot Pop(Snapshot originSnapshot);
 
   enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC,
                        UNINITIALIZED };
@@ -93,7 +235,7 @@ public:
   void RemoveCacheEntryProperty(std::string const& key,
                                 std::string const& propertyName);
 
-  void Reset();
+  Snapshot Reset();
   // Define a property
   void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
                       const char *ShortDescription,
@@ -101,12 +243,14 @@ public:
                       bool chain = false);
 
   // get property definition
-  cmPropertyDefinition *GetPropertyDefinition
-  (const std::string& name, cmProperty::ScopeType scope);
+  cmPropertyDefinition const* GetPropertyDefinition
+  (const std::string& name, cmProperty::ScopeType scope) const;
 
   // Is a property defined?
-  bool IsPropertyDefined(const std::string& name, cmProperty::ScopeType scope);
-  bool IsPropertyChained(const std::string& name, cmProperty::ScopeType scope);
+  bool IsPropertyDefined(const std::string& name,
+                         cmProperty::ScopeType scope) const;
+  bool IsPropertyChained(const std::string& name,
+                         cmProperty::ScopeType scope) const;
 
   void SetLanguageEnabled(std::string const& l);
   bool GetLanguageEnabled(std::string const& l) const;
@@ -157,19 +301,14 @@ private:
   std::map<std::string, cmCommand*> Commands;
   cmPropertyMap GlobalProperties;
   cmake* CMakeInstance;
-  std::vector<std::string> Locations;
-  std::vector<std::string> OutputLocations;
-  std::vector<PositionType> ParentPositions;
-
-  std::vector<std::vector<std::string> > CurrentSourceDirectoryComponents;
-  std::vector<std::vector<std::string> > CurrentBinaryDirectoryComponents;
-  // The top-most directories for relative path conversion.  Both the
-  // source and destination location of a relative path conversion
-  // must be underneath one of these directories (both under source or
-  // both under binary) in order for the relative path to be evaluated
-  // safely by the build tools.
-  std::vector<std::string> RelativePathTopSource;
-  std::vector<std::string> RelativePathTopBinary;
+
+  cmLinkedTree<BuildsystemDirectoryStateType> BuildsystemDirectory;
+
+  cmLinkedTree<std::string> ExecutionListFiles;
+
+  cmLinkedTree<PolicyStackEntry> PolicyStack;
+  cmLinkedTree<SnapshotDataType> SnapshotData;
+  cmLinkedTree<cmDefinitions> VarTree;
 
   std::vector<std::string> SourceDirectoryComponents;
   std::vector<std::string> BinaryDirectoryComponents;
@@ -184,4 +323,7 @@ private:
   bool MSYSShell;
 };
 
+bool operator==(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs);
+bool operator!=(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs);
+
 #endif
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index edc6afc..649fb39 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -74,6 +74,10 @@ bool cmStringCommand
     {
     return this->HandleLengthCommand(args);
     }
+  else if(subCommand == "APPEND")
+    {
+    return this->HandleAppendCommand(args);
+    }
   else if(subCommand == "CONCAT")
     {
     return this->HandleConcatCommand(args);
@@ -315,7 +319,7 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
     }
 
   // Concatenate all the last arguments together.
-  std::string input = cmJoin(cmRange(args).advance(4), std::string());
+  std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
 
   // Scan through the input for all matches.
   std::string output;
@@ -361,7 +365,7 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
     }
 
   // Concatenate all the last arguments together.
-  std::string input = cmJoin(cmRange(args).advance(4), std::string());
+  std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
 
   // Scan through the input for all matches.
   std::string output;
@@ -461,7 +465,7 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
     }
 
   // Concatenate all the last arguments together.
-  std::string input = cmJoin(cmRange(args).advance(5), std::string());
+  std::string input = cmJoin(cmMakeRange(args).advance(5), std::string());
 
   // Scan through the input for all matches.
   std::string output;
@@ -661,7 +665,7 @@ bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const&
   const std::string& replaceExpression = args[2];
   const std::string& variableName = args[3];
 
-  std::string input = cmJoin(cmRange(args).advance(4), std::string());
+  std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
 
   cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(),
                                     replaceExpression.c_str());
@@ -730,6 +734,34 @@ bool cmStringCommand
 }
 
 //----------------------------------------------------------------------------
+bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args)
+{
+  if(args.size() < 2)
+    {
+    this->SetError("sub-command APPEND requires at least one argument.");
+    return false;
+    }
+
+  // Skip if nothing to append.
+  if(args.size() < 3)
+    {
+    return true;
+    }
+
+  const std::string& variable = args[1];
+
+  std::string value;
+  const char* oldValue = this->Makefile->GetDefinition(variable);
+  if(oldValue)
+    {
+    value = oldValue;
+    }
+  value += cmJoin(cmMakeRange(args).advance(2), std::string());
+  this->Makefile->AddDefinition(variable, value.c_str());
+  return true;
+}
+
+//----------------------------------------------------------------------------
 bool cmStringCommand
 ::HandleConcatCommand(std::vector<std::string> const& args)
 {
@@ -740,7 +772,7 @@ bool cmStringCommand
     }
 
   std::string const& variableName = args[1];
-  std::string value = cmJoin(cmRange(args).advance(2), std::string());
+  std::string value = cmJoin(cmMakeRange(args).advance(2), std::string());
 
   this->Makefile->AddDefinition(variableName, value.c_str());
   return true;
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index 9c75095..3ed17eb 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -67,6 +67,7 @@ protected:
   bool HandleReplaceCommand(std::vector<std::string> const& args);
   bool HandleLengthCommand(std::vector<std::string> const& args);
   bool HandleSubstringCommand(std::vector<std::string> const& args);
+  bool HandleAppendCommand(std::vector<std::string> const& args);
   bool HandleConcatCommand(std::vector<std::string> const& args);
   bool HandleStripCommand(std::vector<std::string> const& args);
   bool HandleRandomCommand(std::vector<std::string> const& args);
diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h
index 6addd8f..bcefd2c 100644
--- a/Source/cmSubdirCommand.h
+++ b/Source/cmSubdirCommand.h
@@ -44,12 +44,6 @@ public:
    */
   virtual std::string GetName() const { return "subdirs";}
 
-  /** This command is kept for compatibility with older CMake versions. */
-  virtual bool IsDiscouraged() const
-    {
-    return true;
-    }
-
   cmTypeMacro(cmSubdirCommand, cmCommand);
 };
 
diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h
index 75a5685..3f3507e 100644
--- a/Source/cmSubdirDependsCommand.h
+++ b/Source/cmSubdirDependsCommand.h
@@ -21,7 +21,6 @@ public:
   virtual bool InitialPass(std::vector<std::string> const& args,
                            cmExecutionStatus &status);
   virtual std::string GetName() const { return "subdir_depends";}
-  virtual bool IsDiscouraged() const { return true; }
   cmTypeMacro(cmSubdirDependsCommand, cmCommand);
 };
 
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index b440a17..2c5aa8a 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -30,7 +30,6 @@
 # include "cmLocale.h"
 # include <cm_libarchive.h>
 #endif
-#include <cmsys/stl/algorithm>
 #include <cmsys/FStream.hxx>
 #include <cmsys/Terminal.h>
 
@@ -69,6 +68,11 @@
 # include "cmMachO.h"
 #endif
 
+static bool cm_isspace(char c)
+{
+  return ((c & 0x80) == 0) && isspace(c);
+}
+
 class cmSystemToolsFileTime
 {
 public:
@@ -229,13 +233,13 @@ std::string cmSystemTools::HelpFileName(std::string name)
 std::string cmSystemTools::TrimWhitespace(const std::string& s)
 {
   std::string::const_iterator start = s.begin();
-  while(start != s.end() && *start <= ' ')
+  while (start != s.end() && cm_isspace(*start))
     ++start;
   if (start == s.end())
     return "";
 
   std::string::const_iterator stop = s.end()-1;
-  while(*stop <= ' ')
+  while (cm_isspace(*stop))
     --stop;
   return std::string(start, stop+1);
 }
@@ -497,7 +501,7 @@ void cmSystemTools::ParseWindowsCommandLine(const char* command,
       {
       arg.append(backslashes, '\\');
       backslashes = 0;
-      if(((*c & 0x80) == 0 ) && isspace(*c))
+      if (cm_isspace(*c))
         {
         if(in_quotes)
           {
@@ -556,25 +560,6 @@ void cmSystemTools::ParseUnixCommandLine(const char* command,
   argv.Store(args);
 }
 
-std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg,
-                                                      int shell_flags)
-{
-  char local_buffer[1024];
-  char* buffer = local_buffer;
-  int size = cmsysSystem_Shell_GetArgumentSizeForWindows(arg, shell_flags);
-  if(size > 1024)
-    {
-    buffer = new char[size];
-    }
-  cmsysSystem_Shell_GetArgumentForWindows(arg, buffer, shell_flags);
-  std::string result(buffer);
-  if(buffer != local_buffer)
-    {
-    delete [] buffer;
-    }
-  return result;
-}
-
 std::vector<std::string> cmSystemTools::ParseArguments(const char* command)
 {
   std::vector<std::string> args;
@@ -969,8 +954,9 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
      Try multiple times since we may be racing against another process
      creating/opening the destination file just before our MoveFileEx.  */
   WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();
-  while(!MoveFileExW(cmsys::Encoding::ToWide(oldname).c_str(),
-                     cmsys::Encoding::ToWide(newname).c_str(),
+  while(!MoveFileExW(
+      SystemTools::ConvertToWindowsExtendedPath(oldname).c_str(),
+      SystemTools::ConvertToWindowsExtendedPath(newname).c_str(),
                      MOVEFILE_REPLACE_EXISTING) && --retry.Count)
     {
     DWORD last_error = GetLastError();
@@ -981,12 +967,14 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
       return false;
       }
     DWORD attrs =
-      GetFileAttributesW(cmsys::Encoding::ToWide(newname).c_str());
+      GetFileAttributesW(
+        SystemTools::ConvertToWindowsExtendedPath(newname).c_str());
     if((attrs != INVALID_FILE_ATTRIBUTES) &&
        (attrs & FILE_ATTRIBUTE_READONLY))
       {
       // Remove the read-only attribute from the destination file.
-      SetFileAttributesW(cmsys::Encoding::ToWide(newname).c_str(),
+      SetFileAttributesW(
+        SystemTools::ConvertToWindowsExtendedPath(newname).c_str(),
                          attrs & ~FILE_ATTRIBUTE_READONLY);
       }
     else
@@ -1029,6 +1017,95 @@ std::string cmSystemTools::ComputeStringMD5(const std::string& input)
 #endif
 }
 
+//----------------------------------------------------------------------------
+std::string cmSystemTools::ComputeCertificateThumbprint(
+  const std::string& source)
+{
+  std::string thumbprint;
+
+#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32)
+  BYTE* certData = NULL;
+  CRYPT_INTEGER_BLOB cryptBlob;
+  HCERTSTORE certStore = NULL;
+  PCCERT_CONTEXT certContext = NULL;
+
+  HANDLE certFile =
+    CreateFileW(cmsys::Encoding::ToWide(source.c_str()).c_str(),
+                GENERIC_READ,
+                FILE_SHARE_READ,
+                NULL,
+                OPEN_EXISTING,
+                FILE_ATTRIBUTE_NORMAL,
+                NULL);
+
+  if (certFile != INVALID_HANDLE_VALUE && certFile != NULL)
+    {
+    DWORD fileSize = GetFileSize(certFile, NULL);
+    if (fileSize != INVALID_FILE_SIZE)
+      {
+      certData = new BYTE[fileSize];
+      if (certData != NULL)
+        {
+        DWORD dwRead = 0;
+        if (ReadFile(certFile, certData, fileSize, &dwRead, NULL))
+          {
+          cryptBlob.cbData = fileSize;
+          cryptBlob.pbData = certData;
+
+          // Verify that this is a valid cert
+          if (PFXIsPFXBlob(&cryptBlob))
+            {
+            // Open the certificate as a store
+            certStore = PFXImportCertStore(
+              &cryptBlob, NULL, CRYPT_EXPORTABLE);
+            if (certStore != NULL)
+              {
+              // There should only be 1 cert.
+              certContext = CertEnumCertificatesInStore(certStore,
+                certContext);
+              if (certContext != NULL)
+                {
+                // The hash is 20 bytes
+                BYTE hashData[20];
+                DWORD hashLength = 20;
+
+                // Buffer to print the hash. Each byte takes 2 chars +
+                // terminating character
+                char hashPrint[41];
+                char *pHashPrint = hashPrint;
+                // Get the hash property from the certificate
+                if (CertGetCertificateContextProperty(certContext,
+                  CERT_HASH_PROP_ID, hashData, &hashLength))
+                  {
+                  for (DWORD i = 0; i < hashLength; i++)
+                    {
+                    // Convert each byte to hexadecimal
+                    sprintf(pHashPrint, "%02X", hashData[i]);
+                    pHashPrint += 2;
+                    }
+                  *pHashPrint = '\0';
+                  thumbprint = hashPrint;
+                  }
+                CertFreeCertificateContext(certContext);
+                }
+              CertCloseStore(certStore, 0);
+              }
+            }
+          }
+        delete[] certData;
+        }
+      }
+    CloseHandle(certFile);
+    }
+#else
+  (void)source;
+  cmSystemTools::Message("ComputeCertificateThumbprint is not implemented",
+    "Error");
+#endif
+
+  return thumbprint;
+}
+
 void cmSystemTools::Glob(const std::string& directory,
                          const std::string& regexp,
                          std::vector<std::string>& files)
@@ -1337,15 +1414,6 @@ std::string cmSystemTools::ConvertToRunCommandPath(const char* path)
 #endif
 }
 
-bool cmSystemTools::StringEndsWith(const char* str1, const char* str2)
-{
-  if ( !str1 || !str2 || strlen(str1) < strlen(str2) )
-    {
-    return 0;
-    }
-  return !strncmp(str1 + (strlen(str1)-strlen(str2)), str2, strlen(str2));
-}
-
 // compute the relative path from here to there
 std::string cmSystemTools::RelativePath(const char* local, const char* remote)
 {
@@ -1498,7 +1566,7 @@ bool cmSystemTools::CreateTar(const char* outFileName,
 {
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
-  cmsys::ofstream fout(outFileName, std::ios::out | cmsys_ios_binary);
+  cmsys::ofstream fout(outFileName, std::ios::out | std::ios::binary);
   if(!fout)
     {
     std::string e = "Cannot open output file \"";
@@ -1721,7 +1789,7 @@ bool extract_tar(const char* outFileName, bool verbose,
   static_cast<void>(localeRAII);
   struct archive* a = archive_read_new();
   struct archive *ext = archive_write_disk_new();
-  archive_read_support_compression_all(a);
+  archive_read_support_filter_all(a);
   archive_read_support_format_all(a);
   struct archive_entry *entry;
   int r = cm_archive_read_open_file(a, outFileName, 10240);
@@ -1808,7 +1876,7 @@ bool extract_tar(const char* outFileName, bool verbose,
     }
   archive_write_free(ext);
   archive_read_close(a);
-  archive_read_finish(a);
+  archive_read_free(a);
   return r == ARCHIVE_EOF || r == ARCHIVE_OK;
 }
 }
@@ -1975,12 +2043,13 @@ bool cmSystemTools::CopyFileTime(const char* fromFile, const char* toFile)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   cmSystemToolsWindowsHandle hFrom =
-    CreateFileW(cmsys::Encoding::ToWide(fromFile).c_str(),
+    CreateFileW(SystemTools::ConvertToWindowsExtendedPath(fromFile).c_str(),
                 GENERIC_READ, FILE_SHARE_READ, 0,
-                OPEN_EXISTING, 0, 0);
+                OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
   cmSystemToolsWindowsHandle hTo =
-    CreateFileW(cmsys::Encoding::ToWide(toFile).c_str(),
-                GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+    CreateFileW(SystemTools::ConvertToWindowsExtendedPath(toFile).c_str(),
+                FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING,
+                FILE_FLAG_BACKUP_SEMANTICS, 0);
   if(!hFrom || !hTo)
     {
     return false;
@@ -2031,8 +2100,9 @@ bool cmSystemTools::FileTimeGet(const char* fname, cmSystemToolsFileTime* t)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   cmSystemToolsWindowsHandle h =
-    CreateFileW(cmsys::Encoding::ToWide(fname).c_str(),
-                GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+    CreateFileW(SystemTools::ConvertToWindowsExtendedPath(fname).c_str(),
+                GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,
+                FILE_FLAG_BACKUP_SEMANTICS, 0);
   if(!h)
     {
     return false;
@@ -2058,8 +2128,9 @@ bool cmSystemTools::FileTimeSet(const char* fname, cmSystemToolsFileTime* t)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   cmSystemToolsWindowsHandle h =
-    CreateFileW(cmsys::Encoding::ToWide(fname).c_str(),
-                GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+    CreateFileW(SystemTools::ConvertToWindowsExtendedPath(fname).c_str(),
+                FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING,
+                FILE_FLAG_BACKUP_SEMANTICS, 0);
   if(!h)
     {
     return false;
@@ -2148,6 +2219,7 @@ static std::string cmSystemToolsCTestCommand;
 static std::string cmSystemToolsCPackCommand;
 static std::string cmSystemToolsCMakeCursesCommand;
 static std::string cmSystemToolsCMakeGUICommand;
+static std::string cmSystemToolsCMClDepsCommand;
 static std::string cmSystemToolsCMakeRoot;
 void cmSystemTools::FindCMakeResources(const char* argv0)
 {
@@ -2240,6 +2312,13 @@ void cmSystemTools::FindCMakeResources(const char* argv0)
     {
     cmSystemToolsCMakeCursesCommand = "";
     }
+  cmSystemToolsCMClDepsCommand = exe_dir;
+  cmSystemToolsCMClDepsCommand += "/cmcldeps";
+  cmSystemToolsCMClDepsCommand += cmSystemTools::GetExecutableExtension();
+  if(!cmSystemTools::FileExists(cmSystemToolsCMClDepsCommand.c_str()))
+    {
+    cmSystemToolsCMClDepsCommand = "";
+    }
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
   // Install tree has "<prefix>/bin/cmake" and "<prefix><CMAKE_DATA_DIR>".
@@ -2307,6 +2386,12 @@ std::string const& cmSystemTools::GetCMakeGUICommand()
 }
 
 //----------------------------------------------------------------------------
+std::string const& cmSystemTools::GetCMClDepsCommand()
+{
+  return cmSystemToolsCMClDepsCommand;
+}
+
+//----------------------------------------------------------------------------
 std::string const& cmSystemTools::GetCMakeRoot()
 {
   return cmSystemToolsCMakeRoot;
@@ -2692,6 +2777,14 @@ bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
 }
 
 //----------------------------------------------------------------------------
+bool cmSystemTools::VersionCompareGreater(std::string const& lhs,
+                                          std::string const& rhs)
+{
+  return cmSystemTools::VersionCompare(
+    cmSystemTools::OP_GREATER, lhs.c_str(), rhs.c_str());
+}
+
+//----------------------------------------------------------------------------
 bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
                                 bool* removed)
 {
@@ -2955,3 +3048,12 @@ bool cmSystemTools::StringToLong(const char* str, long* value)
   *value = strtol(str, &endp, 10);
   return (*endp == '\0') && (endp != str) && (errno == 0);
 }
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::StringToULong(const char* str, unsigned long* value)
+{
+  errno = 0;
+  char *endp;
+  *value = strtoul(str, &endp, 10);
+  return (*endp == '\0') && (endp != str) && (errno == 0);
+}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 6feb6c5..b6b0978 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -194,6 +194,9 @@ public:
   /** Compute the md5sum of a string.  */
   static std::string ComputeStringMD5(const std::string& input);
 
+  ///! Get the SHA thumbprint for a certificate file
+  static std::string ComputeCertificateThumbprint(const std::string& source);
+
   /**
    * Run a single executable command
    *
@@ -256,11 +259,6 @@ public:
   static void ParseUnixCommandLine(const char* command,
                                    std::vector<std::string>& args);
 
-  /** Compute an escaped version of the given argument for use in a
-      windows shell.  See kwsys/System.h.in for details.  */
-  static std::string EscapeWindowsShellArgument(const char* arg,
-                                                int shell_flags);
-
   static void EnableMessages() { s_DisableMessages = false; }
   static void DisableMessages() { s_DisableMessages = true; }
   static void DisableRunCommandOutput() {s_DisableRunCommandOutput = true; }
@@ -296,6 +294,8 @@ public:
    * Compare versions
    */
   static bool VersionCompare(CompareOp op, const char* lhs, const char* rhs);
+  static bool VersionCompareGreater(std::string const& lhs,
+                                    std::string const& rhs);
 
   /**
    * Determine the file type based on the extension
@@ -338,8 +338,6 @@ public:
   // be used when RunCommand is called from cmake, because the
   // running cmake needs paths to be in its format
   static std::string ConvertToRunCommandPath(const char* path);
-  //! Check if the first string ends with the second one.
-  static bool StringEndsWith(const char* str1, const char* str2);
 
   /** compute the relative path from local to remote.  local must
       be a directory.  remote can be a file or a directory.
@@ -430,6 +428,7 @@ public:
   static std::string const& GetCMakeCommand();
   static std::string const& GetCMakeGUICommand();
   static std::string const& GetCMakeCursesCommand();
+  static std::string const& GetCMClDepsCommand();
   static std::string const& GetCMakeRoot();
 
   /** Echo a message in color using KWSys's Terminal cprintf.  */
@@ -469,6 +468,7 @@ public:
 
   /** Convert string to long. Expected that the whole string is an integer */
   static bool StringToLong(const char* str, long* value);
+  static bool StringToULong(const char* str, unsigned long* value);
 
 #ifdef _WIN32
   struct WindowsFileRetry
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 20d3208..bb44956 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -13,7 +13,7 @@
 #include "cmake.h"
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
 #include "cmGlobalGenerator.h"
 #include "cmComputeLinkInformation.h"
 #include "cmListFileCache.h"
@@ -66,27 +66,8 @@ struct cmTarget::OutputInfo
   std::string OutDir;
   std::string ImpDir;
   std::string PdbDir;
-};
-
-//----------------------------------------------------------------------------
-struct cmTarget::ImportInfo
-{
-  ImportInfo(): NoSOName(false), Multiplicity(0) {}
-  bool NoSOName;
-  int Multiplicity;
-  std::string Location;
-  std::string SOName;
-  std::string ImportLibrary;
-  std::string Languages;
-  std::string Libraries;
-  std::string LibrariesProp;
-  std::string SharedDeps;
-};
-
-//----------------------------------------------------------------------------
-struct cmTarget::CompileInfo
-{
-  std::string CompilePdbDir;
+  bool empty() const
+    { return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); }
 };
 
 //----------------------------------------------------------------------------
@@ -94,15 +75,13 @@ class cmTargetInternals
 {
 public:
   cmTargetInternals()
-    : Backtrace(NULL)
+    : Backtrace()
     {
-    this->PolicyWarnedCMP0022 = false;
     this->UtilityItemsDone = false;
     }
   cmTargetInternals(cmTargetInternals const&)
-    : Backtrace(NULL)
+    : Backtrace()
     {
-    this->PolicyWarnedCMP0022 = false;
     this->UtilityItemsDone = false;
     }
   ~cmTargetInternals();
@@ -110,88 +89,18 @@ public:
   // The backtrace when the target was created.
   cmListFileBacktrace Backtrace;
 
-  // Cache link interface computation from each configuration.
-  struct OptionalLinkInterface: public cmTarget::LinkInterface
-  {
-    OptionalLinkInterface():
-      LibrariesDone(false), AllDone(false),
-      Exists(false), HadHeadSensitiveCondition(false),
-      ExplicitLibraries(0) {}
-    bool LibrariesDone;
-    bool AllDone;
-    bool Exists;
-    bool HadHeadSensitiveCondition;
-    const char* ExplicitLibraries;
-  };
-  void ComputeLinkInterface(cmTarget const* thisTarget,
-                            const std::string& config,
-                            OptionalLinkInterface& iface,
-                            cmTarget const* head) const;
-  void ComputeLinkInterfaceLibraries(cmTarget const* thisTarget,
-                                     const std::string& config,
-                                     OptionalLinkInterface& iface,
-                                     cmTarget const* head,
-                                     bool usage_requirements_only);
-
-  struct HeadToLinkInterfaceMap:
-    public std::map<cmTarget const*, OptionalLinkInterface> {};
-  typedef std::map<std::string, HeadToLinkInterfaceMap>
-                                                          LinkInterfaceMapType;
-  LinkInterfaceMapType LinkInterfaceMap;
-  LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
-  bool PolicyWarnedCMP0022;
-
   typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType;
   OutputInfoMapType OutputInfoMap;
 
   typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
   ImportInfoMapType ImportInfoMap;
 
-  typedef std::map<std::string, cmTarget::CompileInfo> CompileInfoMapType;
-  CompileInfoMapType CompileInfoMap;
-
-  // Cache link implementation computation from each configuration.
-  struct OptionalLinkImplementation: public cmTarget::LinkImplementation
-  {
-    OptionalLinkImplementation():
-      LibrariesDone(false), LanguagesDone(false),
-      HadHeadSensitiveCondition(false) {}
-    bool LibrariesDone;
-    bool LanguagesDone;
-    bool HadHeadSensitiveCondition;
-  };
-  void ComputeLinkImplementationLibraries(cmTarget const* thisTarget,
-                                          const std::string& config,
-                                          OptionalLinkImplementation& impl,
-                                          cmTarget const* head) const;
-  void ComputeLinkImplementationLanguages(cmTarget const* thisTarget,
-                                          const std::string& config,
-                                          OptionalLinkImplementation& impl
-                                          ) const;
-
   struct HeadToLinkImplementationMap:
-    public std::map<cmTarget const*, OptionalLinkImplementation> {};
+    public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
   typedef std::map<std::string,
                    HeadToLinkImplementationMap> LinkImplMapType;
   LinkImplMapType LinkImplMap;
 
-  typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType;
-  LinkClosureMapType LinkClosureMap;
-
-  struct LinkImplClosure: public std::vector<cmTarget const*>
-  {
-    LinkImplClosure(): Done(false) {}
-    bool Done;
-  };
-  std::map<std::string, LinkImplClosure> LinkImplClosureMap;
-
-  struct CompatibleInterfaces: public cmTarget::CompatibleInterfaces
-  {
-    CompatibleInterfaces(): Done(false) {}
-    bool Done;
-  };
-  std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
-
   typedef std::map<std::string, std::vector<cmSourceFile*> >
                                                        SourceFilesMapType;
   SourceFilesMapType SourceFilesMap;
@@ -209,10 +118,14 @@ public:
     const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
     cmLinkImplItem const& LinkImplItem;
   };
-  std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
-  std::vector<TargetPropertyEntry*> CompileOptionsEntries;
-  std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
-  std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
+  std::vector<std::string> IncludeDirectoriesEntries;
+  std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
+  std::vector<std::string> CompileOptionsEntries;
+  std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
+  std::vector<std::string> CompileFeaturesEntries;
+  std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
+  std::vector<std::string> CompileDefinitionsEntries;
+  std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
   std::vector<TargetPropertyEntry*> SourceEntries;
   std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
 
@@ -224,14 +137,6 @@ public:
 cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem;
 
 //----------------------------------------------------------------------------
-static void deleteAndClear(
-      std::vector<cmTargetInternals::TargetPropertyEntry*> &entries)
-{
-  cmDeleteAll(entries);
-  entries.clear();
-}
-
-//----------------------------------------------------------------------------
 cmTargetInternals::~cmTargetInternals()
 {
 }
@@ -239,13 +144,6 @@ cmTargetInternals::~cmTargetInternals()
 //----------------------------------------------------------------------------
 cmTarget::cmTarget()
 {
-#define INITIALIZE_TARGET_POLICY_MEMBER(POLICY) \
-  this->PolicyStatus ## POLICY = cmPolicies::WARN;
-
-  CM_FOR_EACH_TARGET_POLICY(INITIALIZE_TARGET_POLICY_MEMBER)
-
-#undef INITIALIZE_TARGET_POLICY_MEMBER
-
   this->Makefile = 0;
 #if defined(_WIN32) && !defined(__CYGWIN__)
   this->LinkLibrariesForVS6Analyzed = false;
@@ -256,10 +154,6 @@ cmTarget::cmTarget()
   this->IsApple = false;
   this->IsImportedTarget = false;
   this->BuildInterfaceIncludesAppended = false;
-  this->DebugIncludesDone = false;
-  this->DebugCompileOptionsDone = false;
-  this->DebugCompileFeaturesDone = false;
-  this->DebugCompileDefinitionsDone = false;
   this->DebugSourcesDone = false;
   this->LinkImplementationLanguageIsContextDependent = true;
 }
@@ -286,9 +180,6 @@ void cmTarget::SetMakefile(cmMakefile* mf)
   // Set our makefile.
   this->Makefile = mf;
 
-  // set the cmake instance of the properties
-  this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
-
   // Check whether this is a DLL platform.
   this->DLLPlatform = (this->Makefile->IsOn("WIN32") ||
                        this->Makefile->IsOn("CYGWIN") ||
@@ -307,6 +198,20 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     {
     this->SetPropertyDefault("ANDROID_API", 0);
     this->SetPropertyDefault("ANDROID_API_MIN", 0);
+    this->SetPropertyDefault("ANDROID_ARCH", 0);
+    this->SetPropertyDefault("ANDROID_STL_TYPE", 0);
+    this->SetPropertyDefault("ANDROID_SKIP_ANT_STEP", 0);
+    this->SetPropertyDefault("ANDROID_PROCESS_MAX", 0);
+    this->SetPropertyDefault("ANDROID_PROGUARD", 0);
+    this->SetPropertyDefault("ANDROID_PROGUARD_CONFIG_PATH", 0);
+    this->SetPropertyDefault("ANDROID_SECURE_PROPS_PATH", 0);
+    this->SetPropertyDefault("ANDROID_NATIVE_LIB_DIRECTORIES", 0);
+    this->SetPropertyDefault("ANDROID_NATIVE_LIB_DEPENDENCIES", 0);
+    this->SetPropertyDefault("ANDROID_JAVA_SOURCE_DIR", 0);
+    this->SetPropertyDefault("ANDROID_JAR_DIRECTORIES", 0);
+    this->SetPropertyDefault("ANDROID_JAR_DEPENDENCIES", 0);
+    this->SetPropertyDefault("ANDROID_ASSETS_DIRECTORIES", 0);
+    this->SetPropertyDefault("ANDROID_ANT_ADDITIONAL_OPTIONS", 0);
     this->SetPropertyDefault("INSTALL_NAME_DIR", 0);
     this->SetPropertyDefault("INSTALL_RPATH", "");
     this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
@@ -333,14 +238,18 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     this->SetPropertyDefault("MACOSX_BUNDLE", 0);
     this->SetPropertyDefault("MACOSX_RPATH", 0);
     this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
+    this->SetPropertyDefault("C_COMPILER_LAUNCHER", 0);
     this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0);
     this->SetPropertyDefault("C_STANDARD", 0);
     this->SetPropertyDefault("C_STANDARD_REQUIRED", 0);
     this->SetPropertyDefault("C_EXTENSIONS", 0);
+    this->SetPropertyDefault("CXX_COMPILER_LAUNCHER", 0);
     this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", 0);
     this->SetPropertyDefault("CXX_STANDARD", 0);
     this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0);
     this->SetPropertyDefault("CXX_EXTENSIONS", 0);
+    this->SetPropertyDefault("LINK_SEARCH_START_STATIC", 0);
+    this->SetPropertyDefault("LINK_SEARCH_END_STATIC", 0);
     }
 
   // Collect the set of configuration types.
@@ -396,28 +305,35 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     {
     // Initialize the INCLUDE_DIRECTORIES property based on the current value
     // of the same directory property:
-    const std::vector<cmValueWithOrigin> parentIncludes =
-                                this->Makefile->GetIncludeDirectoriesEntries();
+    const cmStringRange parentIncludes =
+        this->Makefile->GetIncludeDirectoriesEntries();
+    const cmBacktraceRange parentIncludesBts =
+        this->Makefile->GetIncludeDirectoriesBacktraces();
+
+    this->Internal->IncludeDirectoriesEntries.insert(
+          this->Internal->IncludeDirectoriesEntries.end(),
+          parentIncludes.begin(), parentIncludes.end());
+    this->Internal->IncludeDirectoriesBacktraces.insert(
+          this->Internal->IncludeDirectoriesBacktraces.end(),
+          parentIncludesBts.begin(), parentIncludesBts.end());
 
-    for (std::vector<cmValueWithOrigin>::const_iterator it
-                = parentIncludes.begin(); it != parentIncludes.end(); ++it)
-      {
-      this->InsertInclude(*it);
-      }
     const std::set<std::string> parentSystemIncludes =
                                 this->Makefile->GetSystemIncludeDirectories();
 
     this->SystemIncludeDirectories.insert(parentSystemIncludes.begin(),
                                           parentSystemIncludes.end());
 
-    const std::vector<cmValueWithOrigin> parentOptions =
+    const cmStringRange parentOptions =
                                 this->Makefile->GetCompileOptionsEntries();
+    const cmBacktraceRange parentOptionsBts =
+                                this->Makefile->GetCompileOptionsBacktraces();
 
-    for (std::vector<cmValueWithOrigin>::const_iterator it
-                = parentOptions.begin(); it != parentOptions.end(); ++it)
-      {
-      this->InsertCompileOption(*it);
-      }
+    this->Internal->CompileOptionsEntries.insert(
+          this->Internal->CompileOptionsEntries.end(),
+          parentOptions.begin(), parentOptions.end());
+    this->Internal->CompileOptionsBacktraces.insert(
+          this->Internal->CompileOptionsBacktraces.end(),
+          parentOptionsBts.begin(), parentOptionsBts.end());
     }
 
   if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
@@ -431,32 +347,32 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     {
     this->SetPropertyDefault("ANDROID_GUI", 0);
     this->SetPropertyDefault("CROSSCOMPILING_EMULATOR", 0);
+    this->SetPropertyDefault("ENABLE_EXPORTS", 0);
     }
   if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
       || this->TargetTypeValue == cmTarget::MODULE_LIBRARY)
     {
     this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
     }
+  if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY)
+    {
+    this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", 0);
+    }
+
   if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
     {
     this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
     }
 
   // Record current policies for later use.
-#define CAPTURE_TARGET_POLICY(POLICY) \
-  this->PolicyStatus ## POLICY = \
-    this->Makefile->GetPolicyStatus(cmPolicies::POLICY);
-
-  CM_FOR_EACH_TARGET_POLICY(CAPTURE_TARGET_POLICY)
-
-#undef CAPTURE_TARGET_POLICY
+  this->Makefile->RecordPolicies(this->PolicyMap);
 
   if (this->TargetTypeValue == INTERFACE_LIBRARY)
     {
     // This policy is checked in a few conditions. The properties relevant
     // to the policy are always ignored for INTERFACE_LIBRARY targets,
     // so ensure that the conditions don't lead to nonsense.
-    this->PolicyStatusCMP0022 = cmPolicies::NEW;
+    this->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
     }
 
   if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
@@ -466,6 +382,21 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     }
 }
 
+void CreatePropertyGeneratorExpressions(
+    std::vector<std::string> const& entries,
+    std::vector<cmListFileBacktrace> const& backtraces,
+    std::vector<cmTargetInternals::TargetPropertyEntry*>& items)
+{
+  std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin();
+  for (std::vector<std::string>::const_iterator it = entries.begin();
+       it != entries.end(); ++it, ++btIt)
+    {
+    cmGeneratorExpression ge(*btIt);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*it);
+    items.push_back(new cmTargetInternals::TargetPropertyEntry(cge));
+    }
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::AddUtility(const std::string& u, cmMakefile *makefile)
 {
@@ -525,12 +456,7 @@ void cmTarget::ClearLinkMaps()
 {
   this->LinkImplementationLanguageIsContextDependent = true;
   this->Internal->LinkImplMap.clear();
-  this->Internal->LinkInterfaceMap.clear();
-  this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear();
-  this->Internal->LinkClosureMap.clear();
   this->Internal->SourceFilesMap.clear();
-  cmDeleteAll(this->LinkInformation);
-  this->LinkInformation.clear();
 }
 
 //----------------------------------------------------------------------------
@@ -612,13 +538,6 @@ bool cmTarget::IsXCTestOnApple() const
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::IsBundleOnApple() const
-{
-  return this->IsFrameworkOnApple() || this->IsAppBundleOnApple() ||
-         this->IsCFBundleOnApple();
-}
-
-//----------------------------------------------------------------------------
 static bool processSources(cmTarget const* tgt,
       const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
       std::vector<std::string> &srcs,
@@ -718,7 +637,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
 {
   assert(this->GetType() != INTERFACE_LIBRARY);
 
-  if (this->Makefile->GetGeneratorTargets().empty())
+  if (!this->GetMakefile()->GetGlobalGenerator()->GetConfigureDoneCMP0026())
     {
     // At configure-time, this method can be called as part of getting the
     // LOCATION property or to export() a file to be include()d.  However
@@ -764,7 +683,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
                                  "SOURCES")
                         != debugProperties.end();
 
-  if (this->Makefile->IsGeneratingBuildSystem())
+  if (this->GetMakefile()->GetGlobalGenerator()->GetConfigureDoneCMP0026())
     {
     this->DebugSourcesDone = true;
     }
@@ -803,63 +722,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
     this->LinkImplementationLanguageIsContextDependent = false;
     }
 
-  deleteAndClear(linkInterfaceSourcesEntries);
-}
-
-//----------------------------------------------------------------------------
-bool
-cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const
-{
-  std::vector<std::string> configs;
-  this->Makefile->GetConfigurations(configs);
-  if (configs.empty())
-    {
-    configs.push_back("");
-    }
-
-  std::vector<std::string>::const_iterator it = configs.begin();
-  const std::string& firstConfig = *it;
-  this->GetSourceFiles(files, firstConfig);
-
-  for ( ; it != configs.end(); ++it)
-    {
-    std::vector<cmSourceFile*> configFiles;
-    this->GetSourceFiles(configFiles, *it);
-    if (configFiles != files)
-      {
-      std::string firstConfigFiles;
-      const char* sep = "";
-      for (std::vector<cmSourceFile*>::const_iterator fi = files.begin();
-           fi != files.end(); ++fi)
-        {
-        firstConfigFiles += sep;
-        firstConfigFiles += (*fi)->GetFullPath();
-        sep = "\n  ";
-        }
-
-      std::string thisConfigFiles;
-      sep = "";
-      for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin();
-           fi != configFiles.end(); ++fi)
-        {
-        thisConfigFiles += sep;
-        thisConfigFiles += (*fi)->GetFullPath();
-        sep = "\n  ";
-        }
-      std::ostringstream e;
-      e << "Target \"" << this->Name << "\" has source files which vary by "
-        "configuration. This is not supported by the \""
-        << this->Makefile->GetGlobalGenerator()->GetName()
-        << "\" generator.\n"
-          "Config \"" << firstConfig << "\":\n"
-          "  " << firstConfigFiles << "\n"
-          "Config \"" << *it << "\":\n"
-          "  " << thisConfigFiles << "\n";
-      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-      return false;
-      }
-    }
-  return true;
+  cmDeleteAll(linkInterfaceSourcesEntries);
 }
 
 //----------------------------------------------------------------------------
@@ -911,7 +774,7 @@ void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
     this->Internal->SourceFilesMap.clear();
     this->LinkImplementationLanguageIsContextDependent = true;
     cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
+    cmGeneratorExpression ge(lfbt);
     cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(srcFiles);
     cge->SetEvaluateForBuildsystem(true);
     this->Internal->SourceEntries.push_back(
@@ -951,7 +814,7 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
     this->Internal->SourceFilesMap.clear();
     this->LinkImplementationLanguageIsContextDependent = true;
     cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
+    cmGeneratorExpression ge(lfbt);
     cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(srcFiles);
     cge->SetEvaluateForBuildsystem(true);
     this->Internal->SourceEntries.push_back(
@@ -1084,7 +947,7 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
     this->Internal->SourceFilesMap.clear();
     this->LinkImplementationLanguageIsContextDependent = true;
     cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
+    cmGeneratorExpression ge(lfbt);
     cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src);
     cge->SetEvaluateForBuildsystem(true);
     this->Internal->SourceEntries.push_back(
@@ -1257,14 +1120,14 @@ void cmTarget::GetTllSignatureTraces(std::ostringstream &s,
                                                                 : "plain");
   s << "The uses of the " << sigString << " signature are here:\n";
   typedef std::vector<std::pair<TLLSignature, cmListFileContext> > Container;
-  cmLocalGenerator* lg = this->GetMakefile()->GetLocalGenerator();
+  cmOutputConverter converter(this->GetMakefile()->GetStateSnapshot());
   for(Container::const_iterator it = this->TLLCommands.begin();
       it != this->TLLCommands.end(); ++it)
     {
     if (it->first == sig)
       {
       cmListFileContext lfc = it->second;
-      lfc.FilePath = lg->Convert(lfc.FilePath, cmLocalGenerator::HOME);
+      lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
       s << " * " << lfc << std::endl;
       }
     }
@@ -1351,11 +1214,44 @@ cmTarget::AddSystemIncludeDirectories(const std::set<std::string> &incs)
   this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
 }
 
-//----------------------------------------------------------------------------
-void
-cmTarget::AddSystemIncludeDirectories(const std::vector<std::string> &incs)
+cmStringRange cmTarget::GetIncludeDirectoriesEntries() const
 {
-  this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
+  return cmMakeRange(this->Internal->IncludeDirectoriesEntries);
+}
+
+cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const
+{
+  return cmMakeRange(this->Internal->IncludeDirectoriesBacktraces);
+}
+
+cmStringRange cmTarget::GetCompileOptionsEntries() const
+{
+  return cmMakeRange(this->Internal->CompileOptionsEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const
+{
+  return cmMakeRange(this->Internal->CompileOptionsBacktraces);
+}
+
+cmStringRange cmTarget::GetCompileFeaturesEntries() const
+{
+  return cmMakeRange(this->Internal->CompileFeaturesEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const
+{
+  return cmMakeRange(this->Internal->CompileFeaturesBacktraces);
+}
+
+cmStringRange cmTarget::GetCompileDefinitionsEntries() const
+{
+  return cmMakeRange(this->Internal->CompileDefinitionsEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
+{
+  return cmMakeRange(this->Internal->CompileDefinitionsBacktraces);
 }
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1704,39 +1600,47 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
     }
   else if(prop == "INCLUDE_DIRECTORIES")
     {
-    cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
-    deleteAndClear(this->Internal->IncludeDirectoriesEntries);
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
-    this->Internal->IncludeDirectoriesEntries.push_back(
-                          new cmTargetInternals::TargetPropertyEntry(cge));
+    this->Internal->IncludeDirectoriesEntries.clear();
+    this->Internal->IncludeDirectoriesBacktraces.clear();
+    if (value)
+      {
+      this->Internal->IncludeDirectoriesEntries.push_back(value);
+      cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+      this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
+      }
     }
   else if(prop == "COMPILE_OPTIONS")
     {
-    cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
-    deleteAndClear(this->Internal->CompileOptionsEntries);
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
-    this->Internal->CompileOptionsEntries.push_back(
-                          new cmTargetInternals::TargetPropertyEntry(cge));
+    this->Internal->CompileOptionsEntries.clear();
+    this->Internal->CompileOptionsBacktraces.clear();
+    if (value)
+      {
+      this->Internal->CompileOptionsEntries.push_back(value);
+      cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+      this->Internal->CompileOptionsBacktraces.push_back(lfbt);
+      }
     }
   else if(prop == "COMPILE_FEATURES")
     {
-    cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
-    deleteAndClear(this->Internal->CompileFeaturesEntries);
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
-    this->Internal->CompileFeaturesEntries.push_back(
-                          new cmTargetInternals::TargetPropertyEntry(cge));
+    this->Internal->CompileFeaturesEntries.clear();
+    this->Internal->CompileFeaturesBacktraces.clear();
+    if (value)
+      {
+      this->Internal->CompileFeaturesEntries.push_back(value);
+      cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+      this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
+      }
     }
   else if(prop == "COMPILE_DEFINITIONS")
     {
-    cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
-    deleteAndClear(this->Internal->CompileDefinitionsEntries);
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
-    this->Internal->CompileDefinitionsEntries.push_back(
-                          new cmTargetInternals::TargetPropertyEntry(cge));
+    this->Internal->CompileDefinitionsEntries.clear();
+    this->Internal->CompileDefinitionsBacktraces.clear();
+    if (value)
+      {
+      this->Internal->CompileDefinitionsEntries.push_back(value);
+      cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+      this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
+      }
     }
   else if(prop == "EXPORT_NAME" && this->IsImported())
     {
@@ -1767,7 +1671,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
       }
     this->Internal->SourceFilesMap.clear();
     cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
+    cmGeneratorExpression ge(lfbt);
+    cmDeleteAll(this->Internal->SourceEntries);
     this->Internal->SourceEntries.clear();
     cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
     this->Internal->SourceEntries.push_back(
@@ -1775,7 +1680,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
     }
   else
     {
-    this->Properties.SetProperty(prop, value, cmProperty::TARGET);
+    this->Properties.SetProperty(prop, value);
     this->MaybeInvalidatePropertyCache(prop);
     }
 }
@@ -1802,31 +1707,39 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
     }
   else if(prop == "INCLUDE_DIRECTORIES")
     {
-    cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
-    this->Internal->IncludeDirectoriesEntries.push_back(
-              new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+    if (value && *value)
+      {
+      this->Internal->IncludeDirectoriesEntries.push_back(value);
+      cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+      this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
+      }
     }
   else if(prop == "COMPILE_OPTIONS")
     {
-    cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
-    this->Internal->CompileOptionsEntries.push_back(
-              new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+    if (value && *value)
+      {
+      this->Internal->CompileOptionsEntries.push_back(value);
+      cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+      this->Internal->CompileOptionsBacktraces.push_back(lfbt);
+      }
     }
   else if(prop == "COMPILE_FEATURES")
     {
-    cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
-    this->Internal->CompileFeaturesEntries.push_back(
-              new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+    if (value && *value)
+      {
+      this->Internal->CompileFeaturesEntries.push_back(value);
+      cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+      this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
+      }
     }
   else if(prop == "COMPILE_DEFINITIONS")
     {
-    cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-    cmGeneratorExpression ge(&lfbt);
-    this->Internal->CompileDefinitionsEntries.push_back(
-              new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+    if (value && *value)
+      {
+      this->Internal->CompileDefinitionsEntries.push_back(value);
+      cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+      this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
+      }
     }
   else if(prop == "EXPORT_NAME" && this->IsImported())
     {
@@ -1837,7 +1750,7 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
     }
   else if (prop == "LINK_LIBRARIES")
     {
-    if (value)
+    if (value && *value)
       {
       cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
       cmValueWithOrigin entry(value, lfbt);
@@ -1854,16 +1767,16 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
       this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
       return;
       }
-      this->Internal->SourceFilesMap.clear();
-      cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-      cmGeneratorExpression ge(&lfbt);
-      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
-      this->Internal->SourceEntries.push_back(
-                            new cmTargetInternals::TargetPropertyEntry(cge));
+    this->Internal->SourceFilesMap.clear();
+    cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+    cmGeneratorExpression ge(lfbt);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+    this->Internal->SourceEntries.push_back(
+                          new cmTargetInternals::TargetPropertyEntry(cge));
     }
   else
     {
-    this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
+    this->Properties.AppendProperty(prop, value, asString);
     this->MaybeInvalidatePropertyCache(prop);
     }
 }
@@ -1921,610 +1834,87 @@ void cmTarget::AppendBuildInterfaceIncludes()
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::InsertInclude(const cmValueWithOrigin &entry,
-                     bool before)
+void cmTarget::InsertInclude(std::string const& entry,
+                             cmListFileBacktrace const& bt,
+                             bool before)
 {
-  cmGeneratorExpression ge(&entry.Backtrace);
+  std::vector<std::string>::iterator position =
+      before ? this->Internal->IncludeDirectoriesEntries.begin()
+             : this->Internal->IncludeDirectoriesEntries.end();
 
-  std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position
-                = before ? this->Internal->IncludeDirectoriesEntries.begin()
-                         : this->Internal->IncludeDirectoriesEntries.end();
+  std::vector<cmListFileBacktrace>::iterator btPosition =
+      before ? this->Internal->IncludeDirectoriesBacktraces.begin()
+             : this->Internal->IncludeDirectoriesBacktraces.end();
 
-  this->Internal->IncludeDirectoriesEntries.insert(position,
-      new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
+  this->Internal->IncludeDirectoriesEntries.insert(position, entry);
+  this->Internal->IncludeDirectoriesBacktraces.insert(btPosition, bt);
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::InsertCompileOption(const cmValueWithOrigin &entry,
-                     bool before)
+void cmTarget::InsertCompileOption(std::string const& entry,
+                                   cmListFileBacktrace const& bt,
+                                   bool before)
 {
-  cmGeneratorExpression ge(&entry.Backtrace);
+  std::vector<std::string>::iterator position =
+      before ? this->Internal->CompileOptionsEntries.begin()
+             : this->Internal->CompileOptionsEntries.end();
 
-  std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position
-                = before ? this->Internal->CompileOptionsEntries.begin()
-                         : this->Internal->CompileOptionsEntries.end();
+  std::vector<cmListFileBacktrace>::iterator btPosition =
+      before ? this->Internal->CompileOptionsBacktraces.begin()
+             : this->Internal->CompileOptionsBacktraces.end();
 
-  this->Internal->CompileOptionsEntries.insert(position,
-      new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
+  this->Internal->CompileOptionsEntries.insert(position, entry);
+  this->Internal->CompileOptionsBacktraces.insert(btPosition, bt);
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::InsertCompileDefinition(const cmValueWithOrigin &entry)
+void cmTarget::InsertCompileDefinition(std::string const& entry,
+                                       cmListFileBacktrace const& bt)
 {
-  cmGeneratorExpression ge(&entry.Backtrace);
-
-  this->Internal->CompileDefinitionsEntries.push_back(
-      new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
+  this->Internal->CompileDefinitionsEntries.push_back(entry);
+  this->Internal->CompileDefinitionsBacktraces.push_back(bt);
 }
 
 //----------------------------------------------------------------------------
-static void processIncludeDirectories(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &includes,
-      UNORDERED_SET<std::string> &uniqueIncludes,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugIncludes,
-      const std::string& language)
+void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
 {
-  cmMakefile *mf = tgt->GetMakefile();
-
-  for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
-      it = entries.begin(), end = entries.end(); it != end; ++it)
+  // Wipe out maps caching information affected by this property.
+  if(this->IsImported() && cmHasLiteralPrefix(prop, "IMPORTED"))
     {
-    cmLinkImplItem const& item = (*it)->LinkImplItem;
-    std::string const& targetName = item;
-    bool const fromImported = item.Target && item.Target->IsImported();
-    bool const checkCMP0027 = item.FromGenex;
-    std::vector<std::string> entryIncludes;
-    cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
-                                              config,
-                                              false,
-                                              tgt,
-                                              dagChecker, language),
-                                    entryIncludes);
-
-    std::string usedIncludes;
-    for(std::vector<std::string>::iterator
-          li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
-      {
-      if (fromImported
-          && !cmSystemTools::FileExists(li->c_str()))
-        {
-        std::ostringstream e;
-        cmake::MessageType messageType = cmake::FATAL_ERROR;
-        if (checkCMP0027)
-          {
-          switch(tgt->GetPolicyStatusCMP0027())
-            {
-            case cmPolicies::WARN:
-              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
-            case cmPolicies::OLD:
-              messageType = cmake::AUTHOR_WARNING;
-              break;
-            case cmPolicies::REQUIRED_ALWAYS:
-            case cmPolicies::REQUIRED_IF_USED:
-            case cmPolicies::NEW:
-              break;
-            }
-          }
-        e << "Imported target \"" << targetName << "\" includes "
-             "non-existent path\n  \"" << *li << "\"\nin its "
-             "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
-             "* The path was deleted, renamed, or moved to another "
-             "location.\n"
-             "* An install or uninstall procedure did not complete "
-             "successfully.\n"
-             "* The installation package was faulty and references files it "
-             "does not provide.\n";
-        tgt->GetMakefile()->IssueMessage(messageType, e.str());
-        return;
-        }
-
-      if (!cmSystemTools::FileIsFullPath(li->c_str()))
-        {
-        std::ostringstream e;
-        bool noMessage = false;
-        cmake::MessageType messageType = cmake::FATAL_ERROR;
-        if (!targetName.empty())
-          {
-          e << "Target \"" << targetName << "\" contains relative "
-            "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
-            "  \"" << *li << "\"";
-          }
-        else
-          {
-          switch(tgt->GetPolicyStatusCMP0021())
-            {
-            case cmPolicies::WARN:
-              {
-              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
-              messageType = cmake::AUTHOR_WARNING;
-              }
-              break;
-            case cmPolicies::OLD:
-              noMessage = true;
-            case cmPolicies::REQUIRED_IF_USED:
-            case cmPolicies::REQUIRED_ALWAYS:
-            case cmPolicies::NEW:
-              // Issue the fatal message.
-              break;
-            }
-          e << "Found relative path while evaluating include directories of "
-          "\"" << tgt->GetName() << "\":\n  \"" << *li << "\"\n";
-          }
-        if (!noMessage)
-          {
-          tgt->GetMakefile()->IssueMessage(messageType, e.str());
-          if (messageType == cmake::FATAL_ERROR)
-            {
-            return;
-            }
-          }
-        }
-
-      if (!cmSystemTools::IsOff(li->c_str()))
-        {
-        cmSystemTools::ConvertToUnixSlashes(*li);
-        }
-      std::string inc = *li;
-
-      if(uniqueIncludes.insert(inc).second)
-        {
-        includes.push_back(inc);
-        if (debugIncludes)
-          {
-          usedIncludes += " * " + inc + "\n";
-          }
-        }
-      }
-    if (!usedIncludes.empty())
-      {
-      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
-                            std::string("Used includes for target ")
-                            + tgt->GetName() + ":\n"
-                            + usedIncludes, (*it)->ge->GetBacktrace());
-      }
+    this->Internal->ImportInfoMap.clear();
+    }
+  if(!this->IsImported() && cmHasLiteralPrefix(prop, "LINK_INTERFACE_"))
+    {
+    this->ClearLinkMaps();
     }
 }
 
 //----------------------------------------------------------------------------
-std::vector<std::string>
-cmTarget::GetIncludeDirectories(const std::string& config,
-                                const std::string& language) const
+static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
+  const std::string& prop, const char* value, cmMakefile* context,
+  bool imported)
 {
-  std::vector<std::string> includes;
-  UNORDERED_SET<std::string> uniqueIncludes;
-
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                             "INCLUDE_DIRECTORIES", 0, 0);
-
-  std::vector<std::string> debugProperties;
-  const char *debugProp =
-              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp)
+  // Look for link-type keywords in the value.
+  static cmsys::RegularExpression
+    keys("(^|;)(debug|optimized|general)(;|$)");
+  if(!keys.find(value))
     {
-    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    return;
     }
 
-  bool debugIncludes = !this->DebugIncludesDone
-                    && std::find(debugProperties.begin(),
-                                 debugProperties.end(),
-                                 "INCLUDE_DIRECTORIES")
-                        != debugProperties.end();
+  // Support imported and non-imported versions of the property.
+  const char* base = (imported?
+                      "IMPORTED_LINK_INTERFACE_LIBRARIES" :
+                      "LINK_INTERFACE_LIBRARIES");
 
-  if (this->Makefile->IsGeneratingBuildSystem())
-    {
-    this->DebugIncludesDone = true;
-    }
-
-  processIncludeDirectories(this,
-                            this->Internal->IncludeDirectoriesEntries,
-                            includes,
-                            uniqueIncludes,
-                            &dagChecker,
-                            config,
-                            debugIncludes,
-                            language);
-
-  std::vector<cmTargetInternals::TargetPropertyEntry*>
-    linkInterfaceIncludeDirectoriesEntries;
-  this->Internal->AddInterfaceEntries(
-    this, config, "INTERFACE_INCLUDE_DIRECTORIES",
-    linkInterfaceIncludeDirectoriesEntries);
-
-  if(this->Makefile->IsOn("APPLE"))
-    {
-    LinkImplementation const* impl = this->GetLinkImplementation(config);
-    for(std::vector<cmLinkImplItem>::const_iterator
-        it = impl->Libraries.begin();
-        it != impl->Libraries.end(); ++it)
-      {
-      std::string libDir = cmSystemTools::CollapseFullPath(*it);
-
-      static cmsys::RegularExpression
-        frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
-      if(!frameworkCheck.find(libDir))
-        {
-        continue;
-        }
-
-      libDir = frameworkCheck.match(1);
-
-      cmGeneratorExpression ge;
-      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
-                ge.Parse(libDir.c_str());
-      linkInterfaceIncludeDirectoriesEntries
-              .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
-      }
-    }
-
-  processIncludeDirectories(this,
-                            linkInterfaceIncludeDirectoriesEntries,
-                            includes,
-                            uniqueIncludes,
-                            &dagChecker,
-                            config,
-                            debugIncludes,
-                            language);
-
-  deleteAndClear(linkInterfaceIncludeDirectoriesEntries);
-
-  return includes;
-}
-
-//----------------------------------------------------------------------------
-static void processCompileOptionsInternal(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &options,
-      UNORDERED_SET<std::string> &uniqueOptions,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugOptions, const char *logName,
-      std::string const& language)
-{
-  cmMakefile *mf = tgt->GetMakefile();
-
-  for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
-      it = entries.begin(), end = entries.end(); it != end; ++it)
-    {
-    std::vector<std::string> entryOptions;
-    cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
-                                              config,
-                                              false,
-                                              tgt,
-                                              dagChecker,
-                                              language),
-                                    entryOptions);
-    std::string usedOptions;
-    for(std::vector<std::string>::iterator
-          li = entryOptions.begin(); li != entryOptions.end(); ++li)
-      {
-      std::string const& opt = *li;
-
-      if(uniqueOptions.insert(opt).second)
-        {
-        options.push_back(opt);
-        if (debugOptions)
-          {
-          usedOptions += " * " + opt + "\n";
-          }
-        }
-      }
-    if (!usedOptions.empty())
-      {
-      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
-                            std::string("Used compile ") + logName
-                            + std::string(" for target ")
-                            + tgt->GetName() + ":\n"
-                            + usedOptions, (*it)->ge->GetBacktrace());
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-static void processCompileOptions(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &options,
-      UNORDERED_SET<std::string> &uniqueOptions,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugOptions,
-      std::string const& language)
-{
-  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
-                                dagChecker, config, debugOptions, "options",
-                                language);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetAutoUicOptions(std::vector<std::string> &result,
-                                 const std::string& config) const
-{
-  const char *prop
-            = this->GetLinkInterfaceDependentStringProperty("AUTOUIC_OPTIONS",
-                                                            config);
-  if (!prop)
-    {
-    return;
-    }
-  cmGeneratorExpression ge;
-
-  cmGeneratorExpressionDAGChecker dagChecker(
-                                      this->GetName(),
-                                      "AUTOUIC_OPTIONS", 0, 0);
-  cmSystemTools::ExpandListArgument(ge.Parse(prop)
-                                      ->Evaluate(this->Makefile,
-                                                config,
-                                                false,
-                                                this,
-                                                &dagChecker),
-                                  result);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetCompileOptions(std::vector<std::string> &result,
-                                 const std::string& config,
-                                 const std::string& language) const
-{
-  UNORDERED_SET<std::string> uniqueOptions;
-
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                             "COMPILE_OPTIONS", 0, 0);
-
-  std::vector<std::string> debugProperties;
-  const char *debugProp =
-              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp)
-    {
-    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
-    }
-
-  bool debugOptions = !this->DebugCompileOptionsDone
-                    && std::find(debugProperties.begin(),
-                                 debugProperties.end(),
-                                 "COMPILE_OPTIONS")
-                        != debugProperties.end();
-
-  if (this->Makefile->IsGeneratingBuildSystem())
-    {
-    this->DebugCompileOptionsDone = true;
-    }
-
-  processCompileOptions(this,
-                            this->Internal->CompileOptionsEntries,
-                            result,
-                            uniqueOptions,
-                            &dagChecker,
-                            config,
-                            debugOptions,
-                            language);
-
-  std::vector<cmTargetInternals::TargetPropertyEntry*>
-    linkInterfaceCompileOptionsEntries;
-
-  this->Internal->AddInterfaceEntries(
-    this, config, "INTERFACE_COMPILE_OPTIONS",
-    linkInterfaceCompileOptionsEntries);
-
-  processCompileOptions(this,
-                        linkInterfaceCompileOptionsEntries,
-                            result,
-                            uniqueOptions,
-                            &dagChecker,
-                            config,
-                            debugOptions,
-                            language);
-
-  deleteAndClear(linkInterfaceCompileOptionsEntries);
-}
-
-//----------------------------------------------------------------------------
-static void processCompileDefinitions(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &options,
-      UNORDERED_SET<std::string> &uniqueOptions,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugOptions,
-      std::string const& language)
-{
-  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
-                                dagChecker, config, debugOptions,
-                                "definitions", language);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
-                                            const std::string& config,
-                                            const std::string& language) const
-{
-  UNORDERED_SET<std::string> uniqueOptions;
-
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                             "COMPILE_DEFINITIONS", 0, 0);
-
-  std::vector<std::string> debugProperties;
-  const char *debugProp =
-              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp)
-    {
-    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
-    }
-
-  bool debugDefines = !this->DebugCompileDefinitionsDone
-                          && std::find(debugProperties.begin(),
-                                debugProperties.end(),
-                                "COMPILE_DEFINITIONS")
-                        != debugProperties.end();
-
-  if (this->Makefile->IsGeneratingBuildSystem())
-    {
-    this->DebugCompileDefinitionsDone = true;
-    }
-
-  processCompileDefinitions(this,
-                            this->Internal->CompileDefinitionsEntries,
-                            list,
-                            uniqueOptions,
-                            &dagChecker,
-                            config,
-                            debugDefines,
-                            language);
-
-  std::vector<cmTargetInternals::TargetPropertyEntry*>
-    linkInterfaceCompileDefinitionsEntries;
-  this->Internal->AddInterfaceEntries(
-    this, config, "INTERFACE_COMPILE_DEFINITIONS",
-    linkInterfaceCompileDefinitionsEntries);
-  if (!config.empty())
-    {
-    std::string configPropName = "COMPILE_DEFINITIONS_"
-                                        + cmSystemTools::UpperCase(config);
-    const char *configProp = this->GetProperty(configPropName);
-    if (configProp)
-      {
-      switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
-        {
-        case cmPolicies::WARN:
-          {
-          std::ostringstream e;
-          e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043);
-          this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
-                                       e.str());
-          }
-        case cmPolicies::OLD:
-          {
-          cmGeneratorExpression ge;
-          cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
-                                                      ge.Parse(configProp);
-          linkInterfaceCompileDefinitionsEntries
-                .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
-          }
-          break;
-        case cmPolicies::NEW:
-        case cmPolicies::REQUIRED_ALWAYS:
-        case cmPolicies::REQUIRED_IF_USED:
-          break;
-        }
-      }
-    }
-
-  processCompileDefinitions(this,
-                            linkInterfaceCompileDefinitionsEntries,
-                            list,
-                            uniqueOptions,
-                            &dagChecker,
-                            config,
-                            debugDefines,
-                            language);
-
-  deleteAndClear(linkInterfaceCompileDefinitionsEntries);
-}
-
-//----------------------------------------------------------------------------
-static void processCompileFeatures(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &options,
-      UNORDERED_SET<std::string> &uniqueOptions,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugOptions)
-{
-  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
-                                dagChecker, config, debugOptions, "features",
-                                std::string());
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
-                                  const std::string& config) const
-{
-  UNORDERED_SET<std::string> uniqueFeatures;
-
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                             "COMPILE_FEATURES",
-                                             0, 0);
-
-  std::vector<std::string> debugProperties;
-  const char *debugProp =
-              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp)
-    {
-    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
-    }
-
-  bool debugFeatures = !this->DebugCompileFeaturesDone
-                    && std::find(debugProperties.begin(),
-                                 debugProperties.end(),
-                                 "COMPILE_FEATURES")
-                        != debugProperties.end();
-
-  if (this->Makefile->IsGeneratingBuildSystem())
-    {
-    this->DebugCompileFeaturesDone = true;
-    }
-
-  processCompileFeatures(this,
-                            this->Internal->CompileFeaturesEntries,
-                            result,
-                            uniqueFeatures,
-                            &dagChecker,
-                            config,
-                            debugFeatures);
-
-  std::vector<cmTargetInternals::TargetPropertyEntry*>
-    linkInterfaceCompileFeaturesEntries;
-  this->Internal->AddInterfaceEntries(
-    this, config, "INTERFACE_COMPILE_FEATURES",
-    linkInterfaceCompileFeaturesEntries);
-
-  processCompileFeatures(this,
-                         linkInterfaceCompileFeaturesEntries,
-                            result,
-                            uniqueFeatures,
-                            &dagChecker,
-                            config,
-                            debugFeatures);
-
-  deleteAndClear(linkInterfaceCompileFeaturesEntries);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
-{
-  // Wipe out maps caching information affected by this property.
-  if(this->IsImported() && cmHasLiteralPrefix(prop, "IMPORTED"))
-    {
-    this->Internal->ImportInfoMap.clear();
-    }
-  if(!this->IsImported() && cmHasLiteralPrefix(prop, "LINK_INTERFACE_"))
-    {
-    this->ClearLinkMaps();
-    }
-}
-
-//----------------------------------------------------------------------------
-static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
-  const std::string& prop, const char* value, cmMakefile* context,
-  bool imported)
-{
-  // Look for link-type keywords in the value.
-  static cmsys::RegularExpression
-    keys("(^|;)(debug|optimized|general)(;|$)");
-  if(!keys.find(value))
-    {
-    return;
-    }
-
-  // Support imported and non-imported versions of the property.
-  const char* base = (imported?
-                      "IMPORTED_LINK_INTERFACE_LIBRARIES" :
-                      "LINK_INTERFACE_LIBRARIES");
-
-  // Report an error.
-  std::ostringstream e;
-  e << "Property " << prop << " may not contain link-type keyword \""
-    << keys.match(2) << "\".  "
-    << "The " << base << " property has a per-configuration "
-    << "version called " << base << "_<CONFIG> which may be "
-    << "used to specify per-configuration rules.";
-  if(!imported)
+  // Report an error.
+  std::ostringstream e;
+  e << "Property " << prop << " may not contain link-type keyword \""
+    << keys.match(2) << "\".  "
+    << "The " << base << " property has a per-configuration "
+    << "version called " << base << "_<CONFIG> which may be "
+    << "used to specify per-configuration rules.";
+  if(!imported)
     {
     e << "  "
       << "Alternatively, an IMPORTED library may be created, configured "
@@ -2637,59 +2027,36 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(
     config_upper = cmSystemTools::UpperCase(config);
     }
   typedef cmTargetInternals::OutputInfoMapType OutputInfoMapType;
-  OutputInfoMapType::const_iterator i =
+  OutputInfoMapType::iterator i =
     this->Internal->OutputInfoMap.find(config_upper);
   if(i == this->Internal->OutputInfoMap.end())
     {
+    // Add empty info in map to detect potential recursion.
     OutputInfo info;
+    OutputInfoMapType::value_type entry(config_upper, info);
+    i = this->Internal->OutputInfoMap.insert(entry).first;
+
+    // Compute output directories.
     this->ComputeOutputDir(config, false, info.OutDir);
     this->ComputeOutputDir(config, true, info.ImpDir);
     if(!this->ComputePDBOutputDir("PDB", config, info.PdbDir))
       {
       info.PdbDir = info.OutDir;
       }
-    OutputInfoMapType::value_type entry(config_upper, info);
-    i = this->Internal->OutputInfoMap.insert(entry).first;
-    }
-  return &i->second;
-}
 
-//----------------------------------------------------------------------------
-cmTarget::CompileInfo const* cmTarget::GetCompileInfo(
-                                            const std::string& config) const
-{
-  // There is no compile information for imported targets.
-  if(this->IsImported())
-    {
-    return 0;
+    // Now update the previously-prepared map entry.
+    i->second = info;
     }
-
-  if(this->GetType() > cmTarget::OBJECT_LIBRARY)
+  else if(i->second.empty())
     {
-    std::string msg = "cmTarget::GetCompileInfo called for ";
-    msg += this->GetName();
-    msg += " which has type ";
-    msg += cmTarget::GetTargetTypeName(this->GetType());
-    this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, msg);
+    // An empty map entry indicates we have been called recursively
+    // from the above block.
+    this->Makefile->GetCMakeInstance()->IssueMessage(
+      cmake::FATAL_ERROR,
+      "Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.",
+      this->GetBacktrace());
     return 0;
     }
-
-  // Lookup/compute/cache the compile information for this configuration.
-  std::string config_upper;
-  if(!config.empty())
-    {
-    config_upper = cmSystemTools::UpperCase(config);
-    }
-  typedef cmTargetInternals::CompileInfoMapType CompileInfoMapType;
-  CompileInfoMapType::const_iterator i =
-    this->Internal->CompileInfoMap.find(config_upper);
-  if(i == this->Internal->CompileInfoMap.end())
-    {
-    CompileInfo info;
-    this->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
-    CompileInfoMapType::value_type entry(config_upper, info);
-    i = this->Internal->CompileInfoMap.insert(entry).first;
-    }
   return &i->second;
 }
 
@@ -2724,65 +2091,16 @@ std::string cmTarget::GetPDBDirectory(const std::string& config) const
 }
 
 //----------------------------------------------------------------------------
-std::string cmTarget::GetCompilePDBDirectory(const std::string& config) const
+const char* cmTarget::ImportedGetLocation(const std::string& config) const
 {
-  if(CompileInfo const* info = this->GetCompileInfo(config))
-    {
-    return info->CompilePdbDir;
-    }
-  return "";
+  static std::string location;
+  assert(this->IsImported());
+  location = this->ImportedGetFullPath(config, false);
+  return location.c_str();
 }
 
 //----------------------------------------------------------------------------
-const char* cmTarget::GetLocation(const std::string& config) const
-{
-  static std::string location;
-  if (this->IsImported())
-    {
-    location = this->ImportedGetFullPath(config, false);
-    }
-  else
-    {
-    location = this->GetFullPath(config, false);
-    }
-  return location.c_str();
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::GetLocationForBuild() const
-{
-  static std::string location;
-  if(this->IsImported())
-    {
-    location = this->ImportedGetFullPath("", false);
-    return location.c_str();
-    }
-
-  // Now handle the deprecated build-time configuration location.
-  location = this->GetDirectory();
-  const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
-  if(cfgid && strcmp(cfgid, ".") != 0)
-    {
-    location += "/";
-    location += cfgid;
-    }
-
-  if(this->IsAppBundleOnApple())
-    {
-    std::string macdir = this->BuildMacContentDirectory("", "", false);
-    if(!macdir.empty())
-      {
-      location += "/";
-      location += macdir;
-      }
-    }
-  location += "/";
-  location += this->GetFullName("", false);
-  return location.c_str();
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetTargetVersion(int& major, int& minor) const
+void cmTarget::GetTargetVersion(int& major, int& minor) const
 {
   int patch;
   this->GetTargetVersion(false, major, minor, patch);
@@ -2820,34 +2138,6 @@ void cmTarget::GetTargetVersion(bool soversion,
 }
 
 //----------------------------------------------------------------------------
-const char* cmTarget::GetFeature(const std::string& feature,
-                                 const std::string& config) const
-{
-  if(!config.empty())
-    {
-    std::string featureConfig = feature;
-    featureConfig += "_";
-    featureConfig += cmSystemTools::UpperCase(config);
-    if(const char* value = this->GetProperty(featureConfig))
-      {
-      return value;
-      }
-    }
-  if(const char* value = this->GetProperty(feature))
-    {
-    return value;
-    }
-  return this->Makefile->GetFeature(feature, config);
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::GetFeatureAsBool(const std::string& feature,
-                                const std::string& config) const
-{
-  return cmSystemTools::IsOn(this->GetFeature(feature, config));
-}
-
-//----------------------------------------------------------------------------
 bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
 {
   if (this->IsImported())
@@ -2884,22 +2174,6 @@ bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
 }
 
 //----------------------------------------------------------------------------
-static void MakePropertyList(std::string& output,
-    std::vector<cmTargetInternals::TargetPropertyEntry*> const& values)
-{
-  output = "";
-  std::string sep;
-  for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
-       it = values.begin(), end = values.end();
-       it != end; ++it)
-    {
-    output += sep;
-    output += (*it)->ge->GetInput();
-    sep = ";";
-    }
-}
-
-//----------------------------------------------------------------------------
 const char *cmTarget::GetProperty(const std::string& prop) const
 {
   return this->GetProperty(prop, this->Makefile);
@@ -2940,12 +2214,24 @@ const char *cmTarget::GetProperty(const std::string& prop,
       // For an imported target this is the location of an arbitrary
       // available configuration.
       //
-      // For a non-imported target this is deprecated because it
-      // cannot take into account the per-configuration name of the
-      // target because the configuration type may not be known at
-      // CMake time.
-      this->Properties.SetProperty(propLOCATION, this->GetLocationForBuild(),
-                                   cmProperty::TARGET);
+      if(this->IsImported())
+        {
+        this->Properties.SetProperty(
+                propLOCATION, this->ImportedGetFullPath("", false).c_str());
+        }
+      else
+        {
+        // For a non-imported target this is deprecated because it
+        // cannot take into account the per-configuration name of the
+        // target because the configuration type may not be known at
+        // CMake time.
+        cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+        gg->CreateGenerationObjects();
+        cmGeneratorTarget* gt = gg->GetGeneratorTarget(this);
+        this->Properties.SetProperty(propLOCATION,
+                                     gt->GetLocationForBuild());
+        }
+
       }
 
     // Support "LOCATION_<CONFIG>".
@@ -2956,9 +2242,20 @@ const char *cmTarget::GetProperty(const std::string& prop,
         return 0;
         }
       const char* configName = prop.c_str() + 9;
-      this->Properties.SetProperty(prop,
-                                   this->GetLocation(configName),
-                                   cmProperty::TARGET);
+
+      if (this->IsImported())
+        {
+        this->Properties.SetProperty(
+                prop, this->ImportedGetFullPath(configName, false).c_str());
+        }
+      else
+        {
+        cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+        gg->CreateGenerationObjects();
+        cmGeneratorTarget* gt = gg->GetGeneratorTarget(this);
+        this->Properties.SetProperty(
+                prop, gt->GetFullPath(configName, false).c_str());
+        }
       }
     // Support "<CONFIG>_LOCATION".
     else if(cmHasLiteralSuffix(prop, "_LOCATION"))
@@ -2970,9 +2267,19 @@ const char *cmTarget::GetProperty(const std::string& prop,
           {
           return 0;
           }
-        this->Properties.SetProperty(prop,
-                                     this->GetLocation(configName),
-                                     cmProperty::TARGET);
+        if (this->IsImported())
+          {
+          this->Properties.SetProperty(
+                  prop, this->ImportedGetFullPath(configName, false).c_str());
+          }
+        else
+          {
+          cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+          gg->CreateGenerationObjects();
+          cmGeneratorTarget* gt = gg->GetGeneratorTarget(this);
+          this->Properties.SetProperty(
+                  prop, gt->GetFullPath(configName, false).c_str());
+          }
         }
       }
     }
@@ -2987,6 +2294,8 @@ const char *cmTarget::GetProperty(const std::string& prop,
   MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
   MAKE_STATIC_PROP(IMPORTED);
   MAKE_STATIC_PROP(NAME);
+  MAKE_STATIC_PROP(BINARY_DIR);
+  MAKE_STATIC_PROP(SOURCE_DIR);
   MAKE_STATIC_PROP(SOURCES);
 #undef MAKE_STATIC_PROP
   if(specialProps.empty())
@@ -2999,6 +2308,8 @@ const char *cmTarget::GetProperty(const std::string& prop,
     specialProps.insert(propCOMPILE_DEFINITIONS);
     specialProps.insert(propIMPORTED);
     specialProps.insert(propNAME);
+    specialProps.insert(propBINARY_DIR);
+    specialProps.insert(propSOURCE_DIR);
     specialProps.insert(propSOURCES);
     }
   if(specialProps.count(prop))
@@ -3037,7 +2348,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
         }
 
       static std::string output;
-      MakePropertyList(output, this->Internal->IncludeDirectoriesEntries);
+      output = cmJoin(this->Internal->IncludeDirectoriesEntries, ";");
       return output.c_str();
       }
     else if(prop == propCOMPILE_FEATURES)
@@ -3048,7 +2359,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
         }
 
       static std::string output;
-      MakePropertyList(output, this->Internal->CompileFeaturesEntries);
+      output = cmJoin(this->Internal->CompileFeaturesEntries, ";");
       return output.c_str();
       }
     else if(prop == propCOMPILE_OPTIONS)
@@ -3059,7 +2370,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
         }
 
       static std::string output;
-      MakePropertyList(output, this->Internal->CompileOptionsEntries);
+      output = cmJoin(this->Internal->CompileOptionsEntries, ";");
       return output.c_str();
       }
     else if(prop == propCOMPILE_DEFINITIONS)
@@ -3070,7 +2381,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
         }
 
       static std::string output;
-      MakePropertyList(output, this->Internal->CompileDefinitionsEntries);
+      output = cmJoin(this->Internal->CompileDefinitionsEntries, ";");
       return output.c_str();
       }
     else if (prop == propIMPORTED)
@@ -3081,6 +2392,14 @@ const char *cmTarget::GetProperty(const std::string& prop,
       {
       return this->GetName().c_str();
       }
+    else if (prop == propBINARY_DIR)
+      {
+      return this->GetMakefile()->GetCurrentBinaryDirectory();
+      }
+    else if (prop == propSOURCE_DIR)
+      {
+      return this->GetMakefile()->GetCurrentSourceDirectory();
+      }
     else if(prop == propSOURCES)
       {
       if (this->Internal->SourceEntries.empty())
@@ -3174,17 +2493,19 @@ const char *cmTarget::GetProperty(const std::string& prop,
             }
           }
         }
-      this->Properties.SetProperty("SOURCES", ss.str().c_str(),
-                                   cmProperty::TARGET);
+      this->Properties.SetProperty("SOURCES", ss.str().c_str());
       }
     }
 
-  bool chain = false;
-  const char *retVal =
-    this->Properties.GetPropertyValue(prop, cmProperty::TARGET, chain);
-  if (chain)
+  const char *retVal = this->Properties.GetPropertyValue(prop);
+  if (!retVal)
     {
-    return this->Makefile->GetProperty(prop, cmProperty::TARGET);
+    const bool chain = this->GetMakefile()->GetState()->
+                      IsPropertyChained(prop, cmProperty::TARGET);
+    if (chain)
+      {
+      return this->Makefile->GetProperty(prop, chain);
+      }
     }
   return retVal;
 }
@@ -3196,274 +2517,6 @@ bool cmTarget::GetPropertyAsBool(const std::string& prop) const
 }
 
 //----------------------------------------------------------------------------
-class cmTargetCollectLinkLanguages
-{
-public:
-  cmTargetCollectLinkLanguages(cmTarget const* target,
-                               const std::string& config,
-                               UNORDERED_SET<std::string>& languages,
-                               cmTarget const* head):
-    Config(config), Languages(languages), HeadTarget(head),
-    Makefile(target->GetMakefile()), Target(target)
-  { this->Visited.insert(target); }
-
-  void Visit(cmLinkItem const& item)
-    {
-    if(!item.Target)
-      {
-      if(item.find("::") != std::string::npos)
-        {
-        bool noMessage = false;
-        cmake::MessageType messageType = cmake::FATAL_ERROR;
-        std::ostringstream e;
-        switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028))
-          {
-          case cmPolicies::WARN:
-            {
-            e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0028) << "\n";
-            messageType = cmake::AUTHOR_WARNING;
-            }
-            break;
-          case cmPolicies::OLD:
-            noMessage = true;
-          case cmPolicies::REQUIRED_IF_USED:
-          case cmPolicies::REQUIRED_ALWAYS:
-          case cmPolicies::NEW:
-            // Issue the fatal message.
-            break;
-          }
-
-        if(!noMessage)
-          {
-          e << "Target \"" << this->Target->GetName()
-            << "\" links to target \"" << item
-            << "\" but the target was not found.  Perhaps a find_package() "
-            "call is missing for an IMPORTED target, or an ALIAS target is "
-            "missing?";
-          this->Makefile->GetCMakeInstance()->IssueMessage(messageType,
-                                                e.str(),
-                                                this->Target->GetBacktrace());
-          }
-        }
-      return;
-      }
-    if(!this->Visited.insert(item.Target).second)
-      {
-      return;
-      }
-
-    cmTarget::LinkInterface const* iface =
-      item.Target->GetLinkInterface(this->Config, this->HeadTarget);
-    if(!iface) { return; }
-
-    for(std::vector<std::string>::const_iterator
-          li = iface->Languages.begin(); li != iface->Languages.end(); ++li)
-      {
-      this->Languages.insert(*li);
-      }
-
-    for(std::vector<cmLinkItem>::const_iterator
-          li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
-      {
-      this->Visit(*li);
-      }
-    }
-private:
-  std::string Config;
-  UNORDERED_SET<std::string>& Languages;
-  cmTarget const* HeadTarget;
-  cmMakefile* Makefile;
-  const cmTarget* Target;
-  std::set<cmTarget const*> Visited;
-};
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetLinkerLanguage(const std::string& config) const
-{
-  return this->GetLinkClosure(config)->LinkerLanguage;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkClosure const*
-cmTarget::GetLinkClosure(const std::string& config) const
-{
-  std::string key(cmSystemTools::UpperCase(config));
-  cmTargetInternals::LinkClosureMapType::iterator
-    i = this->Internal->LinkClosureMap.find(key);
-  if(i == this->Internal->LinkClosureMap.end())
-    {
-    LinkClosure lc;
-    this->ComputeLinkClosure(config, lc);
-    cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
-    i = this->Internal->LinkClosureMap.insert(entry).first;
-    }
-  return &i->second;
-}
-
-//----------------------------------------------------------------------------
-class cmTargetSelectLinker
-{
-  int Preference;
-  cmTarget const* Target;
-  cmMakefile* Makefile;
-  cmGlobalGenerator* GG;
-  UNORDERED_SET<std::string> Preferred;
-public:
-  cmTargetSelectLinker(cmTarget const* target): Preference(0), Target(target)
-    {
-    this->Makefile = this->Target->GetMakefile();
-    this->GG = this->Makefile->GetGlobalGenerator();
-    }
-  void Consider(const std::string& lang)
-    {
-    int preference = this->GG->GetLinkerPreference(lang);
-    if(preference > this->Preference)
-      {
-      this->Preference = preference;
-      this->Preferred.clear();
-      }
-    if(preference == this->Preference)
-      {
-      this->Preferred.insert(lang);
-      }
-    }
-  std::string Choose()
-    {
-    if(this->Preferred.empty())
-      {
-      return "";
-      }
-    else if(this->Preferred.size() > 1)
-      {
-      std::ostringstream e;
-      e << "Target " << this->Target->GetName()
-        << " contains multiple languages with the highest linker preference"
-        << " (" << this->Preference << "):\n";
-      for(UNORDERED_SET<std::string>::const_iterator
-            li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
-        {
-        e << "  " << *li << "\n";
-        }
-      e << "Set the LINKER_LANGUAGE property for this target.";
-      cmake* cm = this->Makefile->GetCMakeInstance();
-      cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
-                       this->Target->GetBacktrace());
-      }
-    return *this->Preferred.begin();
-    }
-};
-
-//----------------------------------------------------------------------------
-void cmTarget::ComputeLinkClosure(const std::string& config,
-                                  LinkClosure& lc) const
-{
-  // Get languages built in this target.
-  UNORDERED_SET<std::string> languages;
-  LinkImplementation const* impl = this->GetLinkImplementation(config);
-  for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
-      li != impl->Languages.end(); ++li)
-    {
-    languages.insert(*li);
-    }
-
-  // Add interface languages from linked targets.
-  cmTargetCollectLinkLanguages cll(this, config, languages, this);
-  for(std::vector<cmLinkImplItem>::const_iterator
-        li = impl->Libraries.begin();
-      li != impl->Libraries.end(); ++li)
-    {
-    cll.Visit(*li);
-    }
-
-  // Store the transitive closure of languages.
-  for(UNORDERED_SET<std::string>::const_iterator li = languages.begin();
-      li != languages.end(); ++li)
-    {
-    lc.Languages.push_back(*li);
-    }
-
-  // Choose the language whose linker should be used.
-  if(this->GetProperty("HAS_CXX"))
-    {
-    lc.LinkerLanguage = "CXX";
-    }
-  else if(const char* linkerLang = this->GetProperty("LINKER_LANGUAGE"))
-    {
-    lc.LinkerLanguage = linkerLang;
-    }
-  else
-    {
-    // Find the language with the highest preference value.
-    cmTargetSelectLinker tsl(this);
-
-    // First select from the languages compiled directly in this target.
-    for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
-        li != impl->Languages.end(); ++li)
-      {
-      tsl.Consider(*li);
-      }
-
-    // Now consider languages that propagate from linked targets.
-    for(UNORDERED_SET<std::string>::const_iterator sit = languages.begin();
-        sit != languages.end(); ++sit)
-      {
-      std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
-      if(this->Makefile->IsOn(propagates))
-        {
-        tsl.Consider(*sit);
-        }
-      }
-
-    lc.LinkerLanguage = tsl.Choose();
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::ExpandLinkItems(std::string const& prop,
-                               std::string const& value,
-                               std::string const& config,
-                               cmTarget const* headTarget,
-                               bool usage_requirements_only,
-                               std::vector<cmLinkItem>& items,
-                               bool& hadHeadSensitiveCondition) const
-{
-  cmGeneratorExpression ge;
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
-  // The $<LINK_ONLY> expression may be in a link interface to specify private
-  // link dependencies that are otherwise excluded from usage requirements.
-  if(usage_requirements_only)
-    {
-    dagChecker.SetTransitivePropertiesOnly();
-    }
-  std::vector<std::string> libs;
-  cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
-  cmSystemTools::ExpandListArgument(cge->Evaluate(
-                                      this->Makefile,
-                                      config,
-                                      false,
-                                      headTarget,
-                                      this, &dagChecker), libs);
-  this->LookupLinkItems(libs, items);
-  hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::LookupLinkItems(std::vector<std::string> const& names,
-                               std::vector<cmLinkItem>& items) const
-{
-  for(std::vector<std::string>::const_iterator i = names.begin();
-      i != names.end(); ++i)
-    {
-    std::string name = this->CheckCMP0004(*i);
-    if(name == this->GetName() || name.empty())
-      {
-      continue;
-      }
-    items.push_back(cmLinkItem(name, this->FindTargetToLink(name)));
-    }
-}
-
-//----------------------------------------------------------------------------
 const char* cmTarget::GetSuffixVariableInternal(bool implib) const
 {
   switch(this->GetType())
@@ -3521,133 +2574,6 @@ const char* cmTarget::GetPrefixVariableInternal(bool implib) const
 }
 
 //----------------------------------------------------------------------------
-std::string cmTarget::GetPDBName(const std::string& config) const
-{
-  std::string prefix;
-  std::string base;
-  std::string suffix;
-  this->GetFullNameInternal(config, false, prefix, base, suffix);
-
-  std::vector<std::string> props;
-  std::string configUpper = cmSystemTools::UpperCase(config);
-  if(!configUpper.empty())
-    {
-    // PDB_NAME_<CONFIG>
-    props.push_back("PDB_NAME_" + configUpper);
-    }
-
-  // PDB_NAME
-  props.push_back("PDB_NAME");
-
-  for(std::vector<std::string>::const_iterator i = props.begin();
-      i != props.end(); ++i)
-    {
-    if(const char* outName = this->GetProperty(*i))
-      {
-      base = outName;
-      break;
-      }
-    }
-  return prefix+base+".pdb";
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetCompilePDBName(const std::string& config) const
-{
-  std::string prefix;
-  std::string base;
-  std::string suffix;
-  this->GetFullNameInternal(config, false, prefix, base, suffix);
-
-  // Check for a per-configuration output directory target property.
-  std::string configUpper = cmSystemTools::UpperCase(config);
-  std::string configProp = "COMPILE_PDB_NAME_";
-  configProp += configUpper;
-  const char* config_name = this->GetProperty(configProp);
-  if(config_name && *config_name)
-    {
-    return prefix + config_name + ".pdb";
-    }
-
-  const char* name = this->GetProperty("COMPILE_PDB_NAME");
-  if(name && *name)
-    {
-    return prefix + name + ".pdb";
-    }
-
-  return "";
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetCompilePDBPath(const std::string& config) const
-{
-  std::string dir = this->GetCompilePDBDirectory(config);
-  std::string name = this->GetCompilePDBName(config);
-  if(dir.empty() && !name.empty())
-    {
-    dir = this->GetPDBDirectory(config);
-    }
-  if(!dir.empty())
-    {
-    dir += "/";
-    }
-  return dir + name;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::HasSOName(const std::string& config) const
-{
-  // soname is supported only for shared libraries and modules,
-  // and then only when the platform supports an soname flag.
-  return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
-           this->GetType() == cmTarget::MODULE_LIBRARY) &&
-          !this->GetPropertyAsBool("NO_SONAME") &&
-          this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetSOName(const std::string& config) const
-{
-  if(this->IsImported())
-    {
-    // Lookup the imported soname.
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
-      {
-      if(info->NoSOName)
-        {
-        // The imported library has no builtin soname so the name
-        // searched at runtime will be just the filename.
-        return cmSystemTools::GetFilenameName(info->Location);
-        }
-      else
-        {
-        // Use the soname given if any.
-        if(info->SOName.find("@rpath/") == 0)
-          {
-          return info->SOName.substr(6);
-          }
-        return info->SOName;
-        }
-      }
-    else
-      {
-      return "";
-      }
-    }
-  else
-    {
-    // Compute the soname that will be built.
-    std::string name;
-    std::string soName;
-    std::string realName;
-    std::string impName;
-    std::string pdbName;
-    this->GetLibraryNames(name, soName, realName, impName, pdbName, config);
-    return soName;
-    }
-}
-
-//----------------------------------------------------------------------------
 bool cmTarget::HasMacOSXRpathInstallNameDir(const std::string& config) const
 {
   bool install_name_is_rpath = false;
@@ -3774,117 +2700,14 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(
 }
 
 //----------------------------------------------------------------------------
-std::string cmTarget::NormalGetRealName(const std::string& config) const
-{
-  // This should not be called for imported targets.
-  // TODO: Split cmTarget into a class hierarchy to get compile-time
-  // enforcement of the limited imported target API.
-  if(this->IsImported())
-    {
-    std::string msg =  "NormalGetRealName called on imported target: ";
-    msg += this->GetName();
-    this->GetMakefile()->
-      IssueMessage(cmake::INTERNAL_ERROR,
-                   msg);
-    }
-
-  if(this->GetType() == cmTarget::EXECUTABLE)
-    {
-    // Compute the real name that will be built.
-    std::string name;
-    std::string realName;
-    std::string impName;
-    std::string pdbName;
-    this->GetExecutableNames(name, realName, impName, pdbName, config);
-    return realName;
-    }
-  else
-    {
-    // Compute the real name that will be built.
-    std::string name;
-    std::string soName;
-    std::string realName;
-    std::string impName;
-    std::string pdbName;
-    this->GetLibraryNames(name, soName, realName, impName, pdbName, config);
-    return realName;
-    }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFullName(const std::string& config,
-                                  bool implib) const
-{
-  if(this->IsImported())
-    {
-    return this->GetFullNameImported(config, implib);
-    }
-  else
-    {
-    return this->GetFullNameInternal(config, implib);
-    }
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmTarget::GetFullNameImported(const std::string& config, bool implib) const
+std::string
+cmTarget::GetFullNameImported(const std::string& config, bool implib) const
 {
   return cmSystemTools::GetFilenameName(
     this->ImportedGetFullPath(config, implib));
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetFullNameComponents(std::string& prefix, std::string& base,
-                                     std::string& suffix,
-                                     const std::string& config,
-                                     bool implib) const
-{
-  this->GetFullNameInternal(config, implib, prefix, base, suffix);
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFullPath(const std::string& config, bool implib,
-                                  bool realname) const
-{
-  if(this->IsImported())
-    {
-    return this->ImportedGetFullPath(config, implib);
-    }
-  else
-    {
-    return this->NormalGetFullPath(config, implib, realname);
-    }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::NormalGetFullPath(const std::string& config,
-                                        bool implib, bool realname) const
-{
-  std::string fpath = this->GetDirectory(config, implib);
-  fpath += "/";
-  if(this->IsAppBundleOnApple())
-    {
-    fpath = this->BuildMacContentDirectory(fpath, config, false);
-    fpath += "/";
-    }
-
-  // Add the full name of the target.
-  if(implib)
-    {
-    fpath += this->GetFullName(config, true);
-    }
-  else if(realname)
-    {
-    fpath += this->NormalGetRealName(config);
-    }
-  else
-    {
-    fpath += this->GetFullName(config, false);
-    }
-  return fpath;
-}
-
-//----------------------------------------------------------------------------
 std::string
 cmTarget::ImportedGetFullPath(const std::string& config, bool implib) const
 {
@@ -3902,237 +2725,6 @@ cmTarget::ImportedGetFullPath(const std::string& config, bool implib) const
 }
 
 //----------------------------------------------------------------------------
-std::string
-cmTarget::GetFullNameInternal(const std::string& config, bool implib) const
-{
-  std::string prefix;
-  std::string base;
-  std::string suffix;
-  this->GetFullNameInternal(config, implib, prefix, base, suffix);
-  return prefix+base+suffix;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetFullNameInternal(const std::string& config,
-                                   bool implib,
-                                   std::string& outPrefix,
-                                   std::string& outBase,
-                                   std::string& outSuffix) const
-{
-  // Use just the target name for non-main target types.
-  if(this->GetType() != cmTarget::STATIC_LIBRARY &&
-     this->GetType() != cmTarget::SHARED_LIBRARY &&
-     this->GetType() != cmTarget::MODULE_LIBRARY &&
-     this->GetType() != cmTarget::EXECUTABLE)
-    {
-    outPrefix = "";
-    outBase = this->GetName();
-    outSuffix = "";
-    return;
-    }
-
-  // Return an empty name for the import library if this platform
-  // does not support import libraries.
-  if(implib &&
-     !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
-    {
-    outPrefix = "";
-    outBase = "";
-    outSuffix = "";
-    return;
-    }
-
-  // The implib option is only allowed for shared libraries, module
-  // libraries, and executables.
-  if(this->GetType() != cmTarget::SHARED_LIBRARY &&
-     this->GetType() != cmTarget::MODULE_LIBRARY &&
-     this->GetType() != cmTarget::EXECUTABLE)
-    {
-    implib = false;
-    }
-
-  // Compute the full name for main target types.
-  const char* targetPrefix = (implib
-                              ? this->GetProperty("IMPORT_PREFIX")
-                              : this->GetProperty("PREFIX"));
-  const char* targetSuffix = (implib
-                              ? this->GetProperty("IMPORT_SUFFIX")
-                              : this->GetProperty("SUFFIX"));
-  const char* configPostfix = 0;
-  if(!config.empty())
-    {
-    std::string configProp = cmSystemTools::UpperCase(config);
-    configProp += "_POSTFIX";
-    configPostfix = this->GetProperty(configProp);
-    // Mac application bundles and frameworks have no postfix.
-    if(configPostfix &&
-       (this->IsAppBundleOnApple() || this->IsFrameworkOnApple()))
-      {
-      configPostfix = 0;
-      }
-    }
-  const char* prefixVar = this->GetPrefixVariableInternal(implib);
-  const char* suffixVar = this->GetSuffixVariableInternal(implib);
-
-  // Check for language-specific default prefix and suffix.
-  std::string ll = this->GetLinkerLanguage(config);
-  if(!ll.empty())
-    {
-    if(!targetSuffix && suffixVar && *suffixVar)
-      {
-      std::string langSuff = suffixVar + std::string("_") + ll;
-      targetSuffix = this->Makefile->GetDefinition(langSuff);
-      }
-    if(!targetPrefix && prefixVar && *prefixVar)
-      {
-      std::string langPrefix = prefixVar + std::string("_") + ll;
-      targetPrefix = this->Makefile->GetDefinition(langPrefix);
-      }
-    }
-
-  // if there is no prefix on the target use the cmake definition
-  if(!targetPrefix && prefixVar)
-    {
-    targetPrefix = this->Makefile->GetSafeDefinition(prefixVar);
-    }
-  // if there is no suffix on the target use the cmake definition
-  if(!targetSuffix && suffixVar)
-    {
-    targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
-    }
-
-  // frameworks have directory prefix but no suffix
-  std::string fw_prefix;
-  if(this->IsFrameworkOnApple())
-    {
-    fw_prefix = this->GetOutputName(config, false);
-    fw_prefix += ".framework/";
-    targetPrefix = fw_prefix.c_str();
-    targetSuffix = 0;
-    }
-
-  if(this->IsCFBundleOnApple())
-    {
-    fw_prefix = this->GetCFBundleDirectory(config, false);
-    fw_prefix += "/";
-    targetPrefix = fw_prefix.c_str();
-    targetSuffix = 0;
-    }
-
-  // Begin the final name with the prefix.
-  outPrefix = targetPrefix?targetPrefix:"";
-
-  // Append the target name or property-specified name.
-  outBase += this->GetOutputName(config, implib);
-
-  // Append the per-configuration postfix.
-  outBase += configPostfix?configPostfix:"";
-
-  // Name shared libraries with their version number on some platforms.
-  if(const char* soversion = this->GetProperty("SOVERSION"))
-    {
-    if(this->GetType() == cmTarget::SHARED_LIBRARY && !implib &&
-       this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION"))
-      {
-      outBase += "-";
-      outBase += soversion;
-      }
-    }
-
-  // Append the suffix.
-  outSuffix = targetSuffix?targetSuffix:"";
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetLibraryNames(std::string& name,
-                               std::string& soName,
-                               std::string& realName,
-                               std::string& impName,
-                               std::string& pdbName,
-                               const std::string& config) const
-{
-  // This should not be called for imported targets.
-  // TODO: Split cmTarget into a class hierarchy to get compile-time
-  // enforcement of the limited imported target API.
-  if(this->IsImported())
-    {
-    std::string msg =  "GetLibraryNames called on imported target: ";
-    msg += this->GetName();
-    this->Makefile->IssueMessage(cmake::INTERNAL_ERROR,
-                                 msg);
-    return;
-    }
-
-  assert(this->GetType() != INTERFACE_LIBRARY);
-
-  // Check for library version properties.
-  const char* version = this->GetProperty("VERSION");
-  const char* soversion = this->GetProperty("SOVERSION");
-  if(!this->HasSOName(config) ||
-     this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") ||
-     this->IsFrameworkOnApple())
-    {
-    // Versioning is supported only for shared libraries and modules,
-    // and then only when the platform supports an soname flag.
-    version = 0;
-    soversion = 0;
-    }
-  if(version && !soversion)
-    {
-    // The soversion must be set if the library version is set.  Use
-    // the library version as the soversion.
-    soversion = version;
-    }
-  if(!version && soversion)
-    {
-    // Use the soversion as the library version.
-    version = soversion;
-    }
-
-  // Get the components of the library name.
-  std::string prefix;
-  std::string base;
-  std::string suffix;
-  this->GetFullNameInternal(config, false, prefix, base, suffix);
-
-  // The library name.
-  name = prefix+base+suffix;
-
-  if(this->IsFrameworkOnApple())
-    {
-    realName = prefix;
-    realName += "Versions/";
-    realName += this->GetFrameworkVersion();
-    realName += "/";
-    realName += base;
-    soName = realName;
-    }
-  else
-    {
-    // The library's soname.
-    this->ComputeVersionedName(soName, prefix, base, suffix,
-                               name, soversion);
-    // The library's real name on disk.
-    this->ComputeVersionedName(realName, prefix, base, suffix,
-                               name, version);
-    }
-
-  // The import library name.
-  if(this->GetType() == cmTarget::SHARED_LIBRARY ||
-     this->GetType() == cmTarget::MODULE_LIBRARY)
-    {
-    impName = this->GetFullNameInternal(config, true);
-    }
-  else
-    {
-    impName = "";
-    }
-
-  // The program database file name.
-  pdbName = this->GetPDBName(config);
-}
-
-//----------------------------------------------------------------------------
 void cmTarget::ComputeVersionedName(std::string& vName,
                                     std::string const& prefix,
                                     std::string const& base,
@@ -4150,68 +2742,6 @@ void cmTarget::ComputeVersionedName(std::string& vName,
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetExecutableNames(std::string& name,
-                                  std::string& realName,
-                                  std::string& impName,
-                                  std::string& pdbName,
-                                  const std::string& config) const
-{
-  // This should not be called for imported targets.
-  // TODO: Split cmTarget into a class hierarchy to get compile-time
-  // enforcement of the limited imported target API.
-  if(this->IsImported())
-    {
-    std::string msg =
-      "GetExecutableNames called on imported target: ";
-    msg += this->GetName();
-    this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, msg);
-    }
-
-  // This versioning is supported only for executables and then only
-  // when the platform supports symbolic links.
-#if defined(_WIN32) && !defined(__CYGWIN__)
-  const char* version = 0;
-#else
-  // Check for executable version properties.
-  const char* version = this->GetProperty("VERSION");
-  if(this->GetType() != cmTarget::EXECUTABLE || this->Makefile->IsOn("XCODE"))
-    {
-    version = 0;
-    }
-#endif
-
-  // Get the components of the executable name.
-  std::string prefix;
-  std::string base;
-  std::string suffix;
-  this->GetFullNameInternal(config, false, prefix, base, suffix);
-
-  // The executable name.
-  name = prefix+base+suffix;
-
-  // The executable's real name on disk.
-#if defined(__CYGWIN__)
-  realName = prefix+base;
-#else
-  realName = name;
-#endif
-  if(version)
-    {
-    realName += "-";
-    realName += version;
-    }
-#if defined(__CYGWIN__)
-  realName += suffix;
-#endif
-
-  // The import library name.
-  impName = this->GetFullNameInternal(config, true);
-
-  // The program database file name.
-  pdbName = this->GetPDBName(config);
-}
-
-//----------------------------------------------------------------------------
 bool cmTarget::HasImplibGNUtoMS() const
 {
   return this->HasImportLibrary() && this->GetPropertyAsBool("GNUtoMS");
@@ -4250,21 +2780,6 @@ void cmTarget::SetPropertyDefault(const std::string& property,
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::HaveBuildTreeRPATH(const std::string& config) const
-{
-  if (this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
-    {
-    return false;
-    }
-  if(LinkImplementationLibraries const* impl =
-     this->GetLinkImplementationLibraries(config))
-    {
-    return !impl->Libraries.empty();
-    }
-  return false;
-}
-
-//----------------------------------------------------------------------------
 bool cmTarget::HaveInstallTreeRPATH() const
 {
   const char* install_rpath = this->GetProperty("INSTALL_RPATH");
@@ -4273,137 +2788,6 @@ bool cmTarget::HaveInstallTreeRPATH() const
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::NeedRelinkBeforeInstall(const std::string& config) const
-{
-  // Only executables and shared libraries can have an rpath and may
-  // need relinking.
-  if(this->TargetTypeValue != cmTarget::EXECUTABLE &&
-     this->TargetTypeValue != cmTarget::SHARED_LIBRARY &&
-     this->TargetTypeValue != cmTarget::MODULE_LIBRARY)
-    {
-    return false;
-    }
-
-  // If there is no install location this target will not be installed
-  // and therefore does not need relinking.
-  if(!this->GetHaveInstallRule())
-    {
-    return false;
-    }
-
-  // If skipping all rpaths completely then no relinking is needed.
-  if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
-    {
-    return false;
-    }
-
-  // If building with the install-tree rpath no relinking is needed.
-  if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
-    {
-    return false;
-    }
-
-  // If chrpath is going to be used no relinking is needed.
-  if(this->IsChrpathUsed(config))
-    {
-    return false;
-    }
-
-  // Check for rpath support on this platform.
-  std::string ll = this->GetLinkerLanguage(config);
-  if(!ll.empty())
-    {
-    std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
-    flagVar += ll;
-    flagVar += "_FLAG";
-    if(!this->Makefile->IsSet(flagVar))
-      {
-      // There is no rpath support on this platform so nothing needs
-      // relinking.
-      return false;
-      }
-    }
-  else
-    {
-    // No linker language is known.  This error will be reported by
-    // other code.
-    return false;
-    }
-
-  // If either a build or install tree rpath is set then the rpath
-  // will likely change between the build tree and install tree and
-  // this target must be relinked.
-  return this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH();
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetInstallNameDirForBuildTree(
-    const std::string& config) const
-{
-  // If building directly for installation then the build tree install_name
-  // is the same as the install tree.
-  if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
-    {
-    return GetInstallNameDirForInstallTree();
-    }
-
-  // Use the build tree directory for the target.
-  if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
-     !this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
-     !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
-    {
-    std::string dir;
-    bool macosx_rpath = this->MacOSXRpathInstallNameDirDefault();
-    if(macosx_rpath)
-      {
-      dir = "@rpath";
-      }
-    else
-      {
-      dir = this->GetDirectory(config);
-      }
-    dir += "/";
-    return dir;
-    }
-  else
-    {
-    return "";
-    }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetInstallNameDirForInstallTree() const
-{
-  if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
-    {
-    std::string dir;
-    const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
-
-    if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
-       !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"))
-      {
-      if(install_name_dir && *install_name_dir)
-        {
-        dir = install_name_dir;
-        dir += "/";
-        }
-      }
-    if(!install_name_dir)
-      {
-      if(this->MacOSXRpathInstallNameDirDefault())
-        {
-        dir = "@rpath/";
-        }
-      }
-    return dir;
-    }
-  else
-    {
-    return "";
-    }
-}
-
-//----------------------------------------------------------------------------
 const char* cmTarget::GetOutputTargetType(bool implib) const
 {
   switch(this->GetType())
@@ -4492,7 +2876,10 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
   if(const char* config_outdir = this->GetProperty(configProp))
     {
     // Use the user-specified per-configuration output directory.
-    out = config_outdir;
+    cmGeneratorExpression ge;
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+      ge.Parse(config_outdir);
+    out = cge->Evaluate(this->Makefile, config);
 
     // Skip per-configuration subdirectory.
     conf = "";
@@ -4500,7 +2887,17 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
   else if(const char* outdir = this->GetProperty(propertyName))
     {
     // Use the user-specified output directory.
-    out = outdir;
+    cmGeneratorExpression ge;
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+      ge.Parse(outdir);
+    out = cge->Evaluate(this->Makefile, config);
+
+    // Skip per-configuration subdirectory if the value contained a
+    // generator expression.
+    if (out != outdir)
+      {
+      conf = "";
+      }
     }
   else if(this->GetType() == cmTarget::EXECUTABLE)
     {
@@ -4530,10 +2927,9 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
   // The generator may add the configuration's subdirectory.
   if(!conf.empty())
     {
-    const char *platforms = this->Makefile->GetDefinition(
-      "CMAKE_XCODE_EFFECTIVE_PLATFORMS");
+    bool iosPlatform = this->Makefile->PlatformIsAppleIos();
     std::string suffix =
-      usesDefaultOutputDir && platforms ? "$(EFFECTIVE_PLATFORM_NAME)" : "";
+      usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : "";
     this->Makefile->GetGlobalGenerator()->
       AppendDirectoryForConfig("/", conf, suffix, out);
     }
@@ -4611,44 +3007,6 @@ bool cmTarget::UsesDefaultOutputDir(const std::string& config,
 }
 
 //----------------------------------------------------------------------------
-std::string cmTarget::GetOutputName(const std::string& config,
-                                    bool implib) const
-{
-  std::vector<std::string> props;
-  std::string type = this->GetOutputTargetType(implib);
-  std::string configUpper = cmSystemTools::UpperCase(config);
-  if(!type.empty() && !configUpper.empty())
-    {
-    // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG>
-    props.push_back(type + "_OUTPUT_NAME_" + configUpper);
-    }
-  if(!type.empty())
-    {
-    // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME
-    props.push_back(type + "_OUTPUT_NAME");
-    }
-  if(!configUpper.empty())
-    {
-    // OUTPUT_NAME_<CONFIG>
-    props.push_back("OUTPUT_NAME_" + configUpper);
-    // <CONFIG>_OUTPUT_NAME
-    props.push_back(configUpper + "_OUTPUT_NAME");
-    }
-  // OUTPUT_NAME
-  props.push_back("OUTPUT_NAME");
-
-  for(std::vector<std::string>::const_iterator i = props.begin();
-      i != props.end(); ++i)
-    {
-    if(const char* outName = this->GetProperty(*i))
-      {
-      return outName;
-      }
-    }
-  return this->GetName();
-}
-
-//----------------------------------------------------------------------------
 std::string cmTarget::GetFrameworkVersion() const
 {
   assert(this->GetType() != INTERFACE_LIBRARY);
@@ -4694,656 +3052,51 @@ const char* cmTarget::GetExportMacro() const
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
-{
-  return this->LinkImplicitNullProperties.find(p)
-      != this->LinkImplicitNullProperties.end();
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop);
-
-//----------------------------------------------------------------------------
-template<>
-bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop)
-{
-  return tgt->GetPropertyAsBool(prop);
-}
-
-//----------------------------------------------------------------------------
-template<>
-const char *getTypedProperty<const char *>(cmTarget const* tgt,
-                                           const std::string& prop)
-{
-  return tgt->GetProperty(prop);
-}
-
-enum CompatibleType
-{
-  BoolType,
-  StringType,
-  NumberMinType,
-  NumberMaxType
-};
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
-                                                 PropertyType rhs,
-                                                 CompatibleType t);
-
-//----------------------------------------------------------------------------
-template<>
-std::pair<bool, bool> consistentProperty(bool lhs, bool rhs, CompatibleType)
-{
-  return std::make_pair(lhs == rhs, lhs);
-}
-
-//----------------------------------------------------------------------------
-std::pair<bool, const char*> consistentStringProperty(const char *lhs,
-                                                      const char *rhs)
-{
-  const bool b = strcmp(lhs, rhs) == 0;
-  return std::make_pair(b, b ? lhs : 0);
-}
-
-//----------------------------------------------------------------------------
-std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
-                                                      const char *rhs,
-                                                      CompatibleType t)
-{
-  char *pEnd;
-
-  const char* const null_ptr = 0;
-
-  long lnum = strtol(lhs, &pEnd, 0);
-  if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
-    {
-    return std::pair<bool, const char*>(false, null_ptr);
-    }
-
-  long rnum = strtol(rhs, &pEnd, 0);
-  if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
-    {
-    return std::pair<bool, const char*>(false, null_ptr);
-    }
-
-  if (t == NumberMaxType)
-    {
-    return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
-    }
-  else
-    {
-    return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs);
-    }
-}
-
-//----------------------------------------------------------------------------
-template<>
-std::pair<bool, const char*> consistentProperty(const char *lhs,
-                                                const char *rhs,
-                                                CompatibleType t)
-{
-  if (!lhs && !rhs)
-    {
-    return std::make_pair(true, lhs);
-    }
-  if (!lhs)
-    {
-    return std::make_pair(true, rhs);
-    }
-  if (!rhs)
-    {
-    return std::make_pair(true, lhs);
-    }
-
-  const char* const null_ptr = 0;
-
-  switch(t)
-  {
-  case BoolType:
-    assert(0 && "consistentProperty for strings called with BoolType");
-    return std::pair<bool, const char*>(false, null_ptr);
-  case StringType:
-    return consistentStringProperty(lhs, rhs);
-  case NumberMinType:
-  case NumberMaxType:
-    return consistentNumberProperty(lhs, rhs, t);
-  }
-  assert(0 && "Unreachable!");
-  return std::pair<bool, const char*>(false, null_ptr);
-}
-
-template<typename PropertyType>
-PropertyType impliedValue(PropertyType);
-template<>
-bool impliedValue<bool>(bool)
-{
-  return false;
-}
-template<>
-const char* impliedValue<const char*>(const char*)
-{
-  return "";
-}
-
-
-template<typename PropertyType>
-std::string valueAsString(PropertyType);
-template<>
-std::string valueAsString<bool>(bool value)
-{
-  return value ? "TRUE" : "FALSE";
-}
-template<>
-std::string valueAsString<const char*>(const char* value)
-{
-  return value ? value : "(unset)";
-}
-
-//----------------------------------------------------------------------------
-void
-cmTarget::ReportPropertyOrigin(const std::string &p,
-                               const std::string &result,
-                               const std::string &report,
-                               const std::string &compatibilityType) const
-{
-  std::vector<std::string> debugProperties;
-  const char *debugProp =
-          this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp)
-    {
-    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
-    }
-
-  bool debugOrigin = !this->DebugCompatiblePropertiesDone[p]
-                    && std::find(debugProperties.begin(),
-                                 debugProperties.end(),
-                                 p)
-                        != debugProperties.end();
-
-  if (this->Makefile->IsGeneratingBuildSystem())
-    {
-    this->DebugCompatiblePropertiesDone[p] = true;
-    }
-  if (!debugOrigin)
-    {
-    return;
-    }
-
-  std::string areport = compatibilityType;
-  areport += std::string(" of property \"") + p + "\" for target \"";
-  areport += std::string(this->GetName());
-  areport += "\" (result: \"";
-  areport += result;
-  areport += "\"):\n" + report;
-
-  this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
-}
-
-//----------------------------------------------------------------------------
-std::string compatibilityType(CompatibleType t)
-{
-  switch(t)
-    {
-    case BoolType:
-      return "Boolean compatibility";
-    case StringType:
-      return "String compatibility";
-    case NumberMaxType:
-      return "Numeric maximum compatibility";
-    case NumberMinType:
-      return "Numeric minimum compatibility";
-    }
-  assert(0 && "Unreachable!");
-  return "";
-}
-
-//----------------------------------------------------------------------------
-std::string compatibilityAgree(CompatibleType t, bool dominant)
-{
-  switch(t)
-    {
-    case BoolType:
-    case StringType:
-      return dominant ? "(Disagree)\n" : "(Agree)\n";
-    case NumberMaxType:
-    case NumberMinType:
-      return dominant ? "(Dominant)\n" : "(Ignored)\n";
-    }
-  assert(0 && "Unreachable!");
-  return "";
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
-                                          const std::string &p,
-                                          const std::string& config,
-                                          const char *defaultValue,
-                                          CompatibleType t,
-                                          PropertyType *)
-{
-  PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
-  const bool explicitlySet = tgt->GetProperties()
-                                  .find(p)
-                                  != tgt->GetProperties().end();
-  const bool impliedByUse =
-          tgt->IsNullImpliedByLinkLibraries(p);
-  assert((impliedByUse ^ explicitlySet)
-      || (!impliedByUse && !explicitlySet));
-
-  std::vector<cmTarget const*> const& deps =
-    tgt->GetLinkImplementationClosure(config);
-
-  if(deps.empty())
-    {
-    return propContent;
-    }
-  bool propInitialized = explicitlySet;
-
-  std::string report = " * Target \"";
-  report += tgt->GetName();
-  if (explicitlySet)
-    {
-    report += "\" has property content \"";
-    report += valueAsString<PropertyType>(propContent);
-    report += "\"\n";
-    }
-  else if (impliedByUse)
-    {
-    report += "\" property is implied by use.\n";
-    }
-  else
-    {
-    report += "\" property not set.\n";
-    }
-
-  std::string interfaceProperty = "INTERFACE_" + p;
-  for(std::vector<cmTarget const*>::const_iterator li =
-      deps.begin();
-      li != deps.end(); ++li)
-    {
-    // An error should be reported if one dependency
-    // has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other
-    // has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the
-    // target itself has a POSITION_INDEPENDENT_CODE which disagrees
-    // with a dependency.
-
-    cmTarget const* theTarget = *li;
-
-    const bool ifaceIsSet = theTarget->GetProperties()
-                            .find(interfaceProperty)
-                            != theTarget->GetProperties().end();
-    PropertyType ifacePropContent =
-                    getTypedProperty<PropertyType>(theTarget,
-                              interfaceProperty);
-
-    std::string reportEntry;
-    if (ifaceIsSet)
-      {
-      reportEntry += " * Target \"";
-      reportEntry += theTarget->GetName();
-      reportEntry += "\" property value \"";
-      reportEntry += valueAsString<PropertyType>(ifacePropContent);
-      reportEntry += "\" ";
-      }
-
-    if (explicitlySet)
-      {
-      if (ifaceIsSet)
-        {
-        std::pair<bool, PropertyType> consistent =
-                                  consistentProperty(propContent,
-                                                     ifacePropContent, t);
-        report += reportEntry;
-        report += compatibilityAgree(t, propContent != consistent.second);
-        if (!consistent.first)
-          {
-          std::ostringstream e;
-          e << "Property " << p << " on target \""
-            << tgt->GetName() << "\" does\nnot match the "
-            "INTERFACE_" << p << " property requirement\nof "
-            "dependency \"" << theTarget->GetName() << "\".\n";
-          cmSystemTools::Error(e.str().c_str());
-          break;
-          }
-        else
-          {
-          propContent = consistent.second;
-          continue;
-          }
-        }
-      else
-        {
-        // Explicitly set on target and not set in iface. Can't disagree.
-        continue;
-        }
-      }
-    else if (impliedByUse)
-      {
-      propContent = impliedValue<PropertyType>(propContent);
-
-      if (ifaceIsSet)
-        {
-        std::pair<bool, PropertyType> consistent =
-                                  consistentProperty(propContent,
-                                                     ifacePropContent, t);
-        report += reportEntry;
-        report += compatibilityAgree(t, propContent != consistent.second);
-        if (!consistent.first)
-          {
-          std::ostringstream e;
-          e << "Property " << p << " on target \""
-            << tgt->GetName() << "\" is\nimplied to be " << defaultValue
-            << " because it was used to determine the link libraries\n"
-               "already. The INTERFACE_" << p << " property on\ndependency \""
-            << theTarget->GetName() << "\" is in conflict.\n";
-          cmSystemTools::Error(e.str().c_str());
-          break;
-          }
-        else
-          {
-          propContent = consistent.second;
-          continue;
-          }
-        }
-      else
-        {
-        // Implicitly set on target and not set in iface. Can't disagree.
-        continue;
-        }
-      }
-    else
-      {
-      if (ifaceIsSet)
-        {
-        if (propInitialized)
-          {
-          std::pair<bool, PropertyType> consistent =
-                                    consistentProperty(propContent,
-                                                       ifacePropContent, t);
-          report += reportEntry;
-          report += compatibilityAgree(t, propContent != consistent.second);
-          if (!consistent.first)
-            {
-            std::ostringstream e;
-            e << "The INTERFACE_" << p << " property of \""
-              << theTarget->GetName() << "\" does\nnot agree with the value "
-                "of " << p << " already determined\nfor \""
-              << tgt->GetName() << "\".\n";
-            cmSystemTools::Error(e.str().c_str());
-            break;
-            }
-          else
-            {
-            propContent = consistent.second;
-            continue;
-            }
-          }
-        else
-          {
-          report += reportEntry + "(Interface set)\n";
-          propContent = ifacePropContent;
-          propInitialized = true;
-          }
-        }
-      else
-        {
-        // Not set. Nothing to agree on.
-        continue;
-        }
-      }
-    }
-
-  tgt->ReportPropertyOrigin(p, valueAsString<PropertyType>(propContent),
-                            report, compatibilityType(t));
-  return propContent;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
-                                              const std::string& config) const
-{
-  return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE",
-                                                   BoolType, 0);
-}
-
-//----------------------------------------------------------------------------
-const char * cmTarget::GetLinkInterfaceDependentStringProperty(
-                                              const std::string &p,
-                                              const std::string& config) const
-{
-  return checkInterfacePropertyCompatibility<const char *>(this,
-                                                           p,
-                                                           config,
-                                                           "empty",
-                                                           StringType, 0);
-}
-
-//----------------------------------------------------------------------------
-const char * cmTarget::GetLinkInterfaceDependentNumberMinProperty(
-                                              const std::string &p,
-                                              const std::string& config) const
-{
-  return checkInterfacePropertyCompatibility<const char *>(this,
-                                                           p,
-                                                           config,
-                                                           "empty",
-                                                           NumberMinType, 0);
-}
-
-//----------------------------------------------------------------------------
-const char * cmTarget::GetLinkInterfaceDependentNumberMaxProperty(
-                                              const std::string &p,
-                                              const std::string& config) const
-{
-  return checkInterfacePropertyCompatibility<const char *>(this,
-                                                           p,
-                                                           config,
-                                                           "empty",
-                                                           NumberMaxType, 0);
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
-                                           const std::string& config) const
-{
-  if (this->TargetTypeValue == OBJECT_LIBRARY
-      || this->TargetTypeValue == INTERFACE_LIBRARY)
-    {
-    return false;
-    }
-  return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
-                                    const std::string& config) const
-{
-  if (this->TargetTypeValue == OBJECT_LIBRARY
-      || this->TargetTypeValue == INTERFACE_LIBRARY)
-    {
-    return false;
-    }
-  return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
-                                    const std::string& config) const
-{
-  if (this->TargetTypeValue == OBJECT_LIBRARY
-      || this->TargetTypeValue == INTERFACE_LIBRARY)
-    {
-    return false;
-    }
-  return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
-                                    const std::string& config) const
-{
-  if (this->TargetTypeValue == OBJECT_LIBRARY
-      || this->TargetTypeValue == INTERFACE_LIBRARY)
-    {
-    return false;
-    }
-  return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
-}
-
-//----------------------------------------------------------------------------
-void
-cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
-{
-  // At configure-time, this method can be called as part of getting the
-  // LOCATION property or to export() a file to be include()d.  However
-  // there is no cmGeneratorTarget at configure-time, so search the SOURCES
-  // for TARGET_OBJECTS instead for backwards compatibility with OLD
-  // behavior of CMP0024 and CMP0026 only.
-  typedef cmTargetInternals::TargetPropertyEntry
-                              TargetPropertyEntry;
-  for(std::vector<TargetPropertyEntry*>::const_iterator
-        i = this->Internal->SourceEntries.begin();
-      i != this->Internal->SourceEntries.end(); ++i)
-    {
-    std::string entry = (*i)->ge->GetInput();
-
-    std::vector<std::string> files;
-    cmSystemTools::ExpandListArgument(entry, files);
-    for (std::vector<std::string>::const_iterator
-        li = files.begin(); li != files.end(); ++li)
-      {
-      if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
-          (*li)[li->size() - 1] == '>')
-        {
-        std::string objLibName = li->substr(17, li->size()-18);
-
-        if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
-          {
-          continue;
-          }
-        cmTarget *objLib = this->Makefile->FindTargetToUse(objLibName);
-        if(objLib)
-          {
-          objlibs.push_back(objLib);
-          }
-        }
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetLanguages(std::set<std::string>& languages,
-                            const std::string& config) const
-{
-  std::vector<cmSourceFile*> sourceFiles;
-  this->GetSourceFiles(sourceFiles, config);
-  for(std::vector<cmSourceFile*>::const_iterator
-        i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
-    {
-    const std::string& lang = (*i)->GetLanguage();
-    if(!lang.empty())
-      {
-      languages.insert(lang);
-      }
-    }
-
-  std::vector<cmTarget*> objectLibraries;
-  std::vector<cmSourceFile const*> externalObjects;
-  if (this->Makefile->GetGeneratorTargets().empty())
-    {
-    this->GetObjectLibrariesCMP0026(objectLibraries);
-    }
-  else
-    {
-    cmGeneratorTarget* gt = this->Makefile->GetGlobalGenerator()
-                                ->GetGeneratorTarget(this);
-    gt->GetExternalObjects(externalObjects, config);
-    for(std::vector<cmSourceFile const*>::const_iterator
-          i = externalObjects.begin(); i != externalObjects.end(); ++i)
-      {
-      std::string objLib = (*i)->GetObjectLibrary();
-      if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
-        {
-        objectLibraries.push_back(tgt);
-        }
-      }
-    }
-  for(std::vector<cmTarget*>::const_iterator
-      i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
-    {
-    (*i)->GetLanguages(languages, config);
-    }
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsChrpathUsed(const std::string& config) const
-{
-  // Only certain target types have an rpath.
-  if(!(this->GetType() == cmTarget::SHARED_LIBRARY ||
-       this->GetType() == cmTarget::MODULE_LIBRARY ||
-       this->GetType() == cmTarget::EXECUTABLE))
-    {
-    return false;
-    }
-
-  // If the target will not be installed we do not need to change its
-  // rpath.
-  if(!this->GetHaveInstallRule())
-    {
-    return false;
-    }
-
-  // Skip chrpath if skipping rpath altogether.
-  if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
-    {
-    return false;
-    }
-
-  // Skip chrpath if it does not need to be changed at install time.
-  if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
-    {
-    return false;
-    }
-
-  // Allow the user to disable builtin chrpath explicitly.
-  if(this->Makefile->IsOn("CMAKE_NO_BUILTIN_CHRPATH"))
-    {
-    return false;
-    }
+bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
+{
+  return this->LinkImplicitNullProperties.find(p)
+      != this->LinkImplicitNullProperties.end();
+}
 
-  if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+//----------------------------------------------------------------------------
+void
+cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
+{
+  // At configure-time, this method can be called as part of getting the
+  // LOCATION property or to export() a file to be include()d.  However
+  // there is no cmGeneratorTarget at configure-time, so search the SOURCES
+  // for TARGET_OBJECTS instead for backwards compatibility with OLD
+  // behavior of CMP0024 and CMP0026 only.
+  typedef cmTargetInternals::TargetPropertyEntry
+                              TargetPropertyEntry;
+  for(std::vector<TargetPropertyEntry*>::const_iterator
+        i = this->Internal->SourceEntries.begin();
+      i != this->Internal->SourceEntries.end(); ++i)
     {
-    return true;
-    }
+    std::string entry = (*i)->ge->GetInput();
 
-#if defined(CMAKE_USE_ELF_PARSER)
-  // Enable if the rpath flag uses a separator and the target uses ELF
-  // binaries.
-  std::string ll = this->GetLinkerLanguage(config);
-  if(!ll.empty())
-    {
-    std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
-    sepVar += ll;
-    sepVar += "_FLAG_SEP";
-    const char* sep = this->Makefile->GetDefinition(sepVar);
-    if(sep && *sep)
+    std::vector<std::string> files;
+    cmSystemTools::ExpandListArgument(entry, files);
+    for (std::vector<std::string>::const_iterator
+        li = files.begin(); li != files.end(); ++li)
       {
-      // TODO: Add ELF check to ABI detection and get rid of
-      // CMAKE_EXECUTABLE_FORMAT.
-      if(const char* fmt =
-         this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT"))
+      if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+          (*li)[li->size() - 1] == '>')
         {
-        return strcmp(fmt, "ELF") == 0;
+        std::string objLibName = li->substr(17, li->size()-18);
+
+        if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+          {
+          continue;
+          }
+        cmTarget *objLib = this->Makefile->FindTargetToUse(objLibName);
+        if(objLib)
+          {
+          objlibs.push_back(objLib);
+          }
         }
       }
     }
-#endif
-  static_cast<void>(config);
-  return false;
 }
 
 //----------------------------------------------------------------------------
@@ -5589,575 +3342,108 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
     impProp += suffix;
     if(const char* config_location = this->GetProperty(impProp))
       {
-      info.Location = config_location;
-      }
-    else if(const char* location = this->GetProperty("IMPORTED_LOCATION"))
-      {
-      info.Location = location;
-      }
-    }
-
-  // Get the soname.
-  if(this->GetType() == cmTarget::SHARED_LIBRARY)
-    {
-    std::string soProp = "IMPORTED_SONAME";
-    soProp += suffix;
-    if(const char* config_soname = this->GetProperty(soProp))
-      {
-      info.SOName = config_soname;
-      }
-    else if(const char* soname = this->GetProperty("IMPORTED_SONAME"))
-      {
-      info.SOName = soname;
-      }
-    }
-
-  // Get the "no-soname" mark.
-  if(this->GetType() == cmTarget::SHARED_LIBRARY)
-    {
-    std::string soProp = "IMPORTED_NO_SONAME";
-    soProp += suffix;
-    if(const char* config_no_soname = this->GetProperty(soProp))
-      {
-      info.NoSOName = cmSystemTools::IsOn(config_no_soname);
-      }
-    else if(const char* no_soname = this->GetProperty("IMPORTED_NO_SONAME"))
-      {
-      info.NoSOName = cmSystemTools::IsOn(no_soname);
-      }
-    }
-
-  // Get the import library.
-  if(imp)
-    {
-    info.ImportLibrary = imp;
-    }
-  else if(this->GetType() == cmTarget::SHARED_LIBRARY ||
-          this->IsExecutableWithExports())
-    {
-    std::string impProp = "IMPORTED_IMPLIB";
-    impProp += suffix;
-    if(const char* config_implib = this->GetProperty(impProp))
-      {
-      info.ImportLibrary = config_implib;
-      }
-    else if(const char* implib = this->GetProperty("IMPORTED_IMPLIB"))
-      {
-      info.ImportLibrary = implib;
-      }
-    }
-
-  // Get the link dependencies.
-  {
-  std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
-  linkProp += suffix;
-  if(const char* config_libs = this->GetProperty(linkProp))
-    {
-    info.SharedDeps = config_libs;
-    }
-  else if(const char* libs =
-          this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES"))
-    {
-    info.SharedDeps = libs;
-    }
-  }
-
-  // Get the link languages.
-  if(this->LinkLanguagePropagatesToDependents())
-    {
-    std::string linkProp = "IMPORTED_LINK_INTERFACE_LANGUAGES";
-    linkProp += suffix;
-    if(const char* config_libs = this->GetProperty(linkProp))
-      {
-      info.Languages = config_libs;
-      }
-    else if(const char* libs =
-            this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES"))
-      {
-      info.Languages = libs;
-      }
-    }
-
-  // Get the cyclic repetition count.
-  if(this->GetType() == cmTarget::STATIC_LIBRARY)
-    {
-    std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
-    linkProp += suffix;
-    if(const char* config_reps = this->GetProperty(linkProp))
-      {
-      sscanf(config_reps, "%u", &info.Multiplicity);
-      }
-    else if(const char* reps =
-            this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY"))
-      {
-      sscanf(reps, "%u", &info.Multiplicity);
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
-                                                  const std::string& config,
-                                                  cmTarget const* head) const
-{
-  // Imported targets have their own link interface.
-  if(this->IsImported())
-    {
-    return this->GetImportLinkInterface(config, head, false);
-    }
-
-  // Link interfaces are not supported for executables that do not
-  // export symbols.
-  if(this->GetType() == cmTarget::EXECUTABLE &&
-     !this->IsExecutableWithExports())
-    {
-    return 0;
-    }
-
-  // Lookup any existing link interface for this configuration.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::HeadToLinkInterfaceMap& hm =
-    this->Internal->LinkInterfaceMap[CONFIG];
-
-  // If the link interface does not depend on the head target
-  // then return the one we computed first.
-  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
-    {
-    return &hm.begin()->second;
-    }
-
-  cmTargetInternals::OptionalLinkInterface& iface = hm[head];
-  if(!iface.LibrariesDone)
-    {
-    iface.LibrariesDone = true;
-    this->Internal->ComputeLinkInterfaceLibraries(
-      this, config, iface, head, false);
-    }
-  if(!iface.AllDone)
-    {
-    iface.AllDone = true;
-    if(iface.Exists)
-      {
-      this->Internal->ComputeLinkInterface(this, config, iface, head);
-      }
-    }
-
-  return iface.Exists? &iface : 0;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkInterfaceLibraries const*
-cmTarget::GetLinkInterfaceLibraries(const std::string& config,
-                                    cmTarget const* head,
-                                    bool usage_requirements_only) const
-{
-  // Imported targets have their own link interface.
-  if(this->IsImported())
-    {
-    return this->GetImportLinkInterface(config, head, usage_requirements_only);
-    }
-
-  // Link interfaces are not supported for executables that do not
-  // export symbols.
-  if(this->GetType() == cmTarget::EXECUTABLE &&
-     !this->IsExecutableWithExports())
-    {
-    return 0;
-    }
-
-  // Lookup any existing link interface for this configuration.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::HeadToLinkInterfaceMap& hm =
-    (usage_requirements_only ?
-     this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
-     this->Internal->LinkInterfaceMap[CONFIG]);
-
-  // If the link interface does not depend on the head target
-  // then return the one we computed first.
-  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
-    {
-    return &hm.begin()->second;
-    }
-
-  cmTargetInternals::OptionalLinkInterface& iface = hm[head];
-  if(!iface.LibrariesDone)
-    {
-    iface.LibrariesDone = true;
-    this->Internal->ComputeLinkInterfaceLibraries(
-      this, config, iface, head, usage_requirements_only);
-    }
-
-  return iface.Exists? &iface : 0;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkInterface const*
-cmTarget::GetImportLinkInterface(const std::string& config,
-                                 cmTarget const* headTarget,
-                                 bool usage_requirements_only) const
-{
-  cmTarget::ImportInfo const* info = this->GetImportInfo(config);
-  if(!info)
-    {
-    return 0;
-    }
-
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::HeadToLinkInterfaceMap& hm =
-    (usage_requirements_only ?
-     this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
-     this->Internal->LinkInterfaceMap[CONFIG]);
-
-  // If the link interface does not depend on the head target
-  // then return the one we computed first.
-  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
-    {
-    return &hm.begin()->second;
-    }
-
-  cmTargetInternals::OptionalLinkInterface& iface = hm[headTarget];
-  if(!iface.AllDone)
-    {
-    iface.AllDone = true;
-    iface.Multiplicity = info->Multiplicity;
-    cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
-    this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
-                          headTarget, usage_requirements_only,
-                          iface.Libraries,
-                          iface.HadHeadSensitiveCondition);
-    std::vector<std::string> deps;
-    cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
-    this->LookupLinkItems(deps, iface.SharedDeps);
-    }
-
-  return &iface;
-}
-
-//----------------------------------------------------------------------------
-void processILibs(const std::string& config,
-                  cmTarget const* headTarget,
-                  cmLinkItem const& item,
-                  std::vector<cmTarget const*>& tgts,
-                  std::set<cmTarget const*>& emitted)
-{
-  if (item.Target && emitted.insert(item.Target).second)
-    {
-    tgts.push_back(item.Target);
-    if(cmTarget::LinkInterfaceLibraries const* iface =
-       item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
-      {
-      for(std::vector<cmLinkItem>::const_iterator
-            it = iface->Libraries.begin();
-          it != iface->Libraries.end(); ++it)
-        {
-        processILibs(config, headTarget, *it, tgts, emitted);
-        }
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-std::vector<cmTarget const*> const&
-cmTarget::GetLinkImplementationClosure(const std::string& config) const
-{
-  cmTargetInternals::LinkImplClosure& tgts =
-    this->Internal->LinkImplClosureMap[config];
-  if(!tgts.Done)
-    {
-    tgts.Done = true;
-    std::set<cmTarget const*> emitted;
-
-    cmTarget::LinkImplementationLibraries const* impl
-      = this->GetLinkImplementationLibraries(config);
-
-    for(std::vector<cmLinkImplItem>::const_iterator
-          it = impl->Libraries.begin();
-        it != impl->Libraries.end(); ++it)
-      {
-      processILibs(config, this, *it, tgts , emitted);
-      }
-    }
-  return tgts;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::CompatibleInterfaces const&
-cmTarget::GetCompatibleInterfaces(std::string const& config) const
-{
-  cmTargetInternals::CompatibleInterfaces& compat =
-    this->Internal->CompatibleInterfacesMap[config];
-  if(!compat.Done)
-    {
-    compat.Done = true;
-    compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
-    compat.PropsString.insert("AUTOUIC_OPTIONS");
-    std::vector<cmTarget const*> const& deps =
-      this->GetLinkImplementationClosure(config);
-    for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
-        li != deps.end(); ++li)
-      {
-#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
-      if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \
-        { \
-        std::vector<std::string> props; \
-        cmSystemTools::ExpandListArgument(prop, props); \
-        compat.Props##x.insert(props.begin(), props.end()); \
-        }
-      CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
-      CM_READ_COMPATIBLE_INTERFACE(STRING, String)
-      CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin)
-      CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax)
-#undef CM_READ_COMPATIBLE_INTERFACE
-      }
-    }
-  return compat;
-}
-
-//----------------------------------------------------------------------------
-void
-cmTargetInternals::ComputeLinkInterfaceLibraries(
-  cmTarget const* thisTarget,
-  const std::string& config,
-  OptionalLinkInterface& iface,
-  cmTarget const* headTarget,
-  bool usage_requirements_only)
-{
-  // Construct the property name suffix for this configuration.
-  std::string suffix = "_";
-  if(!config.empty())
-    {
-    suffix += cmSystemTools::UpperCase(config);
-    }
-  else
-    {
-    suffix += "NOCONFIG";
+      info.Location = config_location;
+      }
+    else if(const char* location = this->GetProperty("IMPORTED_LOCATION"))
+      {
+      info.Location = location;
+      }
     }
 
-  // An explicit list of interface libraries may be set for shared
-  // libraries and executables that export symbols.
-  const char* explicitLibraries = 0;
-  std::string linkIfaceProp;
-  if(thisTarget->PolicyStatusCMP0022 != cmPolicies::OLD &&
-     thisTarget->PolicyStatusCMP0022 != cmPolicies::WARN)
-    {
-    // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
-    linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
-    explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
-    }
-  else if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY ||
-          thisTarget->IsExecutableWithExports())
+  // Get the soname.
+  if(this->GetType() == cmTarget::SHARED_LIBRARY)
     {
-    // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
-    // shared lib or executable.
-
-    // Lookup the per-configuration property.
-    linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
-    linkIfaceProp += suffix;
-    explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
-
-    // If not set, try the generic property.
-    if(!explicitLibraries)
+    std::string soProp = "IMPORTED_SONAME";
+    soProp += suffix;
+    if(const char* config_soname = this->GetProperty(soProp))
+      {
+      info.SOName = config_soname;
+      }
+    else if(const char* soname = this->GetProperty("IMPORTED_SONAME"))
       {
-      linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
-      explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
+      info.SOName = soname;
       }
     }
 
-  if(explicitLibraries &&
-     thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN &&
-     !this->PolicyWarnedCMP0022)
+  // Get the "no-soname" mark.
+  if(this->GetType() == cmTarget::SHARED_LIBRARY)
     {
-    // Compare the explicitly set old link interface properties to the
-    // preferred new link interface property one and warn if different.
-    const char* newExplicitLibraries =
-      thisTarget->GetProperty("INTERFACE_LINK_LIBRARIES");
-    if (newExplicitLibraries
-        && strcmp(newExplicitLibraries, explicitLibraries) != 0)
+    std::string soProp = "IMPORTED_NO_SONAME";
+    soProp += suffix;
+    if(const char* config_no_soname = this->GetProperty(soProp))
+      {
+      info.NoSOName = cmSystemTools::IsOn(config_no_soname);
+      }
+    else if(const char* no_soname = this->GetProperty("IMPORTED_NO_SONAME"))
       {
-      std::ostringstream w;
-      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
-        "Target \"" << thisTarget->GetName() << "\" has an "
-        "INTERFACE_LINK_LIBRARIES property which differs from its " <<
-        linkIfaceProp << " properties."
-        "\n"
-        "INTERFACE_LINK_LIBRARIES:\n"
-        "  " << newExplicitLibraries << "\n" <<
-        linkIfaceProp << ":\n"
-        "  " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
-      thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
-      this->PolicyWarnedCMP0022 = true;
+      info.NoSOName = cmSystemTools::IsOn(no_soname);
       }
     }
 
-  // There is no implicit link interface for executables or modules
-  // so if none was explicitly set then there is no link interface.
-  if(!explicitLibraries &&
-     (thisTarget->GetType() == cmTarget::EXECUTABLE ||
-      (thisTarget->GetType() == cmTarget::MODULE_LIBRARY)))
+  // Get the import library.
+  if(imp)
     {
-    return;
+    info.ImportLibrary = imp;
     }
-  iface.Exists = true;
-  iface.ExplicitLibraries = explicitLibraries;
-
-  if(explicitLibraries)
-    {
-    // The interface libraries have been explicitly set.
-    thisTarget->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
-                                headTarget, usage_requirements_only,
-                                iface.Libraries,
-                                iface.HadHeadSensitiveCondition);
-    }
-  else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN
-        || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD)
-    // If CMP0022 is NEW then the plain tll signature sets the
-    // INTERFACE_LINK_LIBRARIES, so if we get here then the project
-    // cleared the property explicitly and we should not fall back
-    // to the link implementation.
-    {
-    // The link implementation is the default link interface.
-    cmTarget::LinkImplementationLibraries const* impl =
-      thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget);
-    iface.Libraries.insert(iface.Libraries.end(),
-                           impl->Libraries.begin(), impl->Libraries.end());
-    if(thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN &&
-       !this->PolicyWarnedCMP0022 && !usage_requirements_only)
+  else if(this->GetType() == cmTarget::SHARED_LIBRARY ||
+          this->IsExecutableWithExports())
+    {
+    std::string impProp = "IMPORTED_IMPLIB";
+    impProp += suffix;
+    if(const char* config_implib = this->GetProperty(impProp))
       {
-      // Compare the link implementation fallback link interface to the
-      // preferred new link interface property and warn if different.
-      std::vector<cmLinkItem> ifaceLibs;
-      static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
-      if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp))
-        {
-        bool hadHeadSensitiveConditionDummy = false;
-        thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config,
-                                    headTarget, usage_requirements_only,
-                                ifaceLibs, hadHeadSensitiveConditionDummy);
-        }
-      if (ifaceLibs != iface.Libraries)
-        {
-        std::string oldLibraries = cmJoin(impl->Libraries, ";");
-        std::string newLibraries = cmJoin(ifaceLibs, ";");
-        if(oldLibraries.empty())
-          { oldLibraries = "(empty)"; }
-        if(newLibraries.empty())
-          { newLibraries = "(empty)"; }
-
-        std::ostringstream w;
-        w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
-          "Target \"" << thisTarget->GetName() << "\" has an "
-          "INTERFACE_LINK_LIBRARIES property.  "
-          "This should be preferred as the source of the link interface "
-          "for this library but because CMP0022 is not set CMake is "
-          "ignoring the property and using the link implementation "
-          "as the link interface instead."
-          "\n"
-          "INTERFACE_LINK_LIBRARIES:\n"
-          "  " << newLibraries << "\n"
-          "Link implementation:\n"
-          "  " << oldLibraries << "\n";
-        thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
-        this->PolicyWarnedCMP0022 = true;
-        }
+      info.ImportLibrary = config_implib;
       }
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
-                                             const std::string& config,
-                                             OptionalLinkInterface& iface,
-                                             cmTarget const* headTarget) const
-{
-  if(iface.ExplicitLibraries)
-    {
-    if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY
-        || thisTarget->GetType() == cmTarget::STATIC_LIBRARY
-        || thisTarget->GetType() == cmTarget::INTERFACE_LIBRARY)
+    else if(const char* implib = this->GetProperty("IMPORTED_IMPLIB"))
       {
-      // Shared libraries may have runtime implementation dependencies
-      // on other shared libraries that are not in the interface.
-      UNORDERED_SET<std::string> emitted;
-      for(std::vector<cmLinkItem>::const_iterator
-          li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
-        {
-        emitted.insert(*li);
-        }
-      if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY)
-        {
-        cmTarget::LinkImplementation const* impl =
-            thisTarget->GetLinkImplementation(config);
-        for(std::vector<cmLinkImplItem>::const_iterator
-              li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
-          {
-          if(emitted.insert(*li).second)
-            {
-            if(li->Target)
-              {
-              // This is a runtime dependency on another shared library.
-              if(li->Target->GetType() == cmTarget::SHARED_LIBRARY)
-                {
-                iface.SharedDeps.push_back(*li);
-                }
-              }
-            else
-              {
-              // TODO: Recognize shared library file names.  Perhaps this
-              // should be moved to cmComputeLinkInformation, but that creates
-              // a chicken-and-egg problem since this list is needed for its
-              // construction.
-              }
-            }
-          }
-        }
+      info.ImportLibrary = implib;
       }
     }
-  else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN
-        || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD)
+
+  // Get the link dependencies.
+  {
+  std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
+  linkProp += suffix;
+  if(const char* config_libs = this->GetProperty(linkProp))
     {
-    // The link implementation is the default link interface.
-    cmTarget::LinkImplementationLibraries const*
-      impl = thisTarget->GetLinkImplementationLibrariesInternal(config,
-                                                                headTarget);
-    iface.ImplementationIsInterface = true;
-    iface.WrongConfigLibraries = impl->WrongConfigLibraries;
+    info.SharedDeps = config_libs;
     }
-
-  if(thisTarget->LinkLanguagePropagatesToDependents())
+  else if(const char* libs =
+          this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES"))
     {
-    // Targets using this archive need its language runtime libraries.
-    if(cmTarget::LinkImplementation const* impl =
-       thisTarget->GetLinkImplementation(config))
-      {
-      iface.Languages = impl->Languages;
-      }
+    info.SharedDeps = libs;
     }
+  }
 
-  if(thisTarget->GetType() == cmTarget::STATIC_LIBRARY)
+  // Get the link languages.
+  if(this->LinkLanguagePropagatesToDependents())
     {
-    // Construct the property name suffix for this configuration.
-    std::string suffix = "_";
-    if(!config.empty())
+    std::string linkProp = "IMPORTED_LINK_INTERFACE_LANGUAGES";
+    linkProp += suffix;
+    if(const char* config_libs = this->GetProperty(linkProp))
       {
-      suffix += cmSystemTools::UpperCase(config);
+      info.Languages = config_libs;
       }
-    else
+    else if(const char* libs =
+            this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES"))
       {
-      suffix += "NOCONFIG";
+      info.Languages = libs;
       }
+    }
 
-    // How many repetitions are needed if this library has cyclic
-    // dependencies?
-    std::string propName = "LINK_INTERFACE_MULTIPLICITY";
-    propName += suffix;
-    if(const char* config_reps = thisTarget->GetProperty(propName))
+  // Get the cyclic repetition count.
+  if(this->GetType() == cmTarget::STATIC_LIBRARY)
+    {
+    std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
+    linkProp += suffix;
+    if(const char* config_reps = this->GetProperty(linkProp))
       {
-      sscanf(config_reps, "%u", &iface.Multiplicity);
+      sscanf(config_reps, "%u", &info.Multiplicity);
       }
     else if(const char* reps =
-            thisTarget->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
+            this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY"))
       {
-      sscanf(reps, "%u", &iface.Multiplicity);
+      sscanf(reps, "%u", &info.Multiplicity);
       }
     }
 }
@@ -6167,7 +3453,7 @@ void cmTargetInternals::AddInterfaceEntries(
   cmTarget const* thisTarget, std::string const& config,
   std::string const& prop, std::vector<TargetPropertyEntry*>& entries)
 {
-  if(cmTarget::LinkImplementationLibraries const* impl =
+  if(cmLinkImplementationLibraries const* impl =
      thisTarget->GetLinkImplementationLibraries(config))
     {
     for (std::vector<cmLinkImplItem>::const_iterator
@@ -6178,7 +3464,7 @@ void cmTargetInternals::AddInterfaceEntries(
         {
         std::string genex =
           "$<TARGET_PROPERTY:" + *it + "," + prop + ">";
-        cmGeneratorExpression ge(&it->Backtrace);
+        cmGeneratorExpression ge(it->Backtrace);
         cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
         cge->SetEvaluateForBuildsystem(true);
         entries.push_back(
@@ -6188,43 +3474,23 @@ void cmTargetInternals::AddInterfaceEntries(
     }
 }
 
-//----------------------------------------------------------------------------
-cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementation(const std::string& config) const
+cmOptionalLinkImplementation&
+cmTarget::GetLinkImplMap(std::string const& config) const
 {
-  // There is no link implementation for imported targets.
-  if(this->IsImported())
-    {
-    return 0;
-    }
-
   // Populate the link implementation for this configuration.
   std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::OptionalLinkImplementation&
-    impl = this->Internal->LinkImplMap[CONFIG][this];
-  if(!impl.LibrariesDone)
-    {
-    impl.LibrariesDone = true;
-    this->Internal
-      ->ComputeLinkImplementationLibraries(this, config, impl, this);
-    }
-  if(!impl.LanguagesDone)
-    {
-    impl.LanguagesDone = true;
-    this->Internal->ComputeLinkImplementationLanguages(this, config, impl);
-    }
-  return &impl;
+  return Internal->LinkImplMap[CONFIG][this];
 }
 
 //----------------------------------------------------------------------------
-cmTarget::LinkImplementationLibraries const*
+cmLinkImplementationLibraries const*
 cmTarget::GetLinkImplementationLibraries(const std::string& config) const
 {
   return this->GetLinkImplementationLibrariesInternal(config, this);
 }
 
 //----------------------------------------------------------------------------
-cmTarget::LinkImplementationLibraries const*
+cmLinkImplementationLibraries const*
 cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
                                                  cmTarget const* head) const
 {
@@ -6246,39 +3512,36 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
     return &hm.begin()->second;
     }
 
-  cmTargetInternals::OptionalLinkImplementation& impl = hm[head];
+  cmOptionalLinkImplementation& impl = hm[head];
   if(!impl.LibrariesDone)
     {
     impl.LibrariesDone = true;
-    this->Internal
-      ->ComputeLinkImplementationLibraries(this, config, impl, head);
+    this->ComputeLinkImplementationLibraries(config, impl, head);
     }
   return &impl;
 }
 
 //----------------------------------------------------------------------------
-void
-cmTargetInternals::ComputeLinkImplementationLibraries(
-  cmTarget const* thisTarget,
+void cmTarget::ComputeLinkImplementationLibraries(
   const std::string& config,
-  OptionalLinkImplementation& impl,
+  cmOptionalLinkImplementation& impl,
   cmTarget const* head) const
 {
   // Collect libraries directly linked in this configuration.
   for (std::vector<cmValueWithOrigin>::const_iterator
-      le = this->LinkImplementationPropertyEntries.begin(),
-      end = this->LinkImplementationPropertyEntries.end();
+      le = this->Internal->LinkImplementationPropertyEntries.begin(),
+      end = this->Internal->LinkImplementationPropertyEntries.end();
       le != end; ++le)
     {
     std::vector<std::string> llibs;
     cmGeneratorExpressionDAGChecker dagChecker(
-                                        thisTarget->GetName(),
+                                        this->GetName(),
                                         "LINK_LIBRARIES", 0, 0);
-    cmGeneratorExpression ge(&le->Backtrace);
+    cmGeneratorExpression ge(le->Backtrace);
     cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
       ge.Parse(le->Value);
     std::string const evaluated =
-      cge->Evaluate(thisTarget->Makefile, config, false, head, &dagChecker);
+      cge->Evaluate(this->Makefile, config, false, head, &dagChecker);
     cmSystemTools::ExpandListArgument(evaluated, llibs);
     if(cge->GetHadHeadSensitiveCondition())
       {
@@ -6289,15 +3552,15 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
         li != llibs.end(); ++li)
       {
       // Skip entries that resolve to the target itself or are empty.
-      std::string name = thisTarget->CheckCMP0004(*li);
-      if(name == thisTarget->GetName() || name.empty())
+      std::string name = this->CheckCMP0004(*li);
+      if(name == this->GetName() || name.empty())
         {
-        if(name == thisTarget->GetName())
+        if(name == this->GetName())
           {
           bool noMessage = false;
           cmake::MessageType messageType = cmake::FATAL_ERROR;
           std::ostringstream e;
-          switch(thisTarget->GetPolicyStatusCMP0038())
+          switch(this->GetPolicyStatusCMP0038())
             {
             case cmPolicies::WARN:
               {
@@ -6316,9 +3579,9 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
 
           if(!noMessage)
             {
-            e << "Target \"" << thisTarget->GetName() << "\" links to itself.";
-            thisTarget->Makefile->GetCMakeInstance()->IssueMessage(
-              messageType, e.str(), thisTarget->GetBacktrace());
+            e << "Target \"" << this->GetName() << "\" links to itself.";
+            this->Makefile->GetCMakeInstance()->IssueMessage(
+              messageType, e.str(), this->GetBacktrace());
             if (messageType == cmake::FATAL_ERROR)
               {
               return;
@@ -6330,7 +3593,7 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
 
       // The entry is meant for this configuration.
       impl.Libraries.push_back(
-        cmLinkImplItem(name, thisTarget->FindTargetToLink(name),
+        cmLinkImplItem(name, this->FindTargetToLink(name),
                        le->Backtrace, evaluated != le->Value));
       }
 
@@ -6338,51 +3601,35 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
     for (std::set<std::string>::const_iterator it = seenProps.begin();
         it != seenProps.end(); ++it)
       {
-      if (!thisTarget->GetProperty(*it))
+      if (!this->GetProperty(*it))
         {
-        thisTarget->LinkImplicitNullProperties.insert(*it);
+        this->LinkImplicitNullProperties.insert(*it);
         }
       }
-    cge->GetMaxLanguageStandard(thisTarget, thisTarget->MaxLanguageStandards);
+    cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
     }
 
-  cmTarget::LinkLibraryType linkType = thisTarget->ComputeLinkType(config);
+  cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
   cmTarget::LinkLibraryVectorType const& oldllibs =
-    thisTarget->GetOriginalLinkLibraries();
+    this->GetOriginalLinkLibraries();
   for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
       li != oldllibs.end(); ++li)
     {
     if(li->second != cmTarget::GENERAL && li->second != linkType)
       {
-      std::string name = thisTarget->CheckCMP0004(li->first);
-      if(name == thisTarget->GetName() || name.empty())
+      std::string name = this->CheckCMP0004(li->first);
+      if(name == this->GetName() || name.empty())
         {
         continue;
         }
       // Support OLD behavior for CMP0003.
       impl.WrongConfigLibraries.push_back(
-        cmLinkItem(name, thisTarget->FindTargetToLink(name)));
+        cmLinkItem(name, this->FindTargetToLink(name)));
       }
     }
 }
 
 //----------------------------------------------------------------------------
-void
-cmTargetInternals::ComputeLinkImplementationLanguages(
-  cmTarget const* thisTarget,
-  const std::string& config,
-  OptionalLinkImplementation& impl) const
-{
-  // This target needs runtime libraries for its source languages.
-  std::set<std::string> languages;
-  // Get languages used in our source files.
-  thisTarget->GetLanguages(languages, config);
-  // Copy the set of langauges to the link implementation.
-  impl.Languages.insert(impl.Languages.begin(),
-                        languages.begin(), languages.end());
-}
-
-//----------------------------------------------------------------------------
 cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
 {
   cmTarget const* tgt = this->Makefile->FindTargetToUse(name);
@@ -6433,7 +3680,7 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const
   if(lib != item)
     {
     cmake* cm = this->Makefile->GetCMakeInstance();
-    switch(this->PolicyStatusCMP0004)
+    switch(this->GetPolicyStatusCMP0004())
       {
       case cmPolicies::WARN:
         {
@@ -6470,382 +3717,6 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const
   return lib;
 }
 
-template<typename PropertyType>
-PropertyType getLinkInterfaceDependentProperty(cmTarget const* tgt,
-                                               const std::string& prop,
-                                               const std::string& config,
-                                               CompatibleType,
-                                               PropertyType *);
-
-template<>
-bool getLinkInterfaceDependentProperty(cmTarget const* tgt,
-                                       const std::string& prop,
-                                       const std::string& config,
-                                       CompatibleType, bool *)
-{
-  return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
-}
-
-template<>
-const char * getLinkInterfaceDependentProperty(cmTarget const* tgt,
-                                               const std::string& prop,
-                                               const std::string& config,
-                                               CompatibleType t,
-                                               const char **)
-{
-  switch(t)
-  {
-  case BoolType:
-    assert(0 && "String compatibility check function called for boolean");
-    return 0;
-  case StringType:
-    return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
-  case NumberMinType:
-    return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
-  case NumberMaxType:
-    return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
-  }
-  assert(0 && "Unreachable!");
-  return 0;
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-void checkPropertyConsistency(cmTarget const* depender,
-                              cmTarget const* dependee,
-                              const std::string& propName,
-                              std::set<std::string> &emitted,
-                              const std::string& config,
-                              CompatibleType t,
-                              PropertyType *)
-{
-  const char *prop = dependee->GetProperty(propName);
-  if (!prop)
-    {
-    return;
-    }
-
-  std::vector<std::string> props;
-  cmSystemTools::ExpandListArgument(prop, props);
-  std::string pdir =
-    dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
-  pdir += "/Help/prop_tgt/";
-
-  for(std::vector<std::string>::iterator pi = props.begin();
-      pi != props.end(); ++pi)
-    {
-    std::string pname = cmSystemTools::HelpFileName(*pi);
-    std::string pfile = pdir + pname + ".rst";
-    if(cmSystemTools::FileExists(pfile.c_str(), true))
-      {
-      std::ostringstream e;
-      e << "Target \"" << dependee->GetName() << "\" has property \""
-        << *pi << "\" listed in its " << propName << " property.  "
-          "This is not allowed.  Only user-defined properties may appear "
-          "listed in the " << propName << " property.";
-      depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
-      return;
-      }
-    if(emitted.insert(*pi).second)
-      {
-      getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
-                                                      t, 0);
-      if (cmSystemTools::GetErrorOccuredFlag())
-        {
-        return;
-        }
-      }
-    }
-}
-
-static std::string intersect(const std::set<std::string> &s1,
-                             const std::set<std::string> &s2)
-{
-  std::set<std::string> intersect;
-  std::set_intersection(s1.begin(),s1.end(),
-                        s2.begin(),s2.end(),
-                      std::inserter(intersect,intersect.begin()));
-  if (!intersect.empty())
-    {
-    return *intersect.begin();
-    }
-  return "";
-}
-static std::string intersect(const std::set<std::string> &s1,
-                       const std::set<std::string> &s2,
-                       const std::set<std::string> &s3)
-{
-  std::string result;
-  result = intersect(s1, s2);
-  if (!result.empty())
-    return result;
-  result = intersect(s1, s3);
-  if (!result.empty())
-    return result;
-  return intersect(s2, s3);
-}
-static std::string intersect(const std::set<std::string> &s1,
-                       const std::set<std::string> &s2,
-                       const std::set<std::string> &s3,
-                       const std::set<std::string> &s4)
-{
-  std::string result;
-  result = intersect(s1, s2);
-  if (!result.empty())
-    return result;
-  result = intersect(s1, s3);
-  if (!result.empty())
-    return result;
-  result = intersect(s1, s4);
-  if (!result.empty())
-    return result;
-  return intersect(s2, s3, s4);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
-                                          const std::string& config) const
-{
-  const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
-
-  std::set<std::string> emittedBools;
-  static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
-  std::set<std::string> emittedStrings;
-  static std::string strString = "COMPATIBLE_INTERFACE_STRING";
-  std::set<std::string> emittedMinNumbers;
-  static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
-  std::set<std::string> emittedMaxNumbers;
-  static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
-
-  for(cmComputeLinkInformation::ItemVector::const_iterator li =
-      deps.begin();
-      li != deps.end(); ++li)
-    {
-    if (!li->Target)
-      {
-      continue;
-      }
-
-    checkPropertyConsistency<bool>(this, li->Target,
-                                strBool,
-                                emittedBools, config, BoolType, 0);
-    if (cmSystemTools::GetErrorOccuredFlag())
-      {
-      return;
-      }
-    checkPropertyConsistency<const char *>(this, li->Target,
-                                strString,
-                                emittedStrings, config,
-                                StringType, 0);
-    if (cmSystemTools::GetErrorOccuredFlag())
-      {
-      return;
-      }
-    checkPropertyConsistency<const char *>(this, li->Target,
-                                strNumMin,
-                                emittedMinNumbers, config,
-                                NumberMinType, 0);
-    if (cmSystemTools::GetErrorOccuredFlag())
-      {
-      return;
-      }
-    checkPropertyConsistency<const char *>(this, li->Target,
-                                strNumMax,
-                                emittedMaxNumbers, config,
-                                NumberMaxType, 0);
-    if (cmSystemTools::GetErrorOccuredFlag())
-      {
-      return;
-      }
-    }
-
-  std::string prop = intersect(emittedBools,
-                               emittedStrings,
-                               emittedMinNumbers,
-                               emittedMaxNumbers);
-
-  if (!prop.empty())
-    {
-    // Use a sorted std::vector to keep the error message sorted.
-    std::vector<std::string> props;
-    std::set<std::string>::const_iterator i = emittedBools.find(prop);
-    if (i != emittedBools.end())
-      {
-      props.push_back(strBool);
-      }
-    i = emittedStrings.find(prop);
-    if (i != emittedStrings.end())
-      {
-      props.push_back(strString);
-      }
-    i = emittedMinNumbers.find(prop);
-    if (i != emittedMinNumbers.end())
-      {
-      props.push_back(strNumMin);
-      }
-    i = emittedMaxNumbers.find(prop);
-    if (i != emittedMaxNumbers.end())
-      {
-      props.push_back(strNumMax);
-      }
-    std::sort(props.begin(), props.end());
-
-    std::string propsString = cmJoin(cmRange(props).retreat(1), ", ");
-    propsString += " and the " + props.back();
-
-    std::ostringstream e;
-    e << "Property \"" << prop << "\" appears in both the "
-      << propsString <<
-    " property in the dependencies of target \"" << this->GetName() <<
-    "\".  This is not allowed. A property may only require compatibility "
-    "in a boolean interpretation, a numeric minimum, a numeric maximum or a "
-    "string interpretation, but not a mixture.";
-    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-    }
-}
-
-//----------------------------------------------------------------------------
-cmComputeLinkInformation*
-cmTarget::GetLinkInformation(const std::string& config) const
-{
-  // Lookup any existing information for this configuration.
-  std::string key(cmSystemTools::UpperCase(config));
-  cmTargetLinkInformationMap::iterator
-    i = this->LinkInformation.find(key);
-  if(i == this->LinkInformation.end())
-    {
-    // Compute information for this configuration.
-    cmComputeLinkInformation* info =
-      new cmComputeLinkInformation(this, config);
-    if(!info || !info->Compute())
-      {
-      delete info;
-      info = 0;
-      }
-
-    // Store the information for this configuration.
-    cmTargetLinkInformationMap::value_type entry(key, info);
-    i = this->LinkInformation.insert(entry).first;
-
-    if (info)
-      {
-      this->CheckPropertyCompatibility(info, config);
-      }
-    }
-  return i->second;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFrameworkDirectory(const std::string& config,
-                                            bool rootDir) const
-{
-  std::string fpath;
-  fpath += this->GetOutputName(config, false);
-  fpath += ".framework";
-  if(!rootDir)
-    {
-    fpath += "/Versions/";
-    fpath += this->GetFrameworkVersion();
-    }
-  return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetCFBundleDirectory(const std::string& config,
-                                           bool contentOnly) const
-{
-  std::string fpath;
-  fpath += this->GetOutputName(config, false);
-  fpath += ".";
-  const char *ext = this->GetProperty("BUNDLE_EXTENSION");
-  if (!ext)
-    {
-    if (this->IsXCTestOnApple())
-      {
-      ext = "xctest";
-      }
-    else
-      {
-      ext = "bundle";
-      }
-    }
-  fpath += ext;
-  fpath += "/Contents";
-  if(!contentOnly)
-    fpath += "/MacOS";
-  return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetAppBundleDirectory(const std::string& config,
-                                            bool contentOnly) const
-{
-  std::string fpath = this->GetFullName(config, false);
-  fpath += ".app/Contents";
-  if(!contentOnly)
-    fpath += "/MacOS";
-  return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::BuildMacContentDirectory(const std::string& base,
-                                               const std::string& config,
-                                               bool contentOnly) const
-{
-  std::string fpath = base;
-  if(this->IsAppBundleOnApple())
-    {
-    fpath += this->GetAppBundleDirectory(config, contentOnly);
-    }
-  if(this->IsFrameworkOnApple())
-    {
-    fpath += this->GetFrameworkDirectory(config, contentOnly);
-    }
-  if(this->IsCFBundleOnApple())
-    {
-    fpath += this->GetCFBundleDirectory(config, contentOnly);
-    }
-  return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetMacContentDirectory(const std::string& config,
-                                             bool implib) const
-{
-  // Start with the output directory for the target.
-  std::string fpath = this->GetDirectory(config, implib);
-  fpath += "/";
-  bool contentOnly = true;
-  if(this->IsFrameworkOnApple())
-    {
-    // additional files with a framework go into the version specific
-    // directory
-    contentOnly = false;
-    }
-  fpath = this->BuildMacContentDirectory(fpath, config, contentOnly);
-  return fpath;
-}
-
-//----------------------------------------------------------------------------
-cmTargetLinkInformationMap
-::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived()
-{
-  // Ideally cmTarget instances should never be copied.  However until
-  // we can make a sweep to remove that, this copy constructor avoids
-  // allowing the resources (LinkInformation) from getting copied.  In
-  // the worst case this will lead to extra cmComputeLinkInformation
-  // instances.  We also enforce in debug mode that the map be emptied
-  // when copied.
-  static_cast<void>(r);
-  assert(r.empty());
-}
-
-//----------------------------------------------------------------------------
-cmTargetLinkInformationMap::~cmTargetLinkInformationMap()
-{
-  cmDeleteAll(*this);
-}
-
 //----------------------------------------------------------------------------
 cmTargetInternalPointer::cmTargetInternalPointer()
 {
@@ -6865,10 +3736,6 @@ cmTargetInternalPointer
 //----------------------------------------------------------------------------
 cmTargetInternalPointer::~cmTargetInternalPointer()
 {
-  cmDeleteAll(this->Pointer->IncludeDirectoriesEntries);
-  cmDeleteAll(this->Pointer->CompileOptionsEntries);
-  cmDeleteAll(this->Pointer->CompileFeaturesEntries);
-  cmDeleteAll(this->Pointer->CompileDefinitionsEntries);
   cmDeleteAll(this->Pointer->SourceEntries);
   delete this->Pointer;
 }
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3eb9e7e..3e71dbd 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -16,6 +16,7 @@
 #include "cmPropertyMap.h"
 #include "cmPolicies.h"
 #include "cmListFileCache.h"
+#include "cmLinkItem.h"
 
 #include <cmsys/auto_ptr.hxx>
 #if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -40,7 +41,8 @@
   F(CMP0046) \
   F(CMP0052) \
   F(CMP0060) \
-  F(CMP0063)
+  F(CMP0063) \
+  F(CMP0065)
 
 class cmake;
 class cmMakefile;
@@ -52,41 +54,6 @@ class cmTarget;
 class cmGeneratorTarget;
 class cmTargetTraceDependencies;
 
-// Basic information about each link item.
-class cmLinkItem: public std::string
-{
-  typedef std::string std_string;
-public:
-  cmLinkItem(): std_string(), Target(0) {}
-  cmLinkItem(const std_string& n,
-             cmTarget const* t): std_string(n), Target(t) {}
-  cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {}
-  cmTarget const* Target;
-};
-class cmLinkImplItem: public cmLinkItem
-{
-public:
-  cmLinkImplItem(): cmLinkItem(), Backtrace(0), FromGenex(false) {}
-  cmLinkImplItem(std::string const& n,
-                 cmTarget const* t,
-                 cmListFileBacktrace const& bt,
-                 bool fromGenex):
-    cmLinkItem(n, t), Backtrace(bt), FromGenex(fromGenex) {}
-  cmLinkImplItem(cmLinkImplItem const& r):
-    cmLinkItem(r), Backtrace(r.Backtrace), FromGenex(r.FromGenex) {}
-  cmListFileBacktrace Backtrace;
-  bool FromGenex;
-};
-
-struct cmTargetLinkInformationMap:
-  public std::map<std::string, cmComputeLinkInformation*>
-{
-  typedef std::map<std::string, cmComputeLinkInformation*> derived;
-  cmTargetLinkInformationMap() {}
-  cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
-  ~cmTargetLinkInformationMap();
-};
-
 class cmTargetInternals;
 class cmTargetInternalPointer
 {
@@ -144,7 +111,7 @@ public:
 
 #define DECLARE_TARGET_POLICY(POLICY) \
   cmPolicies::PolicyStatus GetPolicyStatus ## POLICY () const \
-    { return this->PolicyStatus ## POLICY; }
+    { return this->PolicyMap.Get(cmPolicies::POLICY); }
 
   CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY)
 
@@ -171,8 +138,6 @@ public:
    */
   void GetSourceFiles(std::vector<cmSourceFile*> &files,
                       const std::string& config) const;
-  bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
-
   /**
    * Add sources to the target.
    */
@@ -261,98 +226,19 @@ public:
   bool GetPropertyAsBool(const std::string& prop) const;
   void CheckProperty(const std::string& prop, cmMakefile* context) const;
 
-  const char* GetFeature(const std::string& feature,
-                         const std::string& config) const;
-  bool GetFeatureAsBool(const std::string& feature,
-                        const std::string& config) const;
-
   bool IsImported() const {return this->IsImportedTarget;}
 
   void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
 
-  /** The link interface specifies transitive library dependencies and
-      other information needed by targets that link to this target.  */
-  struct LinkInterfaceLibraries
-  {
-    // Libraries listed in the interface.
-    std::vector<cmLinkItem> Libraries;
-  };
-  struct LinkInterface: public LinkInterfaceLibraries
-  {
-    // Languages whose runtime libraries must be linked.
-    std::vector<std::string> Languages;
-
-    // Shared library dependencies needed for linking on some platforms.
-    std::vector<cmLinkItem> SharedDeps;
-
-    // Number of repetitions of a strongly connected component of two
-    // or more static libraries.
-    int Multiplicity;
-
-    // Libraries listed for other configurations.
-    // Needed only for OLD behavior of CMP0003.
-    std::vector<cmLinkItem> WrongConfigLibraries;
-
-    bool ImplementationIsInterface;
-
-    LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
-  };
-
-  /** Get the link interface for the given configuration.  Returns 0
-      if the target cannot be linked.  */
-  LinkInterface const* GetLinkInterface(const std::string& config,
-                                        cmTarget const* headTarget) const;
-  LinkInterfaceLibraries const*
-    GetLinkInterfaceLibraries(const std::string& config,
-                              cmTarget const* headTarget,
-                              bool usage_requirements_only) const;
-
-  std::vector<cmTarget const*> const&
-    GetLinkImplementationClosure(const std::string& config) const;
-
-  struct CompatibleInterfaces
-  {
-    std::set<std::string> PropsBool;
-    std::set<std::string> PropsString;
-    std::set<std::string> PropsNumberMax;
-    std::set<std::string> PropsNumberMin;
-  };
-  CompatibleInterfaces const&
-    GetCompatibleInterfaces(std::string const& config) const;
-
-  /** The link implementation specifies the direct library
-      dependencies needed by the object files of the target.  */
-  struct LinkImplementationLibraries
-  {
-    // Libraries linked directly in this configuration.
-    std::vector<cmLinkImplItem> Libraries;
-
-    // Libraries linked directly in other configurations.
-    // Needed only for OLD behavior of CMP0003.
-    std::vector<cmLinkItem> WrongConfigLibraries;
-  };
-  struct LinkImplementation: public LinkImplementationLibraries
-  {
-    // Languages whose runtime libraries must be linked.
-    std::vector<std::string> Languages;
-  };
-  LinkImplementation const*
-    GetLinkImplementation(const std::string& config) const;
-
-  LinkImplementationLibraries const*
+  cmLinkImplementationLibraries const*
     GetLinkImplementationLibraries(const std::string& config) const;
 
-  /** Link information from the transitive closure of the link
-      implementation and the interfaces of its dependencies.  */
-  struct LinkClosure
-  {
-    // The preferred linker language.
-    std::string LinkerLanguage;
+  void ComputeLinkImplementationLibraries(const std::string& config,
+                                          cmOptionalLinkImplementation& impl,
+                                          cmTarget const* head) const;
 
-    // Languages whose runtime libraries must be linked.
-    std::vector<std::string> Languages;
-  };
-  LinkClosure const* GetLinkClosure(const std::string& config) const;
+  cmOptionalLinkImplementation&
+  GetLinkImplMap(std::string const& config) const;
 
   cmTarget const* FindTargetToLink(std::string const& name) const;
 
@@ -373,20 +259,7 @@ public:
       pdb output directory is given.  */
   std::string GetPDBDirectory(const std::string& config) const;
 
-  /** Get the directory in which to place the target compiler .pdb file.
-      If the configuration name is given then the generator will add its
-      subdirectory for that configuration.  Otherwise just the canonical
-      compiler pdb output directory is given.  */
-  std::string GetCompilePDBDirectory(const std::string& config = "") const;
-
-  /** Get the location of the target in the build tree for the given
-      configuration.  */
-  const char* GetLocation(const std::string& config) const;
-
-  /** Get the location of the target in the build tree with a placeholder
-      referencing the configuration in the native build system.  This
-      location is suitable for use as the LOCATION target property.  */
-  const char* GetLocationForBuild() const;
+  const char* ImportedGetLocation(const std::string& config) const;
 
   /** Get the target major and minor version numbers interpreted from
       the VERSION property.  Version 0 is returned if the property is
@@ -399,33 +272,6 @@ public:
   void
   GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
 
-  ///! Return the preferred linker language for this target
-  std::string GetLinkerLanguage(const std::string& config = "") const;
-
-  /** Get the full name of the target according to the settings in its
-      makefile.  */
-  std::string GetFullName(const std::string& config="",
-                          bool implib = false) const;
-  void GetFullNameComponents(std::string& prefix,
-                             std::string& base, std::string& suffix,
-                             const std::string& config="",
-                             bool implib = false) const;
-
-  /** Get the name of the pdb file for the target.  */
-  std::string GetPDBName(const std::string& config) const;
-
-  /** Get the name of the compiler pdb file for the target.  */
-  std::string GetCompilePDBName(const std::string& config="") const;
-
-  /** Get the path for the MSVC /Fd option for this target.  */
-  std::string GetCompilePDBPath(const std::string& config="") const;
-
-  /** Whether this library has soname enabled and platform supports it.  */
-  bool HasSOName(const std::string& config) const;
-
-  /** Get the soname of the target.  Allowed only for a shared library.  */
-  std::string GetSOName(const std::string& config) const;
-
   /** Whether this library has \@rpath and platform supports it.  */
   bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
 
@@ -436,26 +282,6 @@ public:
       no soname at all.  */
   bool IsImportedSharedLibWithoutSOName(const std::string& config) const;
 
-  /** Get the full path to the target according to the settings in its
-      makefile and the configuration type.  */
-  std::string GetFullPath(const std::string& config="", bool implib = false,
-                          bool realname = false) const;
-
-  /** Get the names of the library needed to generate a build rule
-      that takes into account shared library version numbers.  This
-      should be called only on a library target.  */
-  void GetLibraryNames(std::string& name, std::string& soName,
-                       std::string& realName, std::string& impName,
-                       std::string& pdbName, const std::string& config) const;
-
-  /** Get the names of the executable needed to generate a build rule
-      that takes into account executable version numbers.  This should
-      be called only on an executable target.  */
-  void GetExecutableNames(std::string& name, std::string& realName,
-                          std::string& impName,
-                          std::string& pdbName,
-                          const std::string& config) const;
-
   /** Does this target have a GNU implib to convert to MS format?  */
   bool HasImplibGNUtoMS() const;
 
@@ -464,29 +290,8 @@ public:
   bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
                         const char* newExt = 0) const;
 
-  /**
-   * Compute whether this target must be relinked before installing.
-   */
-  bool NeedRelinkBeforeInstall(const std::string& config) const;
-
-  bool HaveBuildTreeRPATH(const std::string& config) const;
   bool HaveInstallTreeRPATH() const;
 
-  /** Return true if builtin chrpath will work for this target */
-  bool IsChrpathUsed(const std::string& config) const;
-
-  /** Return the install name directory for the target in the
-    * build tree.  For example: "\@rpath/", "\@loader_path/",
-    * or "/full/path/to/library".  */
-  std::string GetInstallNameDirForBuildTree(const std::string& config) const;
-
-  /** Return the install name directory for the target in the
-    * install tree.  For example: "\@rpath/" or "\@loader_path/". */
-  std::string GetInstallNameDirForInstallTree() const;
-
-  cmComputeLinkInformation*
-    GetLinkInformation(const std::string& config) const;
-
   // Get the properties
   cmPropertyMap &GetProperties() const { return this->Properties; }
 
@@ -499,18 +304,6 @@ public:
       If no macro should be defined null is returned.  */
   const char* GetExportMacro() const;
 
-  void GetCompileDefinitions(std::vector<std::string> &result,
-                             const std::string& config,
-                             const std::string& language) const;
-
-  // Compute the set of languages compiled by the target.  This is
-  // computed every time it is called because the languages can change
-  // when source file properties are changed and we do not have enough
-  // information to forward these property changes to the targets
-  // until we have per-target object file properties.
-  void GetLanguages(std::set<std::string>& languages,
-                    std::string const& config) const;
-
   /** Return whether this target is an executable with symbol exports
       enabled.  */
   bool IsExecutableWithExports() const;
@@ -537,10 +330,6 @@ public:
   /** Return whether this target is an executable Bundle on Apple.  */
   bool IsAppBundleOnApple() const;
 
-  /** Return whether this target is an executable Bundle, a framework
-      or CFBundle on Apple.  */
-  bool IsBundleOnApple() const;
-
   /** Return the framework version string.  Undefined if
       IsFrameworkOnApple returns false.  */
   std::string GetFrameworkVersion() const;
@@ -555,86 +344,50 @@ public:
       directory.  */
   bool UsesDefaultOutputDir(const std::string& config, bool implib) const;
 
-  /** @return the mac content directory for this target. */
-  std::string GetMacContentDirectory(const std::string& config,
-                                     bool implib) const;
-
   /** @return whether this target have a well defined output file name. */
   bool HaveWellDefinedOutputFiles() const;
 
-  /** @return the Mac framework directory without the base. */
-  std::string GetFrameworkDirectory(const std::string& config,
-                                    bool rootDir) const;
-
-  /** @return the Mac CFBundle directory without the base */
-  std::string GetCFBundleDirectory(const std::string& config,
-                                   bool contentOnly) const;
-
-  /** @return the Mac App directory without the base */
-  std::string GetAppBundleDirectory(const std::string& config,
-                                    bool contentOnly) const;
-
-  std::vector<std::string> GetIncludeDirectories(
-                     const std::string& config,
-                     const std::string& language) const;
-  void InsertInclude(const cmValueWithOrigin &entry,
+  void InsertInclude(std::string const& entry,
+                     cmListFileBacktrace const& bt,
                      bool before = false);
-  void InsertCompileOption(const cmValueWithOrigin &entry,
-                     bool before = false);
-  void InsertCompileDefinition(const cmValueWithOrigin &entry);
+  void InsertCompileOption(std::string const& entry,
+                           cmListFileBacktrace const& bt,
+                           bool before = false);
+  void InsertCompileDefinition(std::string const& entry,
+                               cmListFileBacktrace const& bt);
 
   void AppendBuildInterfaceIncludes();
 
-  void GetCompileOptions(std::vector<std::string> &result,
-                         const std::string& config,
-                         const std::string& language) const;
-  void GetAutoUicOptions(std::vector<std::string> &result,
-                         const std::string& config) const;
-  void GetCompileFeatures(std::vector<std::string> &features,
-                          const std::string& config) const;
-
   bool IsNullImpliedByLinkLibraries(const std::string &p) const;
-  bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
-                         const std::string& config) const;
-  bool IsLinkInterfaceDependentStringProperty(const std::string &p,
-                         const std::string& config) const;
-  bool IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
-                         const std::string& config) const;
-  bool IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
-                         const std::string& config) const;
-
-  bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
-                                             const std::string& config) const;
-
-  const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
-                         const std::string& config) const;
-  const char *GetLinkInterfaceDependentNumberMinProperty(const std::string &p,
-                         const std::string& config) const;
-  const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p,
-                         const std::string& config) const;
 
   std::string GetDebugGeneratorExpressions(const std::string &value,
                                   cmTarget::LinkLibraryType llt) const;
 
   void AddSystemIncludeDirectories(const std::set<std::string> &incs);
-  void AddSystemIncludeDirectories(const std::vector<std::string> &incs);
   std::set<std::string> const & GetSystemIncludeDirectories() const
     { return this->SystemIncludeDirectories; }
 
   bool LinkLanguagePropagatesToDependents() const
   { return this->TargetTypeValue == STATIC_LIBRARY; }
 
-  void ReportPropertyOrigin(const std::string &p,
-                            const std::string &result,
-                            const std::string &report,
-                            const std::string &compatibilityType) const;
-
   std::map<std::string, std::string> const&
   GetMaxLanguageStandards() const
   {
     return this->MaxLanguageStandards;
   }
 
+  cmStringRange GetIncludeDirectoriesEntries() const;
+  cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
+
+  cmStringRange GetCompileOptionsEntries() const;
+  cmBacktraceRange GetCompileOptionsBacktraces() const;
+
+  cmStringRange GetCompileFeaturesEntries() const;
+  cmBacktraceRange GetCompileFeaturesBacktraces() const;
+
+  cmStringRange GetCompileDefinitionsEntries() const;
+  cmBacktraceRange GetCompileDefinitionsBacktraces() const;
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
   const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
   return this->LinkLibrariesForVS6;}
@@ -643,12 +396,6 @@ public:
 private:
   bool HandleLocationPropertyPolicy(cmMakefile* context) const;
 
-  // The set of include directories that are marked as system include
-  // directories.
-  std::set<std::string> SystemIncludeDirectories;
-
-  std::vector<std::pair<TLLSignature, cmListFileContext> > TLLCommands;
-
 #if defined(_WIN32) && !defined(__CYGWIN__)
   /**
    * A list of direct dependencies. Use in conjunction with DependencyMap.
@@ -704,11 +451,6 @@ private:
 
   const char* GetSuffixVariableInternal(bool implib) const;
   const char* GetPrefixVariableInternal(bool implib) const;
-  std::string GetFullNameInternal(const std::string& config,
-                                  bool implib) const;
-  void GetFullNameInternal(const std::string& config, bool implib,
-                           std::string& outPrefix, std::string& outBase,
-                           std::string& outSuffix) const;
 
   // Use a makefile variable to set a default for the given property.
   // If the variable is not defined use the given default instead.
@@ -718,65 +460,53 @@ private:
   // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
   const char* GetOutputTargetType(bool implib) const;
 
-  // Get the target base name.
-  std::string GetOutputName(const std::string& config, bool implib) const;
-
   std::string GetFullNameImported(const std::string& config,
                                   bool implib) const;
 
   std::string ImportedGetFullPath(const std::string& config,
                                   bool implib) const;
-  std::string NormalGetFullPath(const std::string& config, bool implib,
-                                bool realname) const;
-
-  /** Get the real name of the target.  Allowed only for non-imported
-      targets.  When a library or executable file is versioned this is
-      the full versioned name.  If the target is not versioned this is
-      the same as GetFullName.  */
-  std::string NormalGetRealName(const std::string& config) const;
 
-  /** Append to @a base the mac content directory and return it. */
-  std::string BuildMacContentDirectory(const std::string& base,
-                                       const std::string& config,
-                                       bool contentOnly) const;
 
   void GetSourceFiles(std::vector<std::string> &files,
                       const std::string& config) const;
 private:
+  mutable cmPropertyMap Properties;
+  std::set<std::string> SystemIncludeDirectories;
+  std::set<std::string> LinkDirectoriesEmmitted;
+  std::set<std::string> Utilities;
+  mutable std::set<std::string> LinkImplicitNullProperties;
+  std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
+  mutable std::map<std::string, std::string> MaxLanguageStandards;
+  cmPolicies::PolicyMap PolicyMap;
   std::string Name;
+  std::string InstallPath;
+  std::string RuntimeInstallPath;
+  mutable std::string ExportMacro;
+  std::vector<std::string> LinkDirectories;
   std::vector<cmCustomCommand> PreBuildCommands;
   std::vector<cmCustomCommand> PreLinkCommands;
   std::vector<cmCustomCommand> PostBuildCommands;
-  TargetType TargetTypeValue;
+  std::vector<std::pair<TLLSignature, cmListFileContext> > TLLCommands;
   LinkLibraryVectorType PrevLinkedLibraries;
+  LinkLibraryVectorType OriginalLinkLibraries;
 #if defined(_WIN32) && !defined(__CYGWIN__)
   LinkLibraryVectorType LinkLibrariesForVS6;
-  bool LinkLibrariesForVS6Analyzed;
 #endif
-  std::vector<std::string> LinkDirectories;
-  std::set<std::string> LinkDirectoriesEmmitted;
+  cmMakefile* Makefile;
+  cmTargetInternalPointer Internal;
+  TargetType TargetTypeValue;
   bool HaveInstallRule;
-  std::string InstallPath;
-  std::string RuntimeInstallPath;
-  mutable std::string ExportMacro;
-  std::set<std::string> Utilities;
-  std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
   bool RecordDependencies;
-  mutable cmPropertyMap Properties;
-  LinkLibraryVectorType OriginalLinkLibraries;
   bool DLLPlatform;
   bool IsAndroid;
   bool IsApple;
   bool IsImportedTarget;
-  mutable bool DebugIncludesDone;
-  mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
-  mutable bool DebugCompileOptionsDone;
-  mutable bool DebugCompileDefinitionsDone;
-  mutable bool DebugSourcesDone;
-  mutable bool DebugCompileFeaturesDone;
-  mutable std::set<std::string> LinkImplicitNullProperties;
-  mutable std::map<std::string, std::string> MaxLanguageStandards;
   bool BuildInterfaceIncludesAppended;
+  mutable bool DebugSourcesDone;
+  mutable bool LinkImplementationLanguageIsContextDependent;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  bool LinkLibrariesForVS6Analyzed;
+#endif
 
   // Cache target output paths for each configuration.
   struct OutputInfo;
@@ -788,35 +518,27 @@ private:
                            std::string& out) const;
 
   // Cache import information from properties for each configuration.
-  struct ImportInfo;
+  struct ImportInfo
+  {
+    ImportInfo(): NoSOName(false), Multiplicity(0) {}
+    bool NoSOName;
+    int Multiplicity;
+    std::string Location;
+    std::string SOName;
+    std::string ImportLibrary;
+    std::string Languages;
+    std::string Libraries;
+    std::string LibrariesProp;
+    std::string SharedDeps;
+  };
+
   ImportInfo const* GetImportInfo(const std::string& config) const;
   void ComputeImportInfo(std::string const& desired_config,
                          ImportInfo& info) const;
 
-  // Cache target compile paths for each configuration.
-  struct CompileInfo;
-  CompileInfo const* GetCompileInfo(const std::string& config) const;
-
-  mutable cmTargetLinkInformationMap LinkInformation;
-  void CheckPropertyCompatibility(cmComputeLinkInformation *info,
-                                  const std::string& config) const;
-
-  LinkInterface const*
-    GetImportLinkInterface(const std::string& config, cmTarget const* head,
-                           bool usage_requirements_only) const;
-
-  LinkImplementationLibraries const*
+  cmLinkImplementationLibraries const*
     GetLinkImplementationLibrariesInternal(const std::string& config,
                                            cmTarget const* head) const;
-  void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
-
-  void ExpandLinkItems(std::string const& prop, std::string const& value,
-                       std::string const& config, cmTarget const* headTarget,
-                       bool usage_requirements_only,
-                       std::vector<cmLinkItem>& items,
-                       bool& hadHeadSensitiveCondition) const;
-  void LookupLinkItems(std::vector<std::string> const& names,
-                       std::vector<cmLinkItem>& items) const;
 
   std::string ProcessSourceItemCMP0049(const std::string& s);
 
@@ -824,25 +546,10 @@ private:
 
   void MaybeInvalidatePropertyCache(const std::string& prop);
 
-  void ProcessSourceExpression(std::string const& expr);
-
-  // The cmMakefile instance that owns this target.  This should
-  // always be set.
-  cmMakefile* Makefile;
-
-  // Policy status recorded when target was created.
-#define TARGET_POLICY_MEMBER(POLICY) \
-  cmPolicies::PolicyStatus PolicyStatus ## POLICY;
-
-  CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_MEMBER)
-
-#undef TARGET_POLICY_MEMBER
-
   // Internal representation details.
   friend class cmTargetInternals;
   friend class cmGeneratorTarget;
   friend class cmTargetTraceDependencies;
-  cmTargetInternalPointer Internal;
 
   void ComputeVersionedName(std::string& vName,
                             std::string const& prefix,
@@ -850,8 +557,6 @@ private:
                             std::string const& suffix,
                             std::string const& name,
                             const char* version) const;
-
-  mutable bool LinkImplementationLanguageIsContextDependent;
 };
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index a85153d..8e86f0f 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -50,7 +50,6 @@ bool cmTargetCompileOptionsCommand
                                    bool, bool)
 {
   cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-  cmValueWithOrigin entry(this->Join(content), lfbt);
-  tgt->InsertCompileOption(entry);
+  tgt->InsertCompileOption(this->Join(content), lfbt);
   return true;
 }
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
index 1feb072..c5059ee 100644
--- a/Source/cmTargetDepend.h
+++ b/Source/cmTargetDepend.h
@@ -14,23 +14,24 @@
 
 #include "cmStandardIncludes.h"
 
-class cmTarget;
+class cmGeneratorTarget;
 
 /** One edge in the global target dependency graph.
     It may be marked as a 'link' or 'util' edge or both.  */
 class cmTargetDepend
 {
-  cmTarget const* Target;
+  cmGeneratorTarget const* Target;
 
   // The set order depends only on the Target, so we use
   // mutable members to acheive a map with set syntax.
   mutable bool Link;
   mutable bool Util;
 public:
-  cmTargetDepend(cmTarget const* t): Target(t), Link(false), Util(false) {}
-  operator cmTarget const*() const { return this->Target; }
-  cmTarget const* operator->() const { return this->Target; }
-  cmTarget const& operator*() const { return *this->Target; }
+  cmTargetDepend(cmGeneratorTarget const* t)
+    : Target(t), Link(false), Util(false) {}
+  operator cmGeneratorTarget const*() const { return this->Target; }
+  cmGeneratorTarget const* operator->() const { return this->Target; }
+  cmGeneratorTarget const& operator*() const { return *this->Target; }
   friend bool operator < (cmTargetDepend const& l, cmTargetDepend const& r)
     { return l.Target < r.Target; }
   void SetType(bool strong) const
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index 24500db..7dfe9ca 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -72,11 +72,26 @@ bool cmTargetIncludeDirectoriesCommand
                       bool prepend, bool system)
 {
   cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-  cmValueWithOrigin entry(this->Join(content), lfbt);
-  tgt->InsertInclude(entry, prepend);
+  tgt->InsertInclude(this->Join(content), lfbt, prepend);
   if (system)
     {
-    tgt->AddSystemIncludeDirectories(content);
+    std::string prefix =
+      this->Makefile->GetCurrentSourceDirectory() + std::string("/");
+    std::set<std::string> sdirs;
+    for (std::vector<std::string>::const_iterator it = content.begin();
+      it != content.end(); ++it)
+      {
+      if (cmSystemTools::FileIsFullPath(it->c_str())
+          || cmGeneratorExpression::Find(*it) == 0)
+        {
+        sdirs.insert(*it);
+        }
+      else
+        {
+        sdirs.insert(prefix + *it);
+        }
+      }
+    tgt->AddSystemIncludeDirectories(sdirs);
     }
   return true;
 }
@@ -92,7 +107,7 @@ void cmTargetIncludeDirectoriesCommand
 
   if (system)
     {
-    std::string joined = cmJoin(content, ";");
+    std::string joined = this->Join(content);
     tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
                         joined.c_str());
     }
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index ff5d411..6fcd0dc 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -21,7 +21,6 @@ cmTest::cmTest(cmMakefile* mf)
 {
   this->Makefile = mf;
   this->OldStyle = true;
-  this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
 }
 
 //----------------------------------------------------------------------------
@@ -50,12 +49,15 @@ void cmTest::SetCommand(std::vector<std::string> const& command)
 //----------------------------------------------------------------------------
 const char *cmTest::GetProperty(const std::string& prop) const
 {
-  bool chain = false;
-  const char *retVal =
-    this->Properties.GetPropertyValue(prop, cmProperty::TEST, chain);
-  if (chain)
+  const char *retVal = this->Properties.GetPropertyValue(prop);
+  if (!retVal)
     {
-    return this->Makefile->GetProperty(prop,cmProperty::TEST);
+    const bool chain = this->Makefile->GetState()->
+          IsPropertyChained(prop, cmProperty::TEST);
+    if (chain)
+      {
+      return this->Makefile->GetProperty(prop, chain);
+      }
     }
   return retVal;
 }
@@ -69,12 +71,12 @@ bool cmTest::GetPropertyAsBool(const std::string& prop) const
 //----------------------------------------------------------------------------
 void cmTest::SetProperty(const std::string& prop, const char* value)
 {
-  this->Properties.SetProperty(prop, value, cmProperty::TEST);
+  this->Properties.SetProperty(prop, value);
 }
 
 //----------------------------------------------------------------------------
 void cmTest::AppendProperty(const std::string& prop,
                             const char* value, bool asString)
 {
-  this->Properties.AppendProperty(prop, value, cmProperty::TEST, asString);
+  this->Properties.AppendProperty(prop, value, asString);
 }
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 7e11d8c..9d85f5a 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -12,8 +12,9 @@
 #include "cmTestGenerator.h"
 
 #include "cmGeneratorExpression.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
 #include "cmMakefile.h"
+#include "cmLocalGenerator.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 #include "cmTest.h"
@@ -27,6 +28,7 @@ cmTestGenerator
 {
   this->ActionsPerConfig = !test->GetOldStyle();
   this->TestGenerated = false;
+  this->LG = 0;
 }
 
 //----------------------------------------------------------------------------
@@ -35,6 +37,11 @@ cmTestGenerator
 {
 }
 
+void cmTestGenerator::Compute(cmLocalGenerator* lg)
+{
+  this->LG = lg;
+}
+
 //----------------------------------------------------------------------------
 void cmTestGenerator::GenerateScriptConfigs(std::ostream& os,
                                             Indent const& indent)
@@ -70,7 +77,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
   this->TestGenerated = true;
 
   // Set up generator expression evaluation context.
-  cmGeneratorExpression ge(&this->Test->GetBacktrace());
+  cmGeneratorExpression ge(this->Test->GetBacktrace());
 
   // Start the test command.
   os << indent << "add_test(" << this->Test->GetName() << " ";
@@ -81,8 +88,8 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
   // Check whether the command executable is a target whose name is to
   // be translated.
   std::string exe = command[0];
-  cmMakefile* mf = this->Test->GetMakefile();
-  cmTarget* target = mf->FindTargetToUse(exe);
+  cmGeneratorTarget* target =
+      this->LG->GetMakefile()->FindGeneratorTargetToUse(exe);
   if(target && target->GetType() == cmTarget::EXECUTABLE)
     {
     // Use the target file on disk.
@@ -97,30 +104,31 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
       cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs);
       std::string emulatorExe(emulatorWithArgs[0]);
       cmSystemTools::ConvertToUnixSlashes(emulatorExe);
-      os << cmLocalGenerator::EscapeForCMake(emulatorExe) << " ";
+      os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
       for(std::vector<std::string>::const_iterator ei =
           emulatorWithArgs.begin()+1;
           ei != emulatorWithArgs.end();
           ++ei)
         {
-        os << cmLocalGenerator::EscapeForCMake(*ei) << " ";
+        os << cmOutputConverter::EscapeForCMake(*ei) << " ";
         }
       }
     }
   else
     {
     // Use the command name given.
-    exe = ge.Parse(exe.c_str())->Evaluate(mf, config);
+    exe = ge.Parse(exe.c_str())->Evaluate(this->LG->GetMakefile(), config);
     cmSystemTools::ConvertToUnixSlashes(exe);
     }
 
   // Generate the command line with full escapes.
-  os << cmLocalGenerator::EscapeForCMake(exe);
+  os << cmOutputConverter::EscapeForCMake(exe);
   for(std::vector<std::string>::const_iterator ci = command.begin()+1;
       ci != command.end(); ++ci)
     {
-    os << " " << cmLocalGenerator::EscapeForCMake(
-                                         ge.Parse(*ci)->Evaluate(mf, config));
+    os << " " << cmOutputConverter::EscapeForCMake(
+                                         ge.Parse(*ci)->Evaluate(
+                                            this->LG->GetMakefile(), config));
     }
 
   // Finish the test command.
@@ -136,8 +144,9 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
         i != pm.end(); ++i)
       {
       os << " " << i->first
-         << " " << cmLocalGenerator::EscapeForCMake(
-           ge.Parse(i->second.GetValue())->Evaluate(mf, config));
+         << " " << cmOutputConverter::EscapeForCMake(
+           ge.Parse(i->second.GetValue())->Evaluate(this->LG->GetMakefile(),
+                                                    config));
       }
     os << ")" << std::endl;
     }
@@ -206,7 +215,7 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout,
         i != pm.end(); ++i)
       {
       fout << " " << i->first
-           << " " << cmLocalGenerator::EscapeForCMake(i->second.GetValue());
+           << " " << cmOutputConverter::EscapeForCMake(i->second.GetValue());
       }
     fout << ")" << std::endl;
     }
diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h
index 5446553..de8ab78 100644
--- a/Source/cmTestGenerator.h
+++ b/Source/cmTestGenerator.h
@@ -15,6 +15,7 @@
 #include "cmScriptGenerator.h"
 
 class cmTest;
+class cmLocalGenerator;
 
 /** \class cmTestGenerator
  * \brief Support class for generating install scripts.
@@ -28,6 +29,8 @@ public:
                   configurations = std::vector<std::string>());
   virtual ~cmTestGenerator();
 
+  void Compute(cmLocalGenerator* lg);
+
 protected:
   virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
   virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
@@ -38,6 +41,7 @@ protected:
   virtual bool NeedsScriptNoConfig() const;
   void GenerateOldStyle(std::ostream& os, Indent const& indent);
 
+  cmLocalGenerator* LG;
   cmTest* Test;
   bool TestGenerated;
 };
diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h
index da927c7..1af2bfe 100644
--- a/Source/cmUseMangledMesaCommand.h
+++ b/Source/cmUseMangledMesaCommand.h
@@ -23,7 +23,6 @@ public:
                            cmExecutionStatus &status);
   virtual std::string GetName() const { return "use_mangled_mesa";}
   virtual bool IsScriptable() const { return true; }
-  virtual bool IsDiscouraged() const { return true; }
 protected:
   void CopyAndFullPathMesaHeader(const char* source,
                                  const char* outdir);
diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h
index 23afdbe..8863ff5 100644
--- a/Source/cmUtilitySourceCommand.h
+++ b/Source/cmUtilitySourceCommand.h
@@ -22,7 +22,6 @@ public:
   virtual bool InitialPass(std::vector<std::string> const& args,
                            cmExecutionStatus &status);
   virtual std::string GetName() const { return "utility_source";}
-  virtual bool IsDiscouraged() const { return true; }
 };
 
 #endif
diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h
index 7e68de1..5b0477f 100644
--- a/Source/cmVariableRequiresCommand.h
+++ b/Source/cmVariableRequiresCommand.h
@@ -22,7 +22,6 @@ public:
   virtual bool InitialPass(std::vector<std::string> const& args,
                            cmExecutionStatus &status);
   virtual std::string GetName() const { return "variable_requires";}
-  virtual bool IsDiscouraged() const { return true; }
 };
 
 
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 9473008..98a397c 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -49,30 +49,26 @@ static void cmVariableWatchCommandVariableAccessed(
     newLFF.Arguments.clear();
     newLFF.Arguments.push_back(
       cmListFileArgument(variable, cmListFileArgument::Quoted,
-                         "unknown", 9999));
+                         9999));
     newLFF.Arguments.push_back(
       cmListFileArgument(accessString, cmListFileArgument::Quoted,
-                         "unknown", 9999));
+                         9999));
     newLFF.Arguments.push_back(
       cmListFileArgument(newValue?newValue:"", cmListFileArgument::Quoted,
-                         "unknown", 9999));
+                         9999));
     newLFF.Arguments.push_back(
       cmListFileArgument(currentListFile, cmListFileArgument::Quoted,
-                         "unknown", 9999));
+                         9999));
     newLFF.Arguments.push_back(
       cmListFileArgument(stack, cmListFileArgument::Quoted,
-                         "unknown", 9999));
+                         9999));
     newLFF.Name = data->Command;
-    newLFF.FilePath = "Some weird path";
     newLFF.Line = 9999;
     cmExecutionStatus status;
     if(!makefile->ExecuteCommand(newLFF,status))
       {
-      arg.FilePath =  "Unknown";
-      arg.Line = 0;
       std::ostringstream error;
-      error << "Error in cmake code at\n"
-        << arg.FilePath << ":" << arg.Line << ":\n"
+      error << "Error in cmake code at\nUnknown:0:\n"
         << "A command failed during the invocation of callback \""
         << data->Command << "\".";
       cmSystemTools::Error(error.str().c_str());
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 5dfdb14..1de2847 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -9,6 +9,7 @@
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the License for more information.
 ============================================================================*/
+#include "windows.h"
 #include "cmVisualStudio10TargetGenerator.h"
 #include "cmGlobalVisualStudio10Generator.h"
 #include "cmGeneratorTarget.h"
@@ -176,9 +177,8 @@ cmVisualStudio10TargetGenerator(cmTarget* target,
   this->Makefile->GetConfigurations(this->Configurations);
   this->LocalGenerator =
     (cmLocalVisualStudio7Generator*)
-    this->Makefile->GetLocalGenerator();
+    this->GeneratorTarget->GetLocalGenerator();
   this->Name = this->Target->GetName();
-  this->GlobalGenerator->CreateGUID(this->Name.c_str());
   this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
   this->Platform = gg->GetPlatformName();
   this->NsightTegra = gg->IsNsightTegra();
@@ -325,12 +325,22 @@ void cmVisualStudio10TargetGenerator::Generate()
   if(this->NsightTegra)
     {
     this->WriteString("<PropertyGroup Label=\"NsightTegraProject\">\n", 1);
-    if(this->NsightTegraVersion[0] >= 2)
+    const int nsightTegraMajorVersion = this->NsightTegraVersion[0];
+    const int nsightTegraMinorVersion = this->NsightTegraVersion[1];
+    if (nsightTegraMajorVersion >= 2)
       {
-      // Nsight Tegra 2.0 uses project revision 9.
-      this->WriteString("<NsightTegraProjectRevisionNumber>"
-                        "9"
-                        "</NsightTegraProjectRevisionNumber>\n", 2);
+      this->WriteString("<NsightTegraProjectRevisionNumber>", 2);
+      if (nsightTegraMajorVersion > 3 ||
+          (nsightTegraMajorVersion == 3 && nsightTegraMinorVersion >= 1))
+        {
+        (*this->BuildFileStream) << "11";
+        }
+      else
+        {
+        // Nsight Tegra 2.0 uses project revision 9.
+        (*this->BuildFileStream) << "9";
+        }
+      (*this->BuildFileStream) << "</NsightTegraProjectRevisionNumber>\n";
       // Tell newer versions to upgrade silently when loading.
       this->WriteString("<NsightTegraUpgradeOnceWithoutPrompt>"
                         "true"
@@ -453,6 +463,7 @@ void cmVisualStudio10TargetGenerator::Generate()
   this->WriteString("<Import Project=\"" VS10_USER_PROPS "\""
                     " Condition=\"exists('" VS10_USER_PROPS "')\""
                     " Label=\"LocalAppDataPlatform\" />\n", 2);
+  this->WritePlatformExtensions();
   this->WriteString("</ImportGroup>\n", 1);
   this->WriteString("<PropertyGroup Label=\"UserMacros\" />\n", 1);
   this->WriteWinRTPackageCertificateKeyFile();
@@ -465,6 +476,7 @@ void cmVisualStudio10TargetGenerator::Generate()
   this->WriteXamlFilesGroup();
   this->WriteWinRTReferences();
   this->WriteProjectReferences();
+  this->WriteSDKReferences();
   this->WriteString(
     "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\""
     " />\n", 1);
@@ -788,6 +800,20 @@ void cmVisualStudio10TargetGenerator
     (*this->BuildFileStream ) <<
       "android-" << cmVS10EscapeXML(api) << "</AndroidTargetAPI>\n";
     }
+
+  if(const char* cpuArch = this->Target->GetProperty("ANDROID_ARCH"))
+    {
+    this->WriteString("<AndroidArch>", 2);
+    (*this->BuildFileStream) << cmVS10EscapeXML(cpuArch) <<
+      "</AndroidArch>\n";
+    }
+
+  if(const char* stlType = this->Target->GetProperty("ANDROID_STL_TYPE"))
+    {
+    this->WriteString("<AndroidStlType>", 2);
+    (*this->BuildFileStream) << cmVS10EscapeXML(stlType) <<
+      "</AndroidStlType>\n";
+    }
 }
 
 void cmVisualStudio10TargetGenerator::WriteCustomCommands()
@@ -848,6 +874,9 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile const* source,
         fout << "# generated from CMake\n";
         fout.flush();
         fout.close();
+        // Force given file to have a very old timestamp, thus
+        // preventing dependent rebuilds.
+        this->ForceOld(sourcePath);
         }
       else
         {
@@ -867,7 +896,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile const* source,
         i = this->Configurations.begin();
       i != this->Configurations.end(); ++i)
     {
-    cmCustomCommandGenerator ccg(command, *i, this->Makefile);
+    cmCustomCommandGenerator ccg(command, *i, this->LocalGenerator);
     std::string comment = lg->ConstructComment(ccg);
     comment = cmVS10EscapeComment(comment);
     std::string script =
@@ -923,10 +952,7 @@ cmVisualStudio10TargetGenerator::ConvertPath(std::string const& path,
   return forceRelative
     ? cmSystemTools::RelativePath(
       this->Makefile->GetCurrentBinaryDirectory(), path.c_str())
-    : this->LocalGenerator->Convert(path.c_str(),
-                                    cmLocalGenerator::START_OUTPUT,
-                                    cmLocalGenerator::UNCHANGED,
-                                    /* optional = */ true);
+    : path.c_str();
 }
 
 void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s)
@@ -945,7 +971,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
   std::vector<cmSourceGroup> sourceGroups =
     this->Makefile->GetSourceGroups();
   std::vector<cmSourceFile*> classes;
-  if (!this->Target->GetConfigCommonSourceFiles(classes))
+  if (!this->GeneratorTarget->GetConfigCommonSourceFiles(classes))
     {
     return;
     }
@@ -1084,7 +1110,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
       (*this->BuildFileStream) << name << "\">\n";
       std::string guidName = "SG_Filter_";
       guidName += name;
-      this->GlobalGenerator->CreateGUID(guidName.c_str());
       this->WriteString("<UniqueIdentifier>", 3);
       std::string guid
         = this->GlobalGenerator->GetGUID(guidName.c_str());
@@ -1099,7 +1124,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
     {
     this->WriteString("<Filter Include=\"Object Libraries\">\n", 2);
     std::string guidName = "SG_Filter_Object Libraries";
-    this->GlobalGenerator->CreateGUID(guidName.c_str());
     this->WriteString("<UniqueIdentifier>", 3);
     std::string guid =
       this->GlobalGenerator->GetGUID(guidName.c_str());
@@ -1112,7 +1136,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
     {
     this->WriteString("<Filter Include=\"Resource Files\">\n", 2);
     std::string guidName = "SG_Filter_Resource Files";
-    this->GlobalGenerator->CreateGUID(guidName.c_str());
     this->WriteString("<UniqueIdentifier>", 3);
     std::string guid =
       this->GlobalGenerator->GetGUID(guidName.c_str());
@@ -1282,10 +1305,15 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
     {
     tool = "Image";
     }
+  else if(ext == "resw")
+    {
+    tool = "PRIResource";
+    }
   else if(ext == "xml")
     {
     tool = "XML";
     }
+
   if(this->NsightTegra)
     {
     // Nsight Tegra needs specific file types to check up-to-dateness.
@@ -1610,7 +1638,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
     this->GlobalGenerator->GetLanguageFromExtension
     (sf.GetExtension().c_str());
   std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
-  const std::string& linkLanguage = this->Target->GetLinkerLanguage();
+  const std::string& linkLanguage = this->GeneratorTarget->GetLinkerLanguage();
   bool needForceLang = false;
   // source file does not match its extension language
   if(lang != sourceLang)
@@ -1639,7 +1667,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
   // for the first time we need a new line if there is something
   // produced here.
   const char* firstString = ">\n";
-  if(objectName.size())
+  if(!objectName.empty())
     {
     (*this->BuildFileStream ) << firstString;
     firstString = "";
@@ -1658,7 +1686,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
     defPropName += configUpper;
     if(const char* ccdefs = sf.GetProperty(defPropName.c_str()))
       {
-      if(configDefines.size())
+      if(!configDefines.empty())
         {
         configDefines += ";";
         }
@@ -1757,7 +1785,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
       else
         {
         outDir = this->Target->GetDirectory(config->c_str()) + "/";
-        targetNameFull = this->Target->GetFullName(config->c_str());
+        targetNameFull = this->GeneratorTarget->GetFullName(config->c_str());
         }
       this->ConvertToWindowsSlash(intermediateDir);
       this->ConvertToWindowsSlash(outDir);
@@ -1871,7 +1899,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
 
   std::string flags;
   const std::string& linkLanguage =
-    this->Target->GetLinkerLanguage(configName.c_str());
+    this->GeneratorTarget->GetLinkerLanguage(configName.c_str());
   if(linkLanguage.empty())
     {
     cmSystemTools::Error
@@ -1917,7 +1945,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
   clOptions.Parse(flags.c_str());
   clOptions.Parse(defineFlags.c_str());
   std::vector<std::string> targetDefines;
-  this->Target->GetCompileDefinitions(targetDefines,
+  this->GeneratorTarget->GetCompileDefinitions(targetDefines,
                                       configName.c_str(), "CXX");
   clOptions.AddDefines(targetDefines);
   if(this->MSTools)
@@ -1985,6 +2013,17 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
   clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, "      ",
                                           "\n", "CXX");
 
+  if(this->NsightTegra)
+    {
+    if(const char* processMax =
+        this->Target->GetProperty("ANDROID_PROCESS_MAX"))
+      {
+      this->WriteString("<ProcessMax>", 3);
+      *this->BuildFileStream << cmVS10EscapeXML(processMax) <<
+        "</ProcessMax>\n";
+      }
+    }
+
   if(this->MSTools)
     {
     this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
@@ -1998,7 +2037,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
       }
 
     // Specify the compiler program database file if configured.
-    std::string pdb = this->Target->GetCompilePDBPath(configName.c_str());
+    std::string pdb =
+        this->GeneratorTarget->GetCompilePDBPath(configName.c_str());
     if(!pdb.empty())
       {
       this->ConvertToWindowsSlash(pdb);
@@ -2174,10 +2214,37 @@ cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
     }
 }
 
+void cmVisualStudio10TargetGenerator::WriteManifestOptions(
+  std::string const& config)
+{
+  if (this->Target->GetType() != cmTarget::EXECUTABLE &&
+      this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
+      this->Target->GetType() != cmTarget::MODULE_LIBRARY)
+    {
+    return;
+    }
+
+  std::vector<cmSourceFile const*> manifest_srcs;
+  this->GeneratorTarget->GetManifests(manifest_srcs, config);
+  if (!manifest_srcs.empty())
+    {
+    this->WriteString("<Manifest>\n", 2);
+    this->WriteString("<AdditionalManifestFiles>", 3);
+    for (std::vector<cmSourceFile const*>::const_iterator
+           mi = manifest_srcs.begin(); mi != manifest_srcs.end(); ++mi)
+      {
+      std::string m = this->ConvertPath((*mi)->GetFullPath(), false);
+      this->ConvertToWindowsSlash(m);
+      (*this->BuildFileStream) << m << ";";
+      }
+    (*this->BuildFileStream) << "</AdditionalManifestFiles>\n";
+    this->WriteString("</Manifest>\n", 2);
+    }
+}
 
 //----------------------------------------------------------------------------
 void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
-  std::string const&)
+  std::string const& configName)
 {
   // Look through the sources for AndroidManifest.xml and use
   // its location as the root source directory.
@@ -2207,6 +2274,92 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
     cmVS10EscapeXML(antBuildPath) << "</AntBuildPath>\n";
   }
 
+  if (this->Target->GetPropertyAsBool("ANDROID_SKIP_ANT_STEP"))
+    {
+    this->WriteString("<SkipAntStep>true</SkipAntStep>\n", 3);
+    }
+
+  if (this->Target->GetPropertyAsBool("ANDROID_PROGUARD"))
+    {
+    this->WriteString("<EnableProGuard>true</EnableProGuard>\n", 3);
+    }
+
+  if (const char* proGuardConfigLocation =
+      this->Target->GetProperty("ANDROID_PROGUARD_CONFIG_PATH"))
+    {
+    this->WriteString("<ProGuardConfigLocation>", 3);
+    (*this->BuildFileStream) << cmVS10EscapeXML(proGuardConfigLocation) <<
+      "</ProGuardConfigLocation>\n";
+    }
+
+  if (const char* securePropertiesLocation =
+      this->Target->GetProperty("ANDROID_SECURE_PROPS_PATH"))
+    {
+    this->WriteString("<SecurePropertiesLocation>", 3);
+    (*this->BuildFileStream) << cmVS10EscapeXML(securePropertiesLocation) <<
+      "</SecurePropertiesLocation>\n";
+    }
+
+  if (const char* nativeLibDirectoriesExpression =
+      this->Target->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES"))
+    {
+    cmGeneratorExpression ge;
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+        ge.Parse(nativeLibDirectoriesExpression);
+    std::string nativeLibDirs = cge->Evaluate(this->Makefile, configName);
+    this->WriteString("<NativeLibDirectories>", 3);
+    (*this->BuildFileStream) << cmVS10EscapeXML(nativeLibDirs) <<
+      "</NativeLibDirectories>\n";
+    }
+
+  if (const char* nativeLibDependenciesExpression =
+      this->Target->GetProperty("ANDROID_NATIVE_LIB_DEPENDENCIES"))
+    {
+    cmGeneratorExpression ge;
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+        ge.Parse(nativeLibDependenciesExpression);
+    std::string nativeLibDeps = cge->Evaluate(this->Makefile, configName);
+    this->WriteString("<NativeLibDependencies>", 3);
+    (*this->BuildFileStream) << cmVS10EscapeXML(nativeLibDeps) <<
+      "</NativeLibDependencies>\n";
+    }
+
+  if (const char* javaSourceDir =
+      this->Target->GetProperty("ANDROID_JAVA_SOURCE_DIR"))
+    {
+    this->WriteString("<JavaSourceDir>", 3);
+    (*this->BuildFileStream) << cmVS10EscapeXML(javaSourceDir) <<
+      "</JavaSourceDir>\n";
+    }
+
+  if (const char* jarDirectoriesExpression =
+      this->Target->GetProperty("ANDROID_JAR_DIRECTORIES"))
+    {
+    cmGeneratorExpression ge;
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+      ge.Parse(jarDirectoriesExpression);
+    std::string jarDirectories = cge->Evaluate(this->Makefile, configName);
+    this->WriteString("<JarDirectories>", 3);
+    (*this->BuildFileStream) << cmVS10EscapeXML(jarDirectories) <<
+      "</JarDirectories>\n";
+    }
+
+  if (const char* jarDeps =
+      this->Target->GetProperty("ANDROID_JAR_DEPENDENCIES"))
+    {
+    this->WriteString("<JarDependencies>", 3);
+    (*this->BuildFileStream) << cmVS10EscapeXML(jarDeps) <<
+      "</JarDependencies>\n";
+    }
+
+  if (const char* assetsDirectories =
+      this->Target->GetProperty("ANDROID_ASSETS_DIRECTORIES"))
+    {
+    this->WriteString("<AssetsDirectories>", 3);
+    (*this->BuildFileStream) << cmVS10EscapeXML(assetsDirectories) <<
+      "</AssetsDirectories>\n";
+    }
+
   {
   std::string manifest_xml = rootDir + "/AndroidManifest.xml";
   this->ConvertToWindowsSlash(manifest_xml);
@@ -2215,6 +2368,14 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
     cmVS10EscapeXML(manifest_xml) << "</AndroidManifestLocation>\n";
   }
 
+  if (const char* antAdditionalOptions =
+      this->Target->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS"))
+    {
+    this->WriteString("<AdditionalOptions>", 3);
+    (*this->BuildFileStream) << cmVS10EscapeXML(antAdditionalOptions) <<
+      " %(AdditionalOptions)</AdditionalOptions>\n";
+    }
+
   this->WriteString("</AntBuild>\n", 2);
 }
 
@@ -2248,7 +2409,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
   Options& linkOptions = *pOptions;
 
   const std::string& linkLanguage =
-    this->Target->GetLinkerLanguage(config.c_str());
+    this->GeneratorTarget->GetLinkerLanguage(config.c_str());
   if(linkLanguage.empty())
     {
     cmSystemTools::Error
@@ -2299,7 +2460,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
     libs = this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
   // Remove trailing spaces from libs
   std::string::size_type pos = libs.size()-1;
-  if(libs.size() != 0)
+  if(!libs.empty())
     {
     while(libs[pos] == ' ')
       {
@@ -2316,7 +2477,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
   cmSystemTools::ExpandListArgument(libs, libVec);
 
   cmComputeLinkInformation* pcli =
-    this->Target->GetLinkInformation(config.c_str());
+    this->GeneratorTarget->GetLinkInformation(config.c_str());
   if(!pcli)
     {
     cmSystemTools::Error
@@ -2349,13 +2510,14 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
   std::string targetNamePDB;
   if(this->Target->GetType() == cmTarget::EXECUTABLE)
     {
-    this->Target->GetExecutableNames(targetName, targetNameFull,
+    this->GeneratorTarget->GetExecutableNames(targetName, targetNameFull,
                                      targetNameImport, targetNamePDB,
                                      config.c_str());
     }
   else
     {
-    this->Target->GetLibraryNames(targetName, targetNameSO, targetNameFull,
+    this->GeneratorTarget->GetLibraryNames(targetName, targetNameSO,
+                                  targetNameFull,
                                   targetNameImport, targetNamePDB,
                                   config.c_str());
     }
@@ -2435,7 +2597,8 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
 
     // A Windows Runtime component uses internal .NET metadata,
     // so does not have an import library.
-    if(this->Target->GetPropertyAsBool("VS_WINRT_COMPONENT"))
+    if(this->Target->GetPropertyAsBool("VS_WINRT_COMPONENT") &&
+       this->Target->GetType() != cmTarget::EXECUTABLE)
       {
       linkOptions.AddFlag("GenerateWindowsMetadata", "true");
       }
@@ -2473,6 +2636,15 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
                            "%(IgnoreSpecificDefaultLibraries)");
     }
 
+  if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if (this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)exportall.def");
+      }
+    }
+
   this->LinkOptions[config] = pOptions.release();
   return true;
 }
@@ -2497,7 +2669,7 @@ cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config)
     {
     this->WriteString("<ProjectReference>\n", 2);
     this->WriteString(
-      "  <LinkLibraryDependencies>false</LinkLibraryDependencies>\n", 2);
+      "<LinkLibraryDependencies>false</LinkLibraryDependencies>\n", 3);
     this->WriteString("</ProjectReference>\n", 2);
     }
 }
@@ -2607,6 +2779,8 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
     this->WriteLinkOptions(*i);
     //    output lib flags       <Lib></Lib>
     this->WriteLibOptions(*i);
+    //    output manifest flags  <Manifest></Manifest>
+    this->WriteManifestOptions(*i);
     if(this->NsightTegra &&
        this->Target->GetType() == cmTarget::EXECUTABLE &&
        this->Target->GetPropertyAsBool("ANDROID_GUI"))
@@ -2620,8 +2794,25 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
 void
 cmVisualStudio10TargetGenerator::WriteEvents(std::string const& configName)
 {
-  this->WriteEvent("PreLinkEvent",
-                   this->Target->GetPreLinkCommands(), configName);
+  bool addedPrelink = false;
+  if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if (this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      addedPrelink = true;
+      std::vector<cmCustomCommand> commands =
+        this->Target->GetPreLinkCommands();
+      this->GlobalGenerator->AddSymbolExportCommand(
+        this->GeneratorTarget, commands, configName);
+      this->WriteEvent("PreLinkEvent", commands, configName);
+      }
+    }
+  if (!addedPrelink)
+    {
+    this->WriteEvent("PreLinkEvent",
+                     this->Target->GetPreLinkCommands(), configName);
+    }
   this->WriteEvent("PreBuildEvent",
                    this->Target->GetPreBuildCommands(), configName);
   this->WriteEvent("PostBuildEvent",
@@ -2633,7 +2824,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
   std::vector<cmCustomCommand> const& commands,
   std::string const& configName)
 {
-  if(commands.size() == 0)
+  if(commands.empty())
     {
     return;
     }
@@ -2646,7 +2837,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
   for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
       i != commands.end(); ++i)
     {
-    cmCustomCommandGenerator ccg(*i, configName, this->Makefile);
+    cmCustomCommandGenerator ccg(*i, configName, this->LocalGenerator);
     comment += pre;
     comment += lg->ConstructComment(ccg);
     script += pre;
@@ -2667,15 +2858,15 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
 void cmVisualStudio10TargetGenerator::WriteProjectReferences()
 {
   cmGlobalGenerator::TargetDependSet const& unordered
-    = this->GlobalGenerator->GetTargetDirectDepends(*this->Target);
+    = this->GlobalGenerator->GetTargetDirectDepends(this->GeneratorTarget);
   typedef cmGlobalVisualStudioGenerator::OrderedTargetDependSet
     OrderedTargetDependSet;
-  OrderedTargetDependSet depends(unordered);
+  OrderedTargetDependSet depends(unordered, CMAKE_CHECK_BUILD_SYSTEM_TARGET);
   this->WriteString("<ItemGroup>\n", 1);
   for( OrderedTargetDependSet::const_iterator i = depends.begin();
        i != depends.end(); ++i)
     {
-    cmTarget const* dt = *i;
+    cmTarget const* dt = (*i)->Target;
     if(dt->GetType() == cmTarget::INTERFACE_LIBRARY)
       {
       continue;
@@ -2713,6 +2904,101 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
   this->WriteString("</ItemGroup>\n", 1);
 }
 
+void cmVisualStudio10TargetGenerator::WritePlatformExtensions()
+{
+  // This only applies to Windows 10 apps
+  if (this->GlobalGenerator->TargetsWindowsStore() &&
+      cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0"))
+    {
+    const char* desktopExtensionsVersion =
+      this->Target->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
+    if (desktopExtensionsVersion)
+      {
+      this->WriteSinglePlatformExtension("WindowsDesktop",
+                                         desktopExtensionsVersion);
+      }
+    const char* mobileExtensionsVersion =
+      this->Target->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
+    if (mobileExtensionsVersion)
+      {
+      this->WriteSinglePlatformExtension("WindowsMobile",
+                                         mobileExtensionsVersion);
+      }
+    }
+}
+
+void cmVisualStudio10TargetGenerator::WriteSinglePlatformExtension(
+  std::string const& extension,
+  std::string const& version
+  )
+{
+  this->WriteString("<Import Project=", 2);
+  (*this->BuildFileStream)
+    << "\"$([Microsoft.Build.Utilities.ToolLocationHelper]"
+    << "::GetPlatformExtensionSDKLocation(`"
+    << extension <<", Version=" << version
+    << "`, $(TargetPlatformIdentifier), $(TargetPlatformVersion), null, "
+    << "$(ExtensionSDKDirectoryRoot), null))"
+    << "\\DesignTime\\CommonConfiguration\\Neutral\\"
+    << extension << ".props\" "
+    << "Condition=\"exists('$("
+    << "[Microsoft.Build.Utilities.ToolLocationHelper]"
+    << "::GetPlatformExtensionSDKLocation(`"
+    << extension << ", Version=" << version
+    << "`, $(TargetPlatformIdentifier), $(TargetPlatformVersion), null, "
+    << "$(ExtensionSDKDirectoryRoot), null))"
+    << "\\DesignTime\\CommonConfiguration\\Neutral\\"
+    << extension << ".props')\" />\n";
+}
+
+void cmVisualStudio10TargetGenerator::WriteSDKReferences()
+{
+  // This only applies to Windows 10 apps
+  if (this->GlobalGenerator->TargetsWindowsStore() &&
+      cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0"))
+    {
+    const char* desktopExtensionsVersion =
+      this->Target->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
+    const char* mobileExtensionsVersion =
+      this->Target->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
+    const char* iotExtensionsVersion =
+      this->Target->GetProperty("VS_IOT_EXTENSIONS_VERSION");
+
+    if(desktopExtensionsVersion || mobileExtensionsVersion ||
+       iotExtensionsVersion)
+      {
+      this->WriteString("<ItemGroup>\n", 1);
+      if(desktopExtensionsVersion)
+        {
+        this->WriteSingleSDKReference("WindowsDesktop",
+                                      desktopExtensionsVersion);
+        }
+      if(mobileExtensionsVersion)
+        {
+        this->WriteSingleSDKReference("WindowsMobile",
+                                      mobileExtensionsVersion);
+        }
+      if(iotExtensionsVersion)
+        {
+        this->WriteSingleSDKReference("WindowsIoT",
+                                      iotExtensionsVersion);
+        }
+      this->WriteString("</ItemGroup>\n", 1);
+      }
+    }
+}
+
+void cmVisualStudio10TargetGenerator::WriteSingleSDKReference(
+  std::string const& extension,
+  std::string const& version
+  )
+{
+  this->WriteString("<SDKReference Include=\"", 2);
+  (*this->BuildFileStream) << extension
+    << ", Version=" << version << "\" />\n";
+}
+
+
 void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
 {
   if((this->GlobalGenerator->TargetsWindowsStore() ||
@@ -2743,7 +3029,7 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
       (*this->BuildFileStream) << cmVS10EscapeXML(artifactDir) <<
         "\\</AppxPackageArtifactsDir>\n";
       this->WriteString("<ProjectPriFullPath>"
-        "$(TargetDir)resources.pri</ProjectPriFullPath>", 2);
+        "$(TargetDir)resources.pri</ProjectPriFullPath>\n", 2);
 
       // If we are missing files and we don't have a certificate and
       // aren't targeting WP8.0, add a default certificate
@@ -2761,6 +3047,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
       this->WriteString("<", 2);
       (*this->BuildFileStream) << "PackageCertificateKeyFile>"
         << pfxFile << "</PackageCertificateKeyFile>\n";
+      std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
+      if (!thumb.empty())
+        {
+        this->WriteString("<PackageCertificateThumbprint>", 2);
+        (*this->BuildFileStream) << thumb
+          << "</PackageCertificateThumbprint>\n";
+        }
       this->WriteString("</PropertyGroup>\n", 1);
       }
     else if(!pfxFile.empty())
@@ -2769,6 +3062,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
       this->WriteString("<", 2);
       (*this->BuildFileStream) << "PackageCertificateKeyFile>"
         << pfxFile << "</PackageCertificateKeyFile>\n";
+      std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
+      if (!thumb.empty())
+        {
+        this->WriteString("<PackageCertificateThumbprint>", 2);
+        (*this->BuildFileStream) << thumb
+          << "</PackageCertificateThumbprint>\n";
+        }
       this->WriteString("</PropertyGroup>\n", 1);
       }
     }
@@ -2809,6 +3109,8 @@ IsXamlSource(const std::string& sourceFile)
 
 void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings()
 {
+  cmGlobalVisualStudio10Generator* gg =
+    static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
   bool isAppContainer = false;
   bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone();
   bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore();
@@ -2819,13 +3121,27 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings()
     (*this->BuildFileStream) << (isWindowsPhone ?
                                  "Windows Phone" : "Windows Store")
                              << "</ApplicationType>\n";
-    this->WriteString("<ApplicationTypeRevision>", 2);
-    (*this->BuildFileStream) << cmVS10EscapeXML(v)
-                             << "</ApplicationTypeRevision>\n";
     this->WriteString("<DefaultLanguage>en-US"
                       "</DefaultLanguage>\n", 2);
-    if(v == "8.1")
+    if (cmHasLiteralPrefix(v, "10.0"))
       {
+      this->WriteString("<ApplicationTypeRevision>", 2);
+      (*this->BuildFileStream) << cmVS10EscapeXML("10.0")
+                               << "</ApplicationTypeRevision>\n";
+      // Visual Studio 14.0 is necessary for building 10.0 apps
+      this->WriteString("<MinimumVisualStudioVersion>14.0"
+        "</MinimumVisualStudioVersion>\n", 2);
+
+      if(this->Target->GetType() < cmTarget::UTILITY)
+        {
+        isAppContainer = true;
+        }
+      }
+    else if(v == "8.1")
+      {
+      this->WriteString("<ApplicationTypeRevision>", 2);
+      (*this->BuildFileStream) << cmVS10EscapeXML(v)
+                               << "</ApplicationTypeRevision>\n";
       // Visual Studio 12.0 is necessary for building 8.1 apps
       this->WriteString("<MinimumVisualStudioVersion>12.0"
                         "</MinimumVisualStudioVersion>\n", 2);
@@ -2837,6 +3153,9 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings()
       }
     else if (v == "8.0")
       {
+      this->WriteString("<ApplicationTypeRevision>", 2);
+      (*this->BuildFileStream) << cmVS10EscapeXML(v)
+                               << "</ApplicationTypeRevision>\n";
       // Visual Studio 11.0 is necessary for building 8.0 apps
       this->WriteString("<MinimumVisualStudioVersion>11.0"
                         "</MinimumVisualStudioVersion>\n", 2);
@@ -2865,6 +3184,38 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings()
     this->WriteString("<WindowsSDKDesktopARMSupport>true"
                       "</WindowsSDKDesktopARMSupport>\n", 2);
     }
+  std::string const& targetPlatformVersion =
+    gg->GetWindowsTargetPlatformVersion();
+  if (!targetPlatformVersion.empty())
+    {
+    this->WriteString("<WindowsTargetPlatformVersion>", 2);
+    (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformVersion) <<
+      "</WindowsTargetPlatformVersion>\n";
+    }
+  const char* targetPlatformMinVersion =
+      this->Target->GetProperty("VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION");
+  if(targetPlatformMinVersion)
+    {
+    this->WriteString("<WindowsTargetPlatformMinVersion>", 2);
+    (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformMinVersion) <<
+      "</WindowsTargetPlatformMinVersion>\n";
+    }
+  else if (isWindowsStore && cmHasLiteralPrefix(v, "10.0"))
+    {
+    // If the min version is not set, then use the TargetPlatformVersion
+    if (!targetPlatformVersion.empty())
+      {
+      this->WriteString("<WindowsTargetPlatformMinVersion>", 2);
+      (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformVersion) <<
+        "</WindowsTargetPlatformMinVersion>\n";
+      }
+    }
+
+  // Added IoT Startup Task support
+  if(this->Target->GetPropertyAsBool("VS_IOT_STARTUP_TASK"))
+    {
+    this->WriteString("<ContainsStartupTask>true</ContainsStartupTask>\n", 2);
+    }
 }
 
 void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()
@@ -2917,7 +3268,7 @@ void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()
             {
             this->IsMissingFiles = true;
             }
-          else if (v == "8.1")
+          else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0"))
             {
             this->IsMissingFiles = true;
             }
@@ -2951,6 +3302,10 @@ void cmVisualStudio10TargetGenerator::WriteMissingFiles()
      {
      this->WriteMissingFilesWS81();
      }
+   else if (cmHasLiteralPrefix(v, "10.0"))
+     {
+     this->WriteMissingFilesWS10_0();
+     }
    }
 }
 
@@ -3212,6 +3567,64 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWS81()
   this->WriteCommonMissingFiles(manifestFile);
 }
 
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWS10_0()
+{
+  std::string manifestFile =
+    this->DefaultArtifactDir + "/package.appxManifest";
+  std::string artifactDir =
+    this->LocalGenerator->GetTargetDirectory(*this->Target);
+  this->ConvertToWindowsSlash(artifactDir);
+  std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+  std::string targetNameXML = cmVS10EscapeXML(this->Target->GetName());
+
+  cmGeneratedFileStream fout(manifestFile.c_str());
+  fout.SetCopyIfDifferent(true);
+
+  fout <<
+    "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+    "<Package\n\t"
+    "xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\""
+    "\txmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\"\n"
+    "\txmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\""
+    "\n\tIgnorableNamespaces=\"uap mp\">\n\n"
+    "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\""
+    " Version=\"1.0.0.0\" />\n"
+    "\t<mp:PhoneIdentity PhoneProductId=\"" << this->GUID <<
+    "\" PhonePublisherId=\"00000000-0000-0000-0000-000000000000\"/>\n"
+    "\t<Properties>\n"
+    "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n"
+    "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n"
+    "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n"
+    "\t</Properties>\n"
+    "\t<Dependencies>\n"
+    "\t\t<TargetDeviceFamily Name=\"Windows.Universal\" "
+    "MinVersion=\"10.0.0.0\" MaxVersionTested=\"10.0.0.0\" />\n"
+    "\t</Dependencies>\n"
+
+    "\t<Resources>\n"
+    "\t\t<Resource Language=\"x-generate\" />\n"
+    "\t</Resources>\n"
+    "\t<Applications>\n"
+    "\t\t<Application Id=\"App\""
+    " Executable=\"" << targetNameXML << ".exe\""
+    " EntryPoint=\"" << targetNameXML << ".App\">\n"
+    "\t\t\t<uap:VisualElements\n"
+    "\t\t\t\tDisplayName=\"" << targetNameXML << "\"\n"
+    "\t\t\t\tDescription=\"" << targetNameXML << "\"\n"
+    "\t\t\t\tBackgroundColor=\"#336699\"\n"
+    "\t\t\t\tSquare150x150Logo=\"" << artifactDirXML << "\\Logo.png\"\n"
+    "\t\t\t\tSquare44x44Logo=\"" << artifactDirXML <<
+    "\\SmallLogo44x44.png\">\n"
+    "\t\t\t\t<uap:SplashScreen"
+    " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n"
+    "\t\t\t</uap:VisualElements>\n"
+    "\t\t</Application>\n"
+    "\t</Applications>\n"
+    "</Package>\n";
+
+  this->WriteCommonMissingFiles(manifestFile);
+}
+
 void
 cmVisualStudio10TargetGenerator
 ::WriteCommonMissingFiles(const std::string& manifestFile)
@@ -3235,6 +3648,14 @@ cmVisualStudio10TargetGenerator
   (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo) << "\" />\n";
   this->AddedFiles.push_back(smallLogo);
 
+  std::string smallLogo44 = this->DefaultArtifactDir + "/SmallLogo44x44.png";
+  cmSystemTools::CopyAFile(templateFolder + "/SmallLogo44x44.png",
+                           smallLogo44, false);
+  this->ConvertToWindowsSlash(smallLogo44);
+  this->WriteString("<Image Include=\"", 2);
+  (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo44) << "\" />\n";
+  this->AddedFiles.push_back(smallLogo44);
+
   std::string logo = this->DefaultArtifactDir + "/Logo.png";
   cmSystemTools::CopyAFile(templateFolder + "/Logo.png",
                            logo, false);
@@ -3265,3 +3686,26 @@ cmVisualStudio10TargetGenerator
   this->WriteString("<None Include=\"", 2);
   (*this->BuildFileStream) << cmVS10EscapeXML(keyFile) << "\" />\n";
 }
+
+bool cmVisualStudio10TargetGenerator::ForceOld(const std::string& source) const
+{
+  HANDLE h = CreateFileW(
+    cmSystemTools::ConvertToWindowsExtendedPath(source).c_str(),
+    FILE_WRITE_ATTRIBUTES,
+    FILE_SHARE_WRITE, 0, OPEN_EXISTING,
+    FILE_FLAG_BACKUP_SEMANTICS, 0);
+  if (!h)
+    {
+    return false;
+    }
+
+  FILETIME const ftime_20010101 = { 3365781504u, 29389701u };
+  if (!SetFileTime(h, &ftime_20010101, &ftime_20010101, &ftime_20010101))
+    {
+    CloseHandle(h);
+    return false;
+    }
+
+  CloseHandle(h);
+  return true;
+}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 451f8b2..15ed9f2 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -78,6 +78,13 @@ private:
   void WriteMissingFilesWP81();
   void WriteMissingFilesWS80();
   void WriteMissingFilesWS81();
+  void WriteMissingFilesWS10_0();
+  void WritePlatformExtensions();
+  void WriteSinglePlatformExtension(std::string const& extension,
+                                    std::string const& version);
+  void WriteSDKReferences();
+  void WriteSingleSDKReference(std::string const& extension,
+                               std::string const& version);
   void WriteCommonMissingFiles(const std::string& manifestFile);
   void WriteTargetSpecificReferences();
 
@@ -111,6 +118,7 @@ private:
   void AddLibraries(cmComputeLinkInformation& cli,
                     std::vector<std::string>& libVec);
   void WriteLibOptions(std::string const& config);
+  void WriteManifestOptions(std::string const& config);
   void WriteEvents(std::string const& configName);
   void WriteEvent(const char* name,
                   std::vector<cmCustomCommand> const& commands,
@@ -129,6 +137,8 @@ private:
   cmIDEFlagTable const* GetLinkFlagTable() const;
   cmIDEFlagTable const* GetMasmFlagTable() const;
 
+  bool ForceOld(const std::string& source) const;
+
 private:
   typedef cmVisualStudioGeneratorOptions Options;
   typedef std::map<std::string, Options*> OptionsMap;
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 6512fc2..bd4eb69 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -1,6 +1,6 @@
 #include "cmVisualStudioGeneratorOptions.h"
+#include "cmOutputConverter.h"
 #include "cmSystemTools.h"
-#include <cmsys/System.h>
 #include "cmVisualStudio10TargetGenerator.h"
 
 static
@@ -246,10 +246,10 @@ void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag)
   // This option is not known.  Store it in the output flags.
   this->FlagString += " ";
   this->FlagString +=
-    cmSystemTools::EscapeWindowsShellArgument(
+    cmOutputConverter::EscapeWindowsShellArgument(
       flag,
-      cmsysSystem_Shell_Flag_AllowMakeVariables |
-      cmsysSystem_Shell_Flag_VSIDE);
+      cmOutputConverter::Shell_Flag_AllowMakeVariables |
+      cmOutputConverter::Shell_Flag_VSIDE);
 }
 
 //----------------------------------------------------------------------------
@@ -274,7 +274,7 @@ cmVisualStudioGeneratorOptions
     {
     // if there are configuration specific flags, then
     // use the configuration specific tag for PreprocessorDefinitions
-    if(this->Configuration.size())
+    if(!this->Configuration.empty())
       {
       fout << prefix;
       this->TargetGenerator->WritePlatformConfigTag(
@@ -346,7 +346,7 @@ cmVisualStudioGeneratorOptions
         m != this->FlagMap.end(); ++m)
       {
       fout << indent;
-      if(this->Configuration.size())
+      if(!this->Configuration.empty())
         {
         this->TargetGenerator->WritePlatformConfigTag(
           m->first.c_str(),
@@ -398,7 +398,7 @@ cmVisualStudioGeneratorOptions
     if(this->Version >= cmGlobalVisualStudioGenerator::VS10)
       {
       fout << prefix;
-      if(this->Configuration.size())
+      if(!this->Configuration.empty())
         {
         this->TargetGenerator->WritePlatformConfigTag(
           "AdditionalOptions",
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 012c580..4b7afd8 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -49,7 +49,20 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
       mf.ExpandArguments(this->Args, expandedArguments);
       cmake::MessageType messageType;
 
-      cmConditionEvaluator conditionEvaluator(mf);
+      cmListFileContext execContext = this->GetStartingContext();
+
+      cmCommandContext commandContext;
+      commandContext.Line = execContext.Line;
+      commandContext.Name = execContext.Name;
+
+      cmListFileContext conditionContext =
+          cmConditionEvaluator::GetConditionContext(
+            &mf, commandContext,
+            this->GetStartingContext().FilePath);
+
+      cmConditionEvaluator conditionEvaluator(
+            mf, conditionContext,
+            mf.GetBacktrace(commandContext));
 
       bool isTrue = conditionEvaluator.IsTrue(
         expandedArguments, errorString, messageType);
diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h
index 0d06878..89dc9ff 100644
--- a/Source/cmWriteFileCommand.h
+++ b/Source/cmWriteFileCommand.h
@@ -46,12 +46,6 @@ public:
    */
   virtual std::string GetName() const { return "write_file";}
 
-  /** This command is kept for compatibility with older CMake versions. */
-  virtual bool IsDiscouraged() const
-    {
-    return true;
-    }
-
   cmTypeMacro(cmWriteFileCommand, cmCommand);
 };
 
diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx
index f30f700..3973540 100644
--- a/Source/cmXCode21Object.cxx
+++ b/Source/cmXCode21Object.cxx
@@ -22,7 +22,7 @@ cmXCode21Object::cmXCode21Object(PBXType ptype, Type type)
 //----------------------------------------------------------------------------
 void cmXCode21Object::PrintComment(std::ostream& out)
 {
-  if(this->Comment.size() == 0)
+  if(this->Comment.empty())
     {
     cmXCodeObject* n = this->GetObject("name");
     if(n)
diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
index ba6e395..c59c360 100644
--- a/Source/cmXCodeObject.cxx
+++ b/Source/cmXCodeObject.cxx
@@ -243,7 +243,11 @@ void cmXCodeObject::PrintString(std::ostream& os,std::string String)
   bool needQuote =
     (String.empty() ||
      String.find("//") != String.npos ||
-     String.find_first_of(" <>+-*=@[](){},~") != String.npos);
+     String.find_first_not_of(
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+       "abcdefghijklmnopqrstuvwxyz"
+       "0123456789"
+       "$_./") != String.npos);
   const char* quote = needQuote? "\"" : "";
 
   // Print the string, quoted and escaped as necessary.
diff --git a/Source/cmXMLSafe.cxx b/Source/cmXMLSafe.cxx
index 99f5625..4ad05ca 100644
--- a/Source/cmXMLSafe.cxx
+++ b/Source/cmXMLSafe.cxx
@@ -13,8 +13,8 @@
 
 #include "cm_utf8.h"
 
-#include <cmsys/ios/iostream>
-#include <cmsys/ios/sstream>
+#include <iostream>
+#include <sstream>
 
 #include <string.h>
 #include <stdio.h>
@@ -45,13 +45,13 @@ cmXMLSafe& cmXMLSafe::Quotes(bool b)
 //----------------------------------------------------------------------------
 std::string cmXMLSafe::str()
 {
-  cmsys_ios::ostringstream ss;
+  std::ostringstream ss;
   ss << *this;
   return ss.str();
 }
 
 //----------------------------------------------------------------------------
-cmsys_ios::ostream& operator<<(cmsys_ios::ostream& os, cmXMLSafe const& self)
+std::ostream& operator<<(std::ostream& os, cmXMLSafe const& self)
 {
   char const* first = self.Data;
   char const* last = self.Data + self.Size;
diff --git a/Source/cmXMLSafe.h b/Source/cmXMLSafe.h
index c23a90c..ead2e01 100644
--- a/Source/cmXMLSafe.h
+++ b/Source/cmXMLSafe.h
@@ -12,8 +12,9 @@
 #ifndef cmXMLSafe_h
 #define cmXMLSafe_h
 
-#include <cmsys/stl/string>
-#include <cmsys/ios/iosfwd>
+#include <cmsys/Configure.hxx>
+#include <string>
+#include <iosfwd>
 
 /** \class cmXMLSafe
  * \brief Write strings to XML with proper escapes
@@ -37,8 +38,7 @@ private:
   char const* Data;
   unsigned long Size;
   bool DoQuotes;
-  friend cmsys_ios::ostream& operator<<(cmsys_ios::ostream&,
-                                        cmXMLSafe const&);
+  friend std::ostream& operator<<(std::ostream&, cmXMLSafe const&);
 };
 
 #endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 23803ef..386f6a5 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -75,7 +75,9 @@
 # include "cmGlobalWatcomWMakeGenerator.h"
 #endif
 #include "cmGlobalUnixMakefileGenerator3.h"
-#include "cmGlobalNinjaGenerator.h"
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include "cmGlobalNinjaGenerator.h"
+#endif
 #include "cmExtraCodeLiteGenerator.h"
 
 #if !defined(CMAKE_BOOT_MINGW)
@@ -121,6 +123,7 @@ void cmWarnUnusedCliWarning(const std::string& variable,
 cmake::cmake()
 {
   this->Trace = false;
+  this->TraceExpand = false;
   this->WarnUninitialized = false;
   this->WarnUnused = false;
   this->WarnUnusedCli = true;
@@ -132,9 +135,8 @@ cmake::cmake()
   this->ClearBuildSystem = false;
   this->FileComparison = new cmFileTimeComparison;
 
-  this->Policies = new cmPolicies();
   this->State = new cmState(this);
-  this->CurrentSnapshot = this->State->CreateSnapshot(cmState::Snapshot());
+  this->CurrentSnapshot = this->State->CreateBaseSnapshot();
 
 #ifdef __APPLE__
   struct rlimit rlp;
@@ -170,7 +172,6 @@ cmake::cmake()
 cmake::~cmake()
 {
   delete this->CacheManager;
-  delete this->Policies;
   delete this->State;
   if (this->GlobalGenerator)
     {
@@ -186,7 +187,7 @@ cmake::~cmake()
 
 void cmake::CleanupCommandsAndMacros()
 {
-  this->State->Reset();
+  this->CurrentSnapshot = this->State->Reset();
   this->State->RemoveUserDefinedCommands();
 }
 
@@ -370,11 +371,14 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
   // read in the list file to fill the cache
   if(path)
     {
+    this->CurrentSnapshot = this->State->Reset();
     std::string homeDir = this->GetHomeDirectory();
     std::string homeOutputDir = this->GetHomeOutputDirectory();
     this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
     this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
-    cmsys::auto_ptr<cmLocalGenerator> lg(gg->MakeLocalGenerator());
+    cmState::Snapshot snapshot = this->GetCurrentSnapshot();
+    cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(gg, snapshot));
+    cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator(mf.get()));
     lg->GetMakefile()->SetCurrentBinaryDirectory
       (cmSystemTools::GetCurrentWorkingDirectory());
     lg->GetMakefile()->SetCurrentSourceDirectory
@@ -414,9 +418,10 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
   cmGlobalGenerator *gg = new cmGlobalGenerator(this);
   this->SetGlobalGenerator(gg);
 
+  cmState::Snapshot snapshot = this->GetCurrentSnapshot();
   // read in the list file to fill the cache
-  cmsys::auto_ptr<cmLocalGenerator> lg(gg->MakeLocalGenerator());
-  cmMakefile* mf = lg->GetMakefile();
+  cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(gg, snapshot));
+  cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator(mf.get()));
   mf->SetCurrentBinaryDirectory
     (cmSystemTools::GetCurrentWorkingDirectory());
   mf->SetCurrentSourceDirectory
@@ -482,7 +487,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
     std::string linkPath;
     std::string flags;
     std::string linkFlags;
-    gg->CreateGeneratorTargets(mf);
+    gg->CreateGeneratorTargets(cmGlobalGenerator::AllTargets, lg.get());
     cmGeneratorTarget *gtgt = gg->GetGeneratorTarget(tgt);
     lg->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags,
                        gtgt, false);
@@ -616,10 +621,17 @@ void cmake::SetArgs(const std::vector<std::string>& args,
       std::cout << "Running with debug output on.\n";
       this->SetDebugOutputOn(true);
       }
+    else if(arg.find("--trace-expand",0) == 0)
+      {
+      std::cout << "Running with expanded trace output on.\n";
+      this->SetTrace(true);
+      this->SetTraceExpand(true);
+      }
     else if(arg.find("--trace",0) == 0)
       {
       std::cout << "Running with trace output on.\n";
       this->SetTrace(true);
+      this->SetTraceExpand(false);
       }
     else if(arg.find("--warn-uninitialized",0) == 0)
       {
@@ -1437,35 +1449,8 @@ int cmake::ActualConfigure()
          cmState::PATH);
       }
     }
-  if(!this->State
-          ->GetInitializedCacheValue("CMAKE_USE_RELATIVE_PATHS"))
-    {
-    this->State->AddCacheEntry
-      ("CMAKE_USE_RELATIVE_PATHS", "OFF",
-       "If true, cmake will use relative paths in makefiles and projects.",
-       cmState::BOOL);
-    if (!this->State->GetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS",
-                                                    "ADVANCED"))
-      {
-      this->State->SetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS",
-                                                 "ADVANCED", "1");
-      }
-    }
-
-  if(cmSystemTools::GetFatalErrorOccured())
-    {
-    const char* makeProgram =
-        this->State->GetInitializedCacheValue("CMAKE_MAKE_PROGRAM");
-    if (!makeProgram || cmSystemTools::IsOff(makeProgram))
-      {
-      // We must have a bad generator selection.  Wipe the cache entry so the
-      // user can select another.
-      this->State->RemoveCacheEntry("CMAKE_GENERATOR");
-      this->State->RemoveCacheEntry("CMAKE_EXTRA_GENERATOR");
-      }
-    }
 
-  cmMakefile* mf=this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+  cmMakefile* mf=this->GlobalGenerator->GetMakefiles()[0];
   if (mf->IsOn("CTEST_USE_LAUNCHERS")
               && !this->State->GetGlobalProperty("RULE_LAUNCH_COMPILE"))
     {
@@ -1625,7 +1610,11 @@ int cmake::Generate()
     {
     return -1;
     }
-  this->GlobalGenerator->DoGenerate();
+  if (!this->GlobalGenerator->Compute())
+    {
+    return -1;
+    }
+  this->GlobalGenerator->Generate();
   if ( !this->GraphVizFile.empty() )
     {
     std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl;
@@ -1714,8 +1703,10 @@ void cmake::AddDefaultGenerators()
 #endif
   this->Generators.push_back(
     cmGlobalUnixMakefileGenerator3::NewFactory());
+#if defined(CMAKE_BUILD_WITH_CMAKE)
   this->Generators.push_back(
     cmGlobalNinjaGenerator::NewFactory());
+#endif
 #if defined(CMAKE_USE_WMAKE)
   this->Generators.push_back(
     cmGlobalWatcomWMakeGenerator::NewFactory());
@@ -1914,8 +1905,8 @@ int cmake::CheckBuildSystem()
   cm.SetHomeDirectory("");
   cm.SetHomeOutputDirectory("");
   cmGlobalGenerator gg(&cm);
-  cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
-  cmMakefile* mf = lg->GetMakefile();
+  cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+  cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator(mf.get()));
   if(!mf->ReadListFile(this->CheckBuildSystemArgument.c_str()) ||
      cmSystemTools::GetErrorOccuredFlag())
     {
@@ -1944,8 +1935,11 @@ int cmake::CheckBuildSystem()
       ggd(this->CreateGlobalGenerator(genName));
     if(ggd.get())
       {
-      cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->MakeLocalGenerator());
-      lgd->ClearDependencies(mf, verbose);
+      cmsys::auto_ptr<cmMakefile> mfd(new cmMakefile(ggd.get(),
+                                                    cm.GetCurrentSnapshot()));
+      cmsys::auto_ptr<cmLocalGenerator> lgd(
+            ggd->CreateLocalGenerator(mfd.get()));
+      lgd->ClearDependencies(mfd.get(), verbose);
       }
     }
 
@@ -2519,7 +2513,6 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
                          cmListFileBacktrace const& bt)
 {
   cmListFileBacktrace backtrace = bt;
-  backtrace.MakeRelative();
 
   std::ostringstream msg;
   if (!this->PrintMessagePreamble(t, msg))
@@ -2595,6 +2588,25 @@ int cmake::Build(const std::string& dir,
     }
   std::string cachePath = dir;
   cmSystemTools::ConvertToUnixSlashes(cachePath);
+  std::string cacheFile = cachePath;
+  cacheFile += "/CMakeCache.txt";
+  if(!cmSystemTools::FileExists(cacheFile.c_str()))
+    {
+    // search in parent directories for cache
+    std::string cmakeFiles = cachePath;
+    cmakeFiles += "/CMakeFiles";
+    if(cmSystemTools::FileExists(cmakeFiles.c_str()))
+      {
+      std::string cachePathFound =
+        cmSystemTools::FileExistsInParentDirectories(
+          "CMakeCache.txt", cachePath.c_str(), "/");
+      if(!cachePathFound.empty())
+        {
+        cachePath = cmSystemTools::GetFilenamePath(cachePathFound);
+        }
+      }
+    }
+
   if(!this->LoadCache(cachePath))
     {
     std::cerr << "Error: could not load cache\n";
diff --git a/Source/cmake.h b/Source/cmake.h
index 12b7e68..9d28cba 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -27,7 +27,6 @@ class cmVariableWatch;
 class cmFileTimeComparison;
 class cmExternalMakefileProjectGenerator;
 class cmDocumentationSection;
-class cmPolicies;
 class cmTarget;
 class cmGeneratedFileStream;
 
@@ -222,9 +221,6 @@ class cmake
   ///! this is called by generators to update the progress
   void UpdateProgress(const char *msg, float prog);
 
-  ///!  get the cmake policies instance
-  cmPolicies *GetPolicies() {return this->Policies;}
-
   ///! Get the variable watch object
   cmVariableWatch* GetVariableWatch() { return this->VariableWatch; }
 
@@ -273,6 +269,8 @@ class cmake
   // Do we want trace output during the cmake run.
   bool GetTrace() { return this->Trace;}
   void SetTrace(bool b) {  this->Trace = b;}
+  bool GetTraceExpand() { return this->TraceExpand;}
+  void SetTraceExpand(bool b) {  this->TraceExpand = b;}
   bool GetWarnUninitialized() { return this->WarnUninitialized;}
   void SetWarnUninitialized(bool b) {  this->WarnUninitialized = b;}
   bool GetWarnUnused() { return this->WarnUnused;}
@@ -301,7 +299,7 @@ class cmake
 
   /** Display a message to the user.  */
   void IssueMessage(cmake::MessageType t, std::string const& text,
-        cmListFileBacktrace const& backtrace = cmListFileBacktrace(NULL));
+        cmListFileBacktrace const& backtrace = cmListFileBacktrace());
   void IssueMessage(cmake::MessageType t, std::string const& text,
         cmListFileContext const& lfc);
 
@@ -339,7 +337,6 @@ protected:
   void AddExtraGenerator(const std::string& name,
                          CreateExtraGeneratorFunctionType newFunction);
 
-  cmPolicies *Policies;
   cmGlobalGenerator *GlobalGenerator;
   cmCacheManager *CacheManager;
   bool SuppressDevWarnings;
@@ -381,6 +378,7 @@ private:
   WorkingMode CurrentWorkingMode;
   bool DebugOutput;
   bool Trace;
+  bool TraceExpand;
   bool WarnUninitialized;
   bool WarnUnused;
   bool WarnUnusedCli;
diff --git a/Source/cmake.version.manifest b/Source/cmake.version.manifest
new file mode 100644
index 0000000..e7010c9
--- /dev/null
+++ b/Source/cmake.version.manifest
@@ -0,0 +1,18 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
+          manifestVersion="1.0"
+		  xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
+   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+       <application>
+           <!-- Windows Vista -->
+           <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+           <!-- Windows 7 -->
+           <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+           <!-- Windows 8 -->
+           <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+           <!-- Windows 8.1 -->
+           <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+           <!-- Windows 10 -->
+           <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+       </application>
+   </compatibility>
+</assembly>
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index e5f4700..a06b26f 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -83,6 +83,7 @@ static const char * cmDocumentationOptions[][2] =
    "useful on one try_compile at a time."},
   {"--debug-output", "Put cmake in a debug mode."},
   {"--trace", "Put cmake in trace mode."},
+  {"--trace-expand", "Put cmake in trace mode with variable expansion."},
   {"--warn-uninitialized", "Warn about uninitialized values."},
   {"--warn-unused-vars", "Warn about unused variables."},
   {"--no-warn-unused-cli", "Don't warn about command line options."},
@@ -113,12 +114,7 @@ static cmMakefile* cmakemainGetMakefile(void *clientdata)
     cmGlobalGenerator* gg=cm->GetGlobalGenerator();
     if (gg)
       {
-      cmLocalGenerator* lg=gg->GetCurrentLocalGenerator();
-      if (lg)
-        {
-        cmMakefile* mf = lg->GetMakefile();
-        return mf;
-        }
+      return gg->GetCurrentMakefile();
       }
     }
   return 0;
@@ -425,7 +421,7 @@ static int do_build(int ac, char const* const* av)
       switch (doing)
         {
         case DoingDir:
-          dir = av[i];
+          dir = cmSystemTools::CollapseFullPath(av[i]);
           doing = DoingNone;
           break;
         case DoingTarget:
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 3ea2186..f44c77d 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -34,6 +34,10 @@
 #include <time.h>
 
 #include <stdlib.h> // required for atoi
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+// defined in binexplib.cxx
+bool DumpFile(const char* filename, FILE *fout);
+#endif
 
 void CMakeCommandUsage(const char* program)
 {
@@ -211,6 +215,41 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
       return 0;
       }
 
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+    else if(args[1] == "__create_def")
+      {
+      if(args.size() < 4)
+        {
+        std::cerr <<
+          "__create_def Usage: -E __create_def outfile.def objlistfile\n";
+        return 1;
+        }
+      FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+");
+      if(!fout)
+        {
+        std::cerr << "could not open output .def file: " << args[2].c_str()
+                  << "\n";
+        return 1;
+        }
+      cmsys::ifstream fin(args[3].c_str(),
+                          std::ios::in | std::ios::binary);
+      if(!fin)
+        {
+        std::cerr << "could not open object list file: " << args[3].c_str()
+                  << "\n";
+        return 1;
+        }
+      std::string objfile;
+      while(cmSystemTools::GetLineFromStream(fin, objfile))
+        {
+        if (!DumpFile(objfile.c_str(), fout))
+          {
+          return 1;
+          }
+        }
+      return 0;
+      }
+#endif
     // run include what you use command and then run the compile
     // command. This is an internal undocumented option and should
     // only be used by CMake itself when running iwyu.
@@ -296,14 +335,14 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
     // Echo string
     else if (args[1] == "echo" )
       {
-      std::cout << cmJoin(cmRange(args).advance(2), " ") << std::endl;
+      std::cout << cmJoin(cmMakeRange(args).advance(2), " ") << std::endl;
       return 0;
       }
 
     // Echo string no new line
     else if (args[1] == "echo_append" )
       {
-      std::cout << cmJoin(cmRange(args).advance(2), " ");
+      std::cout << cmJoin(cmMakeRange(args).advance(2), " ");
       return 0;
       }
 
@@ -472,7 +511,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
     // Clock command
     else if (args[1] == "time" && args.size() > 2)
       {
-      std::string command = cmJoin(cmRange(args).advance(2), " ");
+      std::string command = cmJoin(cmMakeRange(args).advance(2), " ");
 
       clock_t clock_start, clock_finish;
       time_t time_start, time_finish;
@@ -533,7 +572,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
         return 1;
         }
 
-      std::string command = cmWrap('"', cmRange(args).advance(3), '"', " ");
+      std::string command =
+        cmWrap('"', cmMakeRange(args).advance(3), '"', " ");
       int retval = 0;
       int timeout = 0;
       if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, 0, &retval,
@@ -728,7 +768,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
       if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen))
         {
         cm.SetGlobalGenerator(ggd);
-        cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->MakeLocalGenerator());
+        cmState::Snapshot snapshot = cm.GetCurrentSnapshot();
+        cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(ggd, snapshot));
+        cmsys::auto_ptr<cmLocalGenerator> lgd(
+              ggd->CreateLocalGenerator(mf.get()));
         lgd->GetMakefile()->SetCurrentSourceDirectory(startDir);
         lgd->GetMakefile()->SetCurrentBinaryDirectory(startOutDir);
 
@@ -1312,6 +1355,35 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
   return -1;
 }
 
+class cmVSLink
+{
+  int Type;
+  bool Verbose;
+  bool Incremental;
+  bool LinkGeneratesManifest;
+  std::vector<std::string> LinkCommand;
+  std::vector<std::string> UserManifests;
+  std::string LinkerManifestFile;
+  std::string ManifestFile;
+  std::string ManifestFileRC;
+  std::string ManifestFileRes;
+  std::string TargetFile;
+public:
+  cmVSLink(int type, bool verbose)
+    : Type(type)
+    , Verbose(verbose)
+    , Incremental(false)
+    , LinkGeneratesManifest(true)
+    {}
+  bool Parse(std::vector<std::string>::const_iterator argBeg,
+             std::vector<std::string>::const_iterator argEnd);
+  int Link();
+private:
+  int LinkIncremental();
+  int LinkNonIncremental();
+  int RunMT(std::string const& out, bool notify);
+};
+
 // For visual studio 2005 and newer manifest files need to be embedded into
 // exe and dll's.  This code does that in such a way that incremental linking
 // still works.
@@ -1321,11 +1393,7 @@ int cmcmd::VisualStudioLink(std::vector<std::string>& args, int type)
     {
     return -1;
     }
-  bool verbose = false;
-  if(cmSystemTools::GetEnv("VERBOSE"))
-    {
-    verbose = true;
-    }
+  bool verbose = cmSystemTools::GetEnv("VERBOSE")? true:false;
   std::vector<std::string> expandedArgs;
   for(std::vector<std::string>::iterator i = args.begin();
       i != args.end(); ++i)
@@ -1346,79 +1414,19 @@ int cmcmd::VisualStudioLink(std::vector<std::string>& args, int type)
       expandedArgs.push_back(*i);
       }
     }
-  bool hasIncremental = false;
-  bool hasManifest = true;
-  for(std::vector<std::string>::iterator i = expandedArgs.begin();
-      i != expandedArgs.end(); ++i)
-    {
-    if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL:YES") == 0)
-      {
-      hasIncremental = true;
-      }
-    if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL") == 0)
-      {
-      hasIncremental = true;
-      }
-    if(cmSystemTools::Strucmp(i->c_str(), "/MANIFEST:NO") == 0)
-      {
-      hasManifest = false;
-      }
-    }
-  if(hasIncremental && hasManifest)
-    {
-    if(verbose)
-      {
-      std::cout << "Visual Studio Incremental Link with embedded manifests\n";
-      }
-    return cmcmd::VisualStudioLinkIncremental(expandedArgs, type, verbose);
-    }
-  if(verbose)
-    {
-    if(!hasIncremental)
-      {
-      std::cout << "Visual Studio Non-Incremental Link\n";
-      }
-    else
-      {
-      std::cout << "Visual Studio Incremental Link without manifests\n";
-      }
-    }
-  return cmcmd::VisualStudioLinkNonIncremental(expandedArgs,
-                                               type, hasManifest, verbose);
-}
 
-int cmcmd::ParseVisualStudioLinkCommand(std::vector<std::string>& args,
-                                        std::vector<std::string>& command,
-                                        std::string& targetName)
-{
-  std::vector<std::string>::iterator i = args.begin();
-  i++; // skip -E
-  i++; // skip vs_link_dll or vs_link_exe
-  command.push_back(*i);
-  i++; // move past link command
-  for(; i != args.end(); ++i)
-    {
-    command.push_back(*i);
-    if(i->find("/Fe") == 0)
-      {
-      targetName = i->substr(3);
-      }
-    if(i->find("/out:") == 0)
-      {
-      targetName = i->substr(5);
-      }
-    }
-  if(targetName.empty() || command.empty())
+  cmVSLink vsLink(type, verbose);
+  if (!vsLink.Parse(expandedArgs.begin()+2, expandedArgs.end()))
     {
     return -1;
     }
-  return 0;
+  return vsLink.Link();
 }
 
-bool cmcmd::RunCommand(const char* comment,
+static bool RunCommand(const char* comment,
                        std::vector<std::string>& command,
                        bool verbose,
-                       int* retCodeOut)
+                       int* retCodeOut = 0)
 {
   if(verbose)
     {
@@ -1428,18 +1436,24 @@ bool cmcmd::RunCommand(const char* comment,
   std::string output;
   int retCode =0;
   // use rc command to create .res file
-  cmSystemTools::RunSingleCommand(command,
-                                  &output, &output,
-                                  &retCode, 0, cmSystemTools::OUTPUT_NONE);
+  bool res = cmSystemTools::RunSingleCommand(command,
+                                             &output, &output,
+                                             &retCode, 0,
+                                             cmSystemTools::OUTPUT_NONE);
   // always print the output of the command, unless
   // it is the dumb rc command banner, but if the command
   // returned an error code then print the output anyway as
   // the banner may be mixed with some other important information.
   if(output.find("Resource Compiler Version") == output.npos
-     || retCode !=0)
+     || !res || retCode)
     {
     std::cout << output;
     }
+  if (!res)
+    {
+    std::cout << comment << " failed to run." << std::endl;
+    return false;
+    }
   // if retCodeOut is requested then always return true
   // and set the retCodeOut to retCode
   if(retCodeOut)
@@ -1454,8 +1468,134 @@ bool cmcmd::RunCommand(const char* comment,
   return retCode == 0;
 }
 
-int cmcmd::VisualStudioLinkIncremental(std::vector<std::string>& args,
-                                       int type, bool verbose)
+bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
+                     std::vector<std::string>::const_iterator argEnd)
+{
+  // Parse our own arguments.
+  std::string intDir;
+  std::vector<std::string>::const_iterator arg = argBeg;
+  while (arg != argEnd && cmHasLiteralPrefix(*arg, "-"))
+    {
+    if (*arg == "--")
+      {
+      ++arg;
+      break;
+      }
+    else if (*arg == "--manifests")
+      {
+      for (++arg; arg != argEnd && !cmHasLiteralPrefix(*arg, "-"); ++arg)
+        {
+        this->UserManifests.push_back(*arg);
+        }
+      }
+    else if (cmHasLiteralPrefix(*arg, "--intdir="))
+      {
+      intDir = arg->substr(9);
+      ++arg;
+      }
+    else
+      {
+      std::cerr << "unknown argument '" << *arg << "'\n";
+      return false;
+      }
+    }
+  if (intDir.empty())
+    {
+    return false;
+    }
+
+  // The rest of the arguments form the link command.
+  if (arg == argEnd)
+    {
+    return false;
+    }
+  this->LinkCommand.insert(this->LinkCommand.begin(), arg, argEnd);
+
+  // Parse the link command to extract information we need.
+  for (; arg != argEnd; ++arg)
+    {
+    if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0)
+      {
+      this->Incremental = true;
+      }
+    else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0)
+      {
+      this->Incremental = true;
+      }
+    else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0)
+      {
+      this->LinkGeneratesManifest = false;
+      }
+    else if (cmHasLiteralPrefix(*arg, "/Fe"))
+      {
+      this->TargetFile = arg->substr(3);
+      }
+    else if (cmHasLiteralPrefix(*arg, "/out:"))
+      {
+      this->TargetFile = arg->substr(5);
+      }
+    }
+
+  if (this->TargetFile.empty())
+    {
+    return false;
+    }
+
+  this->ManifestFile = intDir + "/embed.manifest";
+  this->LinkerManifestFile = intDir + "/intermediate.manifest";
+
+  if (this->Incremental)
+    {
+    // We will compile a resource containing the manifest and
+    // pass it to the link command.
+    this->ManifestFileRC = intDir + "/manifest.rc";
+    this->ManifestFileRes = intDir + "/manifest.res";
+    this->LinkCommand.push_back(this->ManifestFileRes);
+    }
+  else if (this->UserManifests.empty())
+    {
+    // Prior to support for user-specified manifests CMake placed the
+    // linker-generated manifest next to the binary (as if it were not to be
+    // embedded) when not linking incrementally.  Preserve this behavior.
+    this->ManifestFile = this->TargetFile + ".manifest";
+    this->LinkerManifestFile = this->ManifestFile;
+    }
+
+  if (this->LinkGeneratesManifest)
+    {
+    this->LinkCommand.push_back("/MANIFEST");
+    this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
+    }
+
+  return true;
+}
+
+int cmVSLink::Link()
+{
+  if (this->Incremental &&
+      (this->LinkGeneratesManifest || !this->UserManifests.empty()))
+    {
+    if (this->Verbose)
+      {
+      std::cout << "Visual Studio Incremental Link with embedded manifests\n";
+      }
+    return LinkIncremental();
+    }
+  if (this->Verbose)
+    {
+    if (!this->Incremental)
+      {
+      std::cout << "Visual Studio Non-Incremental Link\n";
+      }
+    else
+      {
+      std::cout << "Visual Studio Incremental Link without manifests\n";
+      }
+    }
+  return LinkNonIncremental();
+}
+
+int cmVSLink::LinkIncremental()
 {
   // This follows the steps listed here:
   // http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx
@@ -1479,158 +1619,118 @@ int cmcmd::VisualStudioLinkIncremental(std::vector<std::string>& args,
   //    7.  Finally, the Linker does another incremental link, but since the
   //    only thing that has changed is the *.res file that contains the
   //    manifest it is a short link.
-  std::vector<std::string> linkCommand;
-  std::string targetName;
-  if(cmcmd::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1)
-    {
-    return -1;
-    }
-  std::string manifestArg = "/MANIFESTFILE:";
-  std::vector<std::string> rcCommand;
-  rcCommand.push_back(cmSystemTools::FindProgram("rc.exe"));
-  std::vector<std::string> mtCommand;
-  mtCommand.push_back(cmSystemTools::FindProgram("mt.exe"));
-  std::string tempManifest;
-  tempManifest = targetName;
-  tempManifest += ".intermediate.manifest";
-  std::string resourceInputFile = targetName;
-  resourceInputFile += ".resource.txt";
-  if(verbose)
+
+  // Create a resource file referencing the manifest.
+  std::string absManifestFile =
+    cmSystemTools::CollapseFullPath(this->ManifestFile);
+  if (this->Verbose)
     {
-    std::cout << "Create " << resourceInputFile << "\n";
+    std::cout << "Create " << this->ManifestFileRC << "\n";
     }
-  // Create input file for rc command
-  cmsys::ofstream fout(resourceInputFile.c_str());
-  if(!fout)
+  {
+  cmsys::ofstream fout(this->ManifestFileRC.c_str());
+  if (!fout)
     {
     return -1;
     }
-  std::string manifestFile = targetName;
-  manifestFile += ".embed.manifest";
-  std::string fullPath= cmSystemTools::CollapseFullPath(manifestFile);
-  fout << type << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID "
-    "*/ 24 /* RT_MANIFEST */ " << "\"" << fullPath << "\"";
-  fout.close();
-  manifestArg += tempManifest;
-  // add the manifest arg to the linkCommand
-  linkCommand.push_back("/MANIFEST");
-  linkCommand.push_back(manifestArg);
-  // if manifestFile is not yet created, create an
-  // empty one
-  if(!cmSystemTools::FileExists(manifestFile.c_str()))
+  fout << this->Type << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ "
+    "24 /* RT_MANIFEST */ \"" << absManifestFile << "\"";
+  }
+
+  // If we have not previously generated a manifest file,
+  // generate an empty one so the resource compiler succeeds.
+  if (!cmSystemTools::FileExists(this->ManifestFile))
     {
-    if(verbose)
+    if (this->Verbose)
       {
-      std::cout << "Create empty: " << manifestFile << "\n";
+      std::cout << "Create empty: " << this->ManifestFile << "\n";
       }
-    cmsys::ofstream foutTmp(manifestFile.c_str());
+    cmsys::ofstream foutTmp(this->ManifestFile.c_str());
     }
-  std::string resourceFile = manifestFile;
-  resourceFile += ".res";
-  // add the resource file to the end of the link command
-  linkCommand.push_back(resourceFile);
-  std::string outputOpt = "/fo";
-  outputOpt += resourceFile;
-  rcCommand.push_back(outputOpt);
-  rcCommand.push_back(resourceInputFile);
-  // Run rc command to create resource
-  if(!cmcmd::RunCommand("RC Pass 1", rcCommand, verbose))
+
+  // Compile the resource file.
+  std::vector<std::string> rcCommand;
+  rcCommand.push_back(cmSystemTools::FindProgram("rc.exe"));
+  rcCommand.push_back("/fo" + this->ManifestFileRes);
+  rcCommand.push_back(this->ManifestFileRC);
+  if (!RunCommand("RC Pass 1", rcCommand, this->Verbose))
     {
     return -1;
     }
-  // Now run the link command to link and create manifest
-  if(!cmcmd::RunCommand("LINK Pass 1", linkCommand, verbose))
+
+  // Run the link command (possibly generates intermediate manifest).
+  if (!RunCommand("LINK Pass 1", this->LinkCommand, this->Verbose))
     {
     return -1;
     }
-  // create mt command
-  std::string outArg("/out:");
-  outArg+= manifestFile;
-  mtCommand.push_back("/nologo");
-  mtCommand.push_back(outArg);
-  mtCommand.push_back("/notify_update");
-  mtCommand.push_back("/manifest");
-  mtCommand.push_back(tempManifest);
-  //  now run mt.exe to create the final manifest file
-  int mtRet =0;
-  cmcmd::RunCommand("MT", mtCommand, verbose, &mtRet);
-  // if mt returns 0, then the manifest was not changed and
-  // we do not need to do another link step
-  if(mtRet == 0)
-    {
-    return 0;
-    }
-  // check for magic mt return value if mt returns the magic number
-  // 1090650113 then it means that it updated the manifest file and we need
-  // to do the final link.  If mt has any value other than 0 or 1090650113
-  // then there was some problem with the command itself and there was an
-  // error so return the error code back out of cmake so make can report it.
-  // (when hosted on a posix system the value is 187)
-  if(mtRet != 1090650113 && mtRet != 187)
+
+  // Run the manifest tool to create the final manifest.
+  int mtRet = this->RunMT("/out:" + this->ManifestFile, true);
+
+  // If mt returns 1090650113 (or 187 on a posix host) then it updated the
+  // manifest file so we need to embed it again.  Otherwise we are done.
+  if (mtRet != 1090650113 && mtRet != 187)
     {
     return mtRet;
     }
-  // update the resource file with the new manifest from the mt command.
-  if(!cmcmd::RunCommand("RC Pass 2", rcCommand, verbose))
+
+  // Compile the resource file again.
+  if (!RunCommand("RC Pass 2", rcCommand, this->Verbose))
     {
     return -1;
     }
-  // Run the final incremental link that will put the new manifest resource
-  // into the file incrementally.
-  if(!cmcmd::RunCommand("FINAL LINK", linkCommand, verbose))
+
+  // Link incrementally again to use the updated resource.
+  if (!RunCommand("FINAL LINK", this->LinkCommand, this->Verbose))
     {
     return -1;
     }
   return 0;
 }
 
-int cmcmd::VisualStudioLinkNonIncremental(std::vector<std::string>& args,
-                                          int type,
-                                          bool hasManifest,
-                                          bool verbose)
+int cmVSLink::LinkNonIncremental()
 {
-  std::vector<std::string> linkCommand;
-  std::string targetName;
-  if(cmcmd::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1)
-    {
-    return -1;
-    }
-  // Run the link command as given
-  if (hasManifest)
-    {
-    linkCommand.push_back("/MANIFEST");
-    }
-  if(!cmcmd::RunCommand("LINK", linkCommand, verbose))
+  // Run the link command (possibly generates intermediate manifest).
+  if (!RunCommand("LINK", this->LinkCommand, this->Verbose))
     {
     return -1;
     }
-  if(!hasManifest)
+
+  // If we have no manifest files we are done.
+  if (!this->LinkGeneratesManifest && this->UserManifests.empty())
     {
     return 0;
     }
+
+  // Run the manifest tool to embed the final manifest in the binary.
+  std::string mtOut =
+    "/outputresource:" + this->TargetFile + (this->Type == 1? ";#1" : ";#2");
+  return this->RunMT(mtOut, false);
+}
+
+int cmVSLink::RunMT(std::string const& out, bool notify)
+{
   std::vector<std::string> mtCommand;
   mtCommand.push_back(cmSystemTools::FindProgram("mt.exe"));
   mtCommand.push_back("/nologo");
   mtCommand.push_back("/manifest");
-  std::string manifestFile = targetName;
-  manifestFile += ".manifest";
-  mtCommand.push_back(manifestFile);
-  std::string outresource = "/outputresource:";
-  outresource += targetName;
-  outresource += ";#";
-  if(type == 1)
+  if (this->LinkGeneratesManifest)
     {
-    outresource += "1";
+    mtCommand.push_back(this->LinkerManifestFile);
     }
-  else if(type == 2)
+  mtCommand.insert(mtCommand.end(),
+                   this->UserManifests.begin(), this->UserManifests.end());
+  mtCommand.push_back(out);
+  if (notify)
     {
-    outresource += "2";
+    // Add an undocumented option that enables a special return
+    // code to notify us when the manifest is modified.
+    mtCommand.push_back("/notify_update");
     }
-  mtCommand.push_back(outresource);
-  // Now use the mt tool to embed the manifest into the exe or dll
-  if(!cmcmd::RunCommand("MT", mtCommand, verbose))
+  int mtRet = 0;
+  if (!RunCommand("MT", mtCommand, this->Verbose, &mtRet))
     {
     return -1;
     }
-  return 0;
+  return mtRet;
 }
diff --git a/Source/cmcmd.h b/Source/cmcmd.h
index 2bfbae7..64b2406 100644
--- a/Source/cmcmd.h
+++ b/Source/cmcmd.h
@@ -35,20 +35,6 @@ protected:
   static int WindowsCEEnvironment(const char* version,
                                   const std::string& name);
   static int VisualStudioLink(std::vector<std::string>& args, int type);
-  static int VisualStudioLinkIncremental(std::vector<std::string>& args,
-                                         int type,
-                                         bool verbose);
-  static int VisualStudioLinkNonIncremental(std::vector<std::string>& args,
-                                            int type,
-                                            bool hasManifest,
-                                            bool verbose);
-  static int ParseVisualStudioLinkCommand(std::vector<std::string>& args,
-                                          std::vector<std::string>& command,
-                                          std::string& targetName);
-  static bool RunCommand(const char* comment,
-                         std::vector<std::string>& command,
-                         bool verbose,
-                         int* retCodeOut = 0);
 };
 
 #endif
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index e784759..7fa6aed 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -46,6 +46,10 @@ static const char * cmDocumentationOptions[][2] =
   {"--debug", "Displaying more verbose internals of CTest."},
   {"--output-on-failure", "Output anything outputted by the test program "
     "if the test should fail."},
+  {"--test-output-size-passed <size>", "Limit the output for passed tests "
+    "to <size> bytes"},
+  {"--test-output-size-failed <size>", "Limit the output for failed tests "
+    "to <size> bytes"},
   {"-F", "Enable failover."},
   {"-j <jobs>, --parallel <jobs>", "Run the tests in parallel using the "
    "given number of jobs."},
@@ -98,6 +102,7 @@ static const char * cmDocumentationOptions[][2] =
 
   {"--test-command", "The test to run with the --build-and-test option."},
   {"--test-timeout", "The time limit in seconds, internal use only."},
+  {"--test-load", "CPU load threshold for starting new parallel tests."},
   {"--tomorrow-tag", "Nightly or experimental starts with next day tag."},
   {"--ctest-config", "The configuration file used to initialize CTest state "
    "when submitting dashboards."},
diff --git a/Source/kwsys/CMakeEmptyInputFile.in b/Source/kwsys/CMakeEmptyInputFile.in
deleted file mode 100644
index 40b7ea2..0000000
--- a/Source/kwsys/CMakeEmptyInputFile.in
+++ /dev/null
@@ -1 +0,0 @@
- at CMAKE_EMPTY_INPUT_FILE_CONTENT@
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index c88e888..84010d8 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -35,15 +35,6 @@
 #      SET(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR})
 #      INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
 #
-#  KWSYS_IOS_FORCE_OLD = Force use of old non-ANSI C++ streams even if
-#                        new streams are available.  This may be used
-#                        by projects that cannot configure their
-#                        streams library.
-#    Example:
-#
-#      SET(KWSYS_IOS_FORCE_OLD 1)
-#
-#
 # Optional settings to setup install rules are as follows:
 #
 #  KWSYS_INSTALL_BIN_DIR     = The installation target directories into
@@ -91,6 +82,7 @@ ENDIF()
 IF(POLICY CMP0056)
   CMAKE_POLICY(SET CMP0056 NEW)
 ENDIF()
+SET(CMAKE_LEGACY_CYGWIN_WIN32 0)
 
 #-----------------------------------------------------------------------------
 # If a namespace is not specified, use "kwsys" and enable testing.
@@ -311,6 +303,15 @@ IF(NOT CMAKE_COMPILER_IS_GNUCXX)
     ENDIF()
   ENDIF()
 ENDIF()
+IF(KWSYS_STANDALONE)
+  IF(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
+    IF(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
+    ELSE()
+      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
+    ENDIF()
+  ENDIF()
+ENDIF()
 
 #-----------------------------------------------------------------------------
 # Configure Large File Support.
@@ -341,105 +342,6 @@ ENDIF()
 # capabilities and parent project's request.  Enforce 0/1 as only
 # possible values for configuration into Configure.hxx.
 
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAVE_STD
-  "Checking whether STL classes are in std namespace" DIRECT)
-
-IF(KWSYS_IOS_FORCE_OLD)
-  SET(KWSYS_IOS_USE_ANSI 0)
-ELSE()
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_ANSI
-    "Checking whether ANSI stream headers are available" DIRECT)
-ENDIF()
-
-IF(KWSYS_IOS_USE_ANSI)
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAVE_STD
-    "Checking whether ANSI streams are in std namespace" DIRECT)
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_SSTREAM
-    "Checking whether ANSI string stream is available" DIRECT)
-ELSE()
-  SET(KWSYS_IOS_HAVE_STD 0)
-  SET(KWSYS_IOS_USE_SSTREAM 0)
-ENDIF()
-
-IF(KWSYS_IOS_USE_SSTREAM)
-  SET(KWSYS_IOS_USE_STRSTREAM_H 0)
-  SET(KWSYS_IOS_USE_STRSTREA_H 0)
-ELSE()
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_STRSTREAM_H
-    "Checking whether strstream.h is available" DIRECT)
-  IF(KWSYS_IOS_USE_STRSTREAM_H)
-    SET(KWSYS_IOS_USE_STRSTREA_H 0)
-  ELSE()
-    KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_STRSTREA_H
-      "Checking whether strstrea.h is available" DIRECT)
-  ENDIF()
-ENDIF()
-
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CSTDDEF
-  "Checking whether header cstddef is available" DIRECT)
-
-SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
-  -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD})
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_NEQ_CHAR
-  "Checking whether stl string has operator!= for char*" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ITERATOR_TRAITS
-  "Checking whether stl has iterator_traits" DIRECT)
-IF(KWSYS_STL_HAS_ITERATOR_TRAITS)
-  SET(KWSYS_STL_HAS_ITERATOR_CATEGORY 0)
-  SET(KWSYS_STL_HAS___ITERATOR_CATEGORY 0)
-ELSE()
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ITERATOR_CATEGORY
-    "Checking whether stl has old iterator_category" DIRECT)
-  IF(KWSYS_STL_HAS_ITERATOR_CATEGORY)
-    SET(KWSYS_STL_HAS___ITERATOR_CATEGORY 0)
-  ELSE()
-    KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS___ITERATOR_CATEGORY
-      "Checking whether stl has internal __iterator_category" DIRECT)
-  ENDIF()
-ENDIF()
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE
-  "Checking whether stl has standard template allocator" DIRECT)
-IF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE)
-  SET(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE 0)
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_REBIND
-    "Checking for rebind member of stl allocator" DIRECT)
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
-    "Checking for non-standard argument to stl allocator<>::max_size" DIRECT)
-ELSE()
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE
-    "Checking whether stl has old non-template allocator" DIRECT)
-  SET(KWSYS_STL_HAS_ALLOCATOR_REBIND 0)
-  SET(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT 0)
-ENDIF()
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_OBJECTS
-  "Checking whether stl containers support allocator objects." DIRECT)
-IF(KWSYS_IOS_USE_ANSI AND NOT WATCOM)
-  # ANSI streams always have string operators.
-  SET(KWSYS_STL_STRING_HAVE_OSTREAM 1)
-  SET(KWSYS_STL_STRING_HAVE_ISTREAM 1)
-ELSE()
-  # There may not be string operators for old streams.
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_OSTREAM
-    "Checking whether stl string has ostream operator<<" DIRECT)
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_ISTREAM
-    "Checking whether stl string has istream operator>>" DIRECT)
-ENDIF()
-SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
-  -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
-  -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
-KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAVE_BINARY
-  "Checking whether ios has binary openmode" DIRECT)
-SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
-
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS
-  "Checking whether \"<>\" is needed for template friends" INVERT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_MEMBER_TEMPLATES
-  "Checking for member template support" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_FULL_SPECIALIZATION
-  "Checking for standard template specialization syntax" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
-  "Checking whether argument dependent lookup is supported" DIRECT)
-
 IF(UNIX)
   KWSYS_PLATFORM_CXX_TEST(KWSYS_STAT_HAS_ST_MTIM
     "Checking whether struct stat has st_mtim member" DIRECT)
@@ -548,9 +450,6 @@ ENDIF()
 
 IF(KWSYS_USE_IOStream)
   # Determine whether iostreams support long long.
-  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
-    -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
-    -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
   IF(KWSYS_CXX_HAS_LONG_LONG)
     KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG
       "Checking if istream supports long long" DIRECT)
@@ -569,7 +468,6 @@ IF(KWSYS_USE_IOStream)
     SET(KWSYS_IOS_HAS_ISTREAM___INT64 0)
     SET(KWSYS_IOS_HAS_OSTREAM___INT64 0)
   ENDIF()
-  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
 ENDIF()
 
 IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
@@ -786,6 +684,15 @@ IF(KWSYS_USE_SystemInformation)
     SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
       COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
   ENDIF()
+
+  IF(UNIX AND NOT CYGWIN)
+    KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG
+      "Checking whether CXX compiler has getloadavg" DIRECT)
+    IF(KWSYS_CXX_HAS_GETLOADAVG)
+      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+        COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1)
+    ENDIF()
+  ENDIF()
 ENDIF()
 
 #-----------------------------------------------------------------------------
@@ -813,84 +720,6 @@ IF(KWSYS_INSTALL_DOC_DIR)
 ENDIF()
 
 #-----------------------------------------------------------------------------
-# Create STL header wrappers to block warnings in the STL headers and
-# give standard names by which they may be included.
-SET(KWSYS_STL_HEADER_EXTRA_string 1)
-FOREACH(header
-  algorithm
-  deque
-  exception
-  functional
-  iterator
-  list
-  map
-  memory
-  new
-  numeric
-  queue
-  set
-  stack
-  stdexcept
-  string
-  utility
-  vector
-  )
-  # Configure the header wrapper.
-  SET(KWSYS_STL_HEADER "${header}")
-  IF(KWSYS_STL_HEADER_EXTRA_${header})
-    SET(KWSYS_STL_HEADER_EXTRA
-      "#define ${KWSYS_NAMESPACE}_stl_${header}_including_hxx\n# include <${KWSYS_NAMESPACE}/stl/${header}.hxx>\n#undef ${KWSYS_NAMESPACE}_stl_${header}_including_hxx\n")
-    CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl_${header}.hxx.in
-                   ${KWSYS_HEADER_DIR}/stl/${header}.hxx
-                   @ONLY IMMEDIATE)
-    IF(KWSYS_INSTALL_INCLUDE_DIR)
-      INSTALL(FILES ${KWSYS_HEADER_DIR}/stl/${header}.hxx
-        DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl
-        ${KWSYS_INSTALL_INCLUDE_OPTIONS})
-    ENDIF()
-  ELSE()
-    SET(KWSYS_STL_HEADER_EXTRA "")
-  ENDIF()
-  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl.hxx.in
-                 ${KWSYS_HEADER_DIR}/stl/${header}
-                 @ONLY IMMEDIATE)
-
-  # Create an install target for the header wrapper.
-  IF(KWSYS_INSTALL_INCLUDE_DIR)
-    INSTALL(FILES ${KWSYS_HEADER_DIR}/stl/${header}
-      DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl
-      ${KWSYS_INSTALL_INCLUDE_OPTIONS})
-  ENDIF()
-ENDFOREACH()
-
-# Provide cstddef header.
-CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_cstddef.hxx.in
-               ${KWSYS_HEADER_DIR}/cstddef
-               @ONLY IMMEDIATE)
-IF(KWSYS_INSTALL_INCLUDE_DIR)
-  INSTALL(FILES ${KWSYS_HEADER_DIR}/cstddef
-    DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
-    ${KWSYS_INSTALL_INCLUDE_OPTIONS})
-ENDIF()
-
-#-----------------------------------------------------------------------------
-# Create streams header wrappers to give standard names by which they
-# may be included.
-FOREACH(header iostream fstream sstream iosfwd)
-  # Configure the header wrapper.
-  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_ios_${header}.h.in
-                 ${KWSYS_HEADER_DIR}/ios/${header}
-                 @ONLY IMMEDIATE)
-
-  # Create an install target for the header wrapper.
-  IF(KWSYS_INSTALL_INCLUDE_DIR)
-    INSTALL(FILES ${KWSYS_HEADER_DIR}/ios/${header}
-      DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/ios
-      ${KWSYS_INSTALL_INCLUDE_OPTIONS})
-  ENDIF()
-ENDFOREACH()
-
-#-----------------------------------------------------------------------------
 # Build a list of classes and headers we need to implement the
 # selected components.  Initialize with required components.
 SET(KWSYS_CLASSES)
@@ -1062,7 +891,7 @@ IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
 
   # Apply user-defined target properties to the library.
   IF(KWSYS_PROPERTIES_C)
-    SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES
+    SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE}_c PROPERTIES
       ${KWSYS_PROPERTIES_C}
       )
   ENDIF()
@@ -1228,7 +1057,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
     IF(NOT CYGWIN)
       SET(KWSYS_TEST_PROCESS_7 7)
     ENDIF()
-    FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7})
+    FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
       ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
       SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
       SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
@@ -1261,6 +1090,10 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
       MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
     ENDIF()
 
+    # Set up ctest custom configuration file.
+    CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
+                   ${PROJECT_BINARY_DIR}/CTestCustom.cmake @ONLY)
+
     # Suppress known consistent failures on buggy systems.
     IF(KWSYS_TEST_BOGUS_FAILURES)
       SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
diff --git a/Source/kwsys/CONTRIBUTING.rst b/Source/kwsys/CONTRIBUTING.rst
index e097b76..960eea4 100644
--- a/Source/kwsys/CONTRIBUTING.rst
+++ b/Source/kwsys/CONTRIBUTING.rst
@@ -29,7 +29,7 @@ License
 
 We do not require any formal copyright assignment or contributor license
 agreement.  Any contributions intentionally sent upstream are presumed
-to be offerred under terms of the OSI-approved BSD 3-clause License.
+to be offered under terms of the OSI-approved BSD 3-clause License.
 See `Copyright.txt`_ for details.
 
 .. _`Copyright.txt`: Copyright.txt
diff --git a/Source/kwsys/CTestCustom.cmake.in b/Source/kwsys/CTestCustom.cmake.in
new file mode 100644
index 0000000..760221b
--- /dev/null
+++ b/Source/kwsys/CTestCustom.cmake.in
@@ -0,0 +1,14 @@
+# kwsys.testProcess-10 involves sending SIGINT to a child process, which then
+# exits abnormally via a call to _exit(). (On Windows, a call to ExitProcess).
+# Naturally, this results in plenty of memory being "leaked" by this child
+# process - the memory check results are not meaningful in this case.
+#
+# kwsys.testProcess-9 also tests sending SIGINT to a child process.  However,
+# normal operation of that test involves the child process timing out, and the
+# host process kills (SIGKILL) it as a result.  Since it was SIGKILL'ed, the
+# resulting memory leaks are not logged by valgrind anyway.  Therefore, we
+# don't have to exclude it.
+
+list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE
+  kwsys.testProcess-10
+  )
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index 9fa9802..3636836 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -15,22 +15,19 @@
 #include KWSYS_HEADER(Configure.hxx)
 #include KWSYS_HEADER(String.hxx)
 
-#include KWSYS_HEADER(stl/vector)
-#include KWSYS_HEADER(stl/map)
-#include KWSYS_HEADER(stl/set)
-#include KWSYS_HEADER(ios/sstream)
-#include KWSYS_HEADER(ios/iostream)
-
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
 # include "CommandLineArguments.hxx.in"
 # include "Configure.hxx.in"
-# include "kwsys_stl.hxx.in"
-# include "kwsys_ios_sstream.h.in"
-# include "kwsys_ios_iostream.h.in"
 #endif
 
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+#include <iostream>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -45,7 +42,7 @@
 
 #if 0
 #  define CommandLineArguments_DEBUG(x) \
-  kwsys_ios::cout << __LINE__ << " CLA: " << x << kwsys_ios::endl
+  std::cout << __LINE__ << " CLA: " << x << std::endl
 #else
 #  define CommandLineArguments_DEBUG(x)
 #endif
@@ -67,11 +64,11 @@ struct CommandLineArgumentsCallbackStructure
 };
  
 class CommandLineArgumentsVectorOfStrings : 
-  public kwsys_stl::vector<kwsys::String> {};
+  public std::vector<kwsys::String> {};
 class CommandLineArgumentsSetOfStrings :
-  public kwsys_stl::set<kwsys::String> {};
+  public std::set<kwsys::String> {};
 class CommandLineArgumentsMapOfStrucs : 
-  public kwsys_stl::map<kwsys::String,
+  public std::map<kwsys::String,
     CommandLineArgumentsCallbackStructure> {};
 
 class CommandLineArgumentsInternal
@@ -152,8 +149,8 @@ void CommandLineArguments::ProcessArgument(const char* arg)
 
 //----------------------------------------------------------------------------
 bool CommandLineArguments::GetMatchedArguments(
-  kwsys_stl::vector<kwsys_stl::string>* matches,
-  const kwsys_stl::string& arg)
+  std::vector<std::string>* matches,
+  const std::string& arg)
 {
   matches->clear();
   CommandLineArguments::Internal::CallbacksMap::iterator it;
@@ -184,15 +181,15 @@ bool CommandLineArguments::GetMatchedArguments(
 //----------------------------------------------------------------------------
 int CommandLineArguments::Parse()
 {
-  kwsys_stl::vector<kwsys_stl::string>::size_type cc;
-  kwsys_stl::vector<kwsys_stl::string> matches;
+  std::vector<std::string>::size_type cc;
+  std::vector<std::string> matches;
   if ( this->StoreUnusedArgumentsFlag )
     {
     this->Internals->UnusedArguments.clear();
     }
   for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ )
     {
-    const kwsys_stl::string& arg = this->Internals->Argv[cc]; 
+    const std::string& arg = this->Internals->Argv[cc];
     CommandLineArguments_DEBUG("Process argument: " << arg);
     this->Internals->LastArgument = cc;
     if ( this->GetMatchedArguments(&matches, arg) )
@@ -214,7 +211,7 @@ int CommandLineArguments::Parse()
       // additional value
       CommandLineArgumentsCallbackStructure *cs 
         = &this->Internals->Callbacks[matches[maxidx]];
-      const kwsys_stl::string& sarg = matches[maxidx];
+      const std::string& sarg = matches[maxidx];
       if ( cs->Argument != sarg )
         {
         abort();
@@ -267,7 +264,7 @@ int CommandLineArguments::Parse()
         CommandLineArguments_DEBUG("This is a multi argument: " << arg);
         for (cc++; cc < this->Internals->Argv.size(); ++ cc )
           {
-          const kwsys_stl::string& marg = this->Internals->Argv[cc];
+          const std::string& marg = this->Internals->Argv[cc];
           CommandLineArguments_DEBUG(" check multi argument value: " << marg);
           if ( this->GetMatchedArguments(&matches, marg) )
             {
@@ -288,7 +285,7 @@ int CommandLineArguments::Parse()
           }
         break;
       default:
-        kwsys_ios::cerr << "Got unknown argument type: \"" << cs->ArgumentType << "\"" << kwsys_ios::endl;
+        std::cerr << "Got unknown argument type: \"" << cs->ArgumentType << "\"" << std::endl;
         this->Internals->LastArgument --;
         return 0;
         }
@@ -313,7 +310,7 @@ int CommandLineArguments::Parse()
         }
       else
         {
-        kwsys_ios::cerr << "Got unknown argument: \"" << arg << "\"" << kwsys_ios::endl;
+        std::cerr << "Got unknown argument: \"" << arg << "\"" << std::endl;
         this->Internals->LastArgument --;
         return 0;
         }
@@ -430,13 +427,13 @@ CommandLineArgumentsAddArgumentMacro(BOOL,       bool)
 CommandLineArgumentsAddArgumentMacro(INT,        int)
 CommandLineArgumentsAddArgumentMacro(DOUBLE,     double)
 CommandLineArgumentsAddArgumentMacro(STRING,     char*)
-CommandLineArgumentsAddArgumentMacro(STL_STRING, kwsys_stl::string)
+CommandLineArgumentsAddArgumentMacro(STL_STRING, std::string)
 
-CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL,       kwsys_stl::vector<bool>)
-CommandLineArgumentsAddArgumentMacro(VECTOR_INT,        kwsys_stl::vector<int>)
-CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE,     kwsys_stl::vector<double>)
-CommandLineArgumentsAddArgumentMacro(VECTOR_STRING,     kwsys_stl::vector<char*>)
-CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, kwsys_stl::vector<kwsys_stl::string>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL,       std::vector<bool>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_INT,        std::vector<int>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE,     std::vector<double>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_STRING,     std::vector<char*>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, std::vector<std::string>)
 
 //----------------------------------------------------------------------------
 #define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \
@@ -451,7 +448,7 @@ CommandLineArgumentsAddBooleanArgumentMacro(BOOL,       bool)
 CommandLineArgumentsAddBooleanArgumentMacro(INT,        int)
 CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE,     double)
 CommandLineArgumentsAddBooleanArgumentMacro(STRING,     char*)
-CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, kwsys_stl::string)
+CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, std::string)
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::SetClientData(void* client_data)
@@ -518,12 +515,12 @@ unsigned int CommandLineArguments::GetLastArgument()
 //----------------------------------------------------------------------------
 void CommandLineArguments::GenerateHelp()
 {
-  kwsys_ios::ostringstream str;
+  std::ostringstream str;
   
   // Collapse all arguments into the map of vectors of all arguments that do
   // the same thing.
   CommandLineArguments::Internal::CallbacksMap::iterator it;
-  typedef kwsys_stl::map<CommandLineArguments::Internal::String, 
+  typedef std::map<CommandLineArguments::Internal::String,
      CommandLineArguments::Internal::SetOfStrings > MapArgs;
   MapArgs mp;
   MapArgs::iterator mpit, smpit;
@@ -604,7 +601,7 @@ void CommandLineArguments::GenerateHelp()
     CommandLineArguments::Internal::SetOfStrings::iterator sit;
     for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
       {
-      str << kwsys_ios::endl;
+      str << std::endl;
       char argument[100];
       sprintf(argument, "%s", sit->c_str());
       switch ( this->Internals->Callbacks[*sit].ArgumentType )
@@ -658,8 +655,8 @@ void CommandLineArguments::GenerateHelp()
           skip = cc;
           }
         }
-      str.write(ptr, static_cast<kwsys_ios::streamsize>(skip));
-      str << kwsys_ios::endl;
+      str.write(ptr, static_cast<std::streamsize>(skip));
+      str << std::endl;
       ptr += skip;
       len -= skip;
       cnt ++;
@@ -680,7 +677,7 @@ void CommandLineArguments::GenerateHelp()
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  bool* variable, const kwsys_stl::string& value)
+  bool* variable, const std::string& value)
 {
   if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
     value == "TRUE" || value == "true" || value == "True" ||
@@ -696,7 +693,7 @@ void CommandLineArguments::PopulateVariable(
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  int* variable, const kwsys_stl::string& value)
+  int* variable, const std::string& value)
 {
   char* res = 0;
   *variable = static_cast<int>(strtol(value.c_str(), &res, 10));
@@ -708,7 +705,7 @@ void CommandLineArguments::PopulateVariable(
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  double* variable, const kwsys_stl::string& value)
+  double* variable, const std::string& value)
 {
   char* res = 0;
   *variable = strtod(value.c_str(), &res);
@@ -720,7 +717,7 @@ void CommandLineArguments::PopulateVariable(
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  char** variable, const kwsys_stl::string& value)
+  char** variable, const std::string& value)
 {
   if ( *variable )
     {
@@ -733,14 +730,14 @@ void CommandLineArguments::PopulateVariable(
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  kwsys_stl::string* variable, const kwsys_stl::string& value)
+  std::string* variable, const std::string& value)
 {
   *variable = value;
 }
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value)
+  std::vector<bool>* variable, const std::string& value)
 {
   bool val = false;
   if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
@@ -754,7 +751,7 @@ void CommandLineArguments::PopulateVariable(
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  kwsys_stl::vector<int>* variable, const kwsys_stl::string& value)
+  std::vector<int>* variable, const std::string& value)
 {
   char* res = 0;
   variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10)));
@@ -766,7 +763,7 @@ void CommandLineArguments::PopulateVariable(
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  kwsys_stl::vector<double>* variable, const kwsys_stl::string& value)
+  std::vector<double>* variable, const std::string& value)
 {
   char* res = 0;
   variable->push_back(strtod(value.c_str(), &res));
@@ -778,7 +775,7 @@ void CommandLineArguments::PopulateVariable(
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value)
+  std::vector<char*>* variable, const std::string& value)
 {
   char* var = new char[ value.size() + 1 ];
   strcpy(var, value.c_str());
@@ -787,8 +784,8 @@ void CommandLineArguments::PopulateVariable(
 
 //----------------------------------------------------------------------------
 void CommandLineArguments::PopulateVariable(
-  kwsys_stl::vector<kwsys_stl::string>* variable,
-  const kwsys_stl::string& value)
+  std::vector<std::string>* variable,
+  const std::string& value)
 {
   variable->push_back(value);
 }
@@ -809,7 +806,7 @@ bool CommandLineArguments::PopulateVariable(CommandLineArgumentsCallbackStructur
   CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to " << value);
   if ( cs->Variable )
     {
-    kwsys_stl::string var = "1";
+    std::string var = "1";
     if ( value )
       {
       var = value;
@@ -826,28 +823,28 @@ bool CommandLineArguments::PopulateVariable(CommandLineArgumentsCallbackStructur
       this->PopulateVariable(static_cast<char**>(cs->Variable), var);
       break;
     case CommandLineArguments::STL_STRING_TYPE:
-      this->PopulateVariable(static_cast<kwsys_stl::string*>(cs->Variable), var);
+      this->PopulateVariable(static_cast<std::string*>(cs->Variable), var);
       break;
     case CommandLineArguments::BOOL_TYPE:
       this->PopulateVariable(static_cast<bool*>(cs->Variable), var);
       break;
     case CommandLineArguments::VECTOR_BOOL_TYPE:
-      this->PopulateVariable(static_cast<kwsys_stl::vector<bool>*>(cs->Variable), var);
+      this->PopulateVariable(static_cast<std::vector<bool>*>(cs->Variable), var);
       break;
     case CommandLineArguments::VECTOR_INT_TYPE:
-      this->PopulateVariable(static_cast<kwsys_stl::vector<int>*>(cs->Variable), var);
+      this->PopulateVariable(static_cast<std::vector<int>*>(cs->Variable), var);
       break;
     case CommandLineArguments::VECTOR_DOUBLE_TYPE:
-      this->PopulateVariable(static_cast<kwsys_stl::vector<double>*>(cs->Variable), var);
+      this->PopulateVariable(static_cast<std::vector<double>*>(cs->Variable), var);
       break;
     case CommandLineArguments::VECTOR_STRING_TYPE:
-      this->PopulateVariable(static_cast<kwsys_stl::vector<char*>*>(cs->Variable), var);
+      this->PopulateVariable(static_cast<std::vector<char*>*>(cs->Variable), var);
       break;
     case CommandLineArguments::VECTOR_STL_STRING_TYPE:
-      this->PopulateVariable(static_cast<kwsys_stl::vector<kwsys_stl::string>*>(cs->Variable), var);
+      this->PopulateVariable(static_cast<std::vector<std::string>*>(cs->Variable), var);
       break;
     default:
-      kwsys_ios::cerr << "Got unknown variable type: \"" << cs->VariableType << "\"" << kwsys_ios::endl;
+      std::cerr << "Got unknown variable type: \"" << cs->VariableType << "\"" << std::endl;
       this->Internals->LastArgument --;
       return 0;
       }
diff --git a/Source/kwsys/CommandLineArguments.hxx.in b/Source/kwsys/CommandLineArguments.hxx.in
index cbf6ee3..e4f6d02 100644
--- a/Source/kwsys/CommandLineArguments.hxx.in
+++ b/Source/kwsys/CommandLineArguments.hxx.in
@@ -15,13 +15,8 @@
 #include <@KWSYS_NAMESPACE@/Configure.h>
 #include <@KWSYS_NAMESPACE@/Configure.hxx>
 
-#include <@KWSYS_NAMESPACE@/stl/string>
-#include <@KWSYS_NAMESPACE@/stl/vector>
-
-/* Define this macro temporarily to keep the code readable.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE at _stl
-#endif
+#include <string>
+#include <vector>
 
 namespace @KWSYS_NAMESPACE@
 {
@@ -64,7 +59,7 @@ struct CommandLineArgumentsCallbackStructure;
  *                 "This is help string for --something");
  * if ( !arg.Parse() )
  *   {
- *   kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
+ *   std::cerr << "Problem parsing arguments" << std::endl;
  *   res = 1;
  *   }
  * 
@@ -155,7 +150,7 @@ public:
   void AddArgument(const char* argument, ArgumentTypeEnum type, 
     char** variable, const char* help);
   void AddArgument(const char* argument, ArgumentTypeEnum type,
-    kwsys_stl::string* variable, const char* help);
+    std::string* variable, const char* help);
 
   /**
    * Add handler for argument which is going to set the variable to the
@@ -163,15 +158,15 @@ public:
    * appropriate type. This will handle the multi argument values.
    */
   void AddArgument(const char* argument, ArgumentTypeEnum type,
-    kwsys_stl::vector<bool>* variable, const char* help);
+    std::vector<bool>* variable, const char* help);
   void AddArgument(const char* argument, ArgumentTypeEnum type,
-    kwsys_stl::vector<int>* variable, const char* help);
+    std::vector<int>* variable, const char* help);
   void AddArgument(const char* argument, ArgumentTypeEnum type, 
-    kwsys_stl::vector<double>* variable, const char* help);
+    std::vector<double>* variable, const char* help);
   void AddArgument(const char* argument, ArgumentTypeEnum type, 
-    kwsys_stl::vector<char*>* variable, const char* help);
+    std::vector<char*>* variable, const char* help);
   void AddArgument(const char* argument, ArgumentTypeEnum type,
-    kwsys_stl::vector<kwsys_stl::string>* variable, const char* help);
+    std::vector<std::string>* variable, const char* help);
 
   /**
    * Add handler for boolean argument. The argument does not take any option
@@ -187,7 +182,7 @@ public:
   void AddBooleanArgument(const char* argument,
     char** variable, const char* help);
   void AddBooleanArgument(const char* argument,
-    kwsys_stl::string* variable, const char* help);
+    std::string* variable, const char* help);
 
   /**
    * Set the callbacks for error handling.
@@ -243,28 +238,28 @@ protected:
   void AddArgument(const char* argument, ArgumentTypeEnum type,
     VariableTypeEnum vtype, void* variable, const char* help);
 
-  bool GetMatchedArguments(kwsys_stl::vector<kwsys_stl::string>* matches,
-    const kwsys_stl::string& arg);
+  bool GetMatchedArguments(std::vector<std::string>* matches,
+    const std::string& arg);
 
   //! Populate individual variables
   bool PopulateVariable(CommandLineArgumentsCallbackStructure* cs,
     const char* value);
 
   //! Populate individual variables of type ...
-  void PopulateVariable(bool* variable, const kwsys_stl::string& value);
-  void PopulateVariable(int* variable, const kwsys_stl::string& value);
-  void PopulateVariable(double* variable, const kwsys_stl::string& value);
-  void PopulateVariable(char** variable, const kwsys_stl::string& value);
-  void PopulateVariable(kwsys_stl::string* variable, const kwsys_stl::string& value);
-  void PopulateVariable(kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value);
-  void PopulateVariable(kwsys_stl::vector<int>* variable, const kwsys_stl::string& value);
-  void PopulateVariable(kwsys_stl::vector<double>* variable, const kwsys_stl::string& value);
-  void PopulateVariable(kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value);
-  void PopulateVariable(kwsys_stl::vector<kwsys_stl::string>* variable, const kwsys_stl::string& value);
+  void PopulateVariable(bool* variable, const std::string& value);
+  void PopulateVariable(int* variable, const std::string& value);
+  void PopulateVariable(double* variable, const std::string& value);
+  void PopulateVariable(char** variable, const std::string& value);
+  void PopulateVariable(std::string* variable, const std::string& value);
+  void PopulateVariable(std::vector<bool>* variable, const std::string& value);
+  void PopulateVariable(std::vector<int>* variable, const std::string& value);
+  void PopulateVariable(std::vector<double>* variable, const std::string& value);
+  void PopulateVariable(std::vector<char*>* variable, const std::string& value);
+  void PopulateVariable(std::vector<std::string>* variable, const std::string& value);
 
   typedef CommandLineArgumentsInternal Internal;
   Internal* Internals;
-  kwsys_stl::string Help;
+  std::string Help;
 
   unsigned int LineLength;
 
@@ -273,11 +268,6 @@ protected:
 
 } // namespace @KWSYS_NAMESPACE@
 
-/* Undefine temporary macro.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
 #endif
 
 
diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in
index 8f5ace2..3faf862 100644
--- a/Source/kwsys/Configure.hxx.in
+++ b/Source/kwsys/Configure.hxx.in
@@ -15,125 +15,9 @@
 /* Include C configuration.  */
 #include <@KWSYS_NAMESPACE@/Configure.h>
 
-/* Whether ANSI C++ stream headers are to be used.  */
-#define @KWSYS_NAMESPACE at _IOS_USE_ANSI @KWSYS_IOS_USE_ANSI@
-
-/* Whether ANSI C++ streams are in std namespace.  */
-#define @KWSYS_NAMESPACE at _IOS_HAVE_STD @KWSYS_IOS_HAVE_STD@
-
-/* Whether ANSI C++ <sstream> header is to be used.  */
-#define @KWSYS_NAMESPACE at _IOS_USE_SSTREAM @KWSYS_IOS_USE_SSTREAM@
-
-/* Whether old C++ <strstream.h> header is to be used.  */
-#define @KWSYS_NAMESPACE at _IOS_USE_STRSTREAM_H @KWSYS_IOS_USE_STRSTREAM_H@
-
-/* Whether old C++ <strstrea.h> header is to be used.  */
-#define @KWSYS_NAMESPACE at _IOS_USE_STRSTREA_H @KWSYS_IOS_USE_STRSTREA_H@
-
-/* Whether C++ streams support the ios::binary openmode.  */
-#define @KWSYS_NAMESPACE at _IOS_HAVE_BINARY @KWSYS_IOS_HAVE_BINARY@
-
-/* Whether STL is in std namespace.  */
-#define @KWSYS_NAMESPACE at _STL_HAVE_STD @KWSYS_STL_HAVE_STD@
-
 /* Whether wstring is available.  */
 #define @KWSYS_NAMESPACE at _STL_HAS_WSTRING @KWSYS_STL_HAS_WSTRING@
 
-/* Whether the STL string has operator<< for ostream.  */
-#define @KWSYS_NAMESPACE at _STL_STRING_HAVE_OSTREAM @KWSYS_STL_STRING_HAVE_OSTREAM@
-
-/* Whether the STL string has operator>> for istream.  */
-#define @KWSYS_NAMESPACE at _STL_STRING_HAVE_ISTREAM @KWSYS_STL_STRING_HAVE_ISTREAM@
-
-/* Whether the STL string has operator!= for char*.  */
-#define @KWSYS_NAMESPACE at _STL_STRING_HAVE_NEQ_CHAR @KWSYS_STL_STRING_HAVE_NEQ_CHAR@
-
-/* Define the stl namespace macro.  */
-#if @KWSYS_NAMESPACE at _STL_HAVE_STD
-# define @KWSYS_NAMESPACE at _stl std
-#else
-# define @KWSYS_NAMESPACE at _stl
-#endif
-
-/* Define the ios namespace macro.  */
-#if @KWSYS_NAMESPACE at _IOS_HAVE_STD
-# define @KWSYS_NAMESPACE at _ios_namespace std
-#else
-# define @KWSYS_NAMESPACE at _ios_namespace
-#endif
-#if @KWSYS_NAMESPACE at _IOS_USE_SSTREAM
-# define @KWSYS_NAMESPACE at _ios @KWSYS_NAMESPACE at _ios_namespace
-#else
-# define @KWSYS_NAMESPACE at _ios @KWSYS_NAMESPACE at _ios
-#endif
-
-/* Define the ios::binary openmode macro.  */
-#if @KWSYS_NAMESPACE at _IOS_HAVE_BINARY
-# define @KWSYS_NAMESPACE at _ios_binary @KWSYS_NAMESPACE at _ios::ios::binary
-#else
-# define @KWSYS_NAMESPACE at _ios_binary 0
-#endif
-
-/* Whether the cstddef header is available.  */
-#define @KWSYS_NAMESPACE at _CXX_HAS_CSTDDEF @KWSYS_CXX_HAS_CSTDDEF@
-
-/* Whether the compiler supports null template arguments.  */
-#define @KWSYS_NAMESPACE at _CXX_HAS_NULL_TEMPLATE_ARGS @KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS@
-
-/* Define the null template arguments macro.  */
-#if @KWSYS_NAMESPACE at _CXX_HAS_NULL_TEMPLATE_ARGS
-# define @KWSYS_NAMESPACE at _CXX_NULL_TEMPLATE_ARGS <>
-#else
-# define @KWSYS_NAMESPACE at _CXX_NULL_TEMPLATE_ARGS
-#endif
-
-/* Whether the compiler supports member templates.  */
-#define @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES @KWSYS_CXX_HAS_MEMBER_TEMPLATES@
-
-/* Whether the compiler supports argument dependent lookup.  */
-#define @KWSYS_NAMESPACE at _CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP @KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP@
-
-/* Whether the compiler supports standard full specialization syntax.  */
-#define @KWSYS_NAMESPACE at _CXX_HAS_FULL_SPECIALIZATION @KWSYS_CXX_HAS_FULL_SPECIALIZATION@
-
-/* Define the specialization definition macro.  */
-#if @KWSYS_NAMESPACE at _CXX_HAS_FULL_SPECIALIZATION
-# define @KWSYS_NAMESPACE at _CXX_DEFINE_SPECIALIZATION template <>
-#else
-# define @KWSYS_NAMESPACE at _CXX_DEFINE_SPECIALIZATION
-#endif
-
-/* Define typename keyword macro for use in declarations.  */
-#if defined(_MSC_VER) && _MSC_VER < 1300
-# define @KWSYS_NAMESPACE at _CXX_DECL_TYPENAME
-#else
-# define @KWSYS_NAMESPACE at _CXX_DECL_TYPENAME typename
-#endif
-
-/* Whether the stl has iterator_traits.  */
-#define @KWSYS_NAMESPACE at _STL_HAS_ITERATOR_TRAITS @KWSYS_STL_HAS_ITERATOR_TRAITS@
-
-/* Whether the stl has iterator_category.  */
-#define @KWSYS_NAMESPACE at _STL_HAS_ITERATOR_CATEGORY @KWSYS_STL_HAS_ITERATOR_CATEGORY@
-
-/* Whether the stl has __iterator_category.  */
-#define @KWSYS_NAMESPACE at _STL_HAS___ITERATOR_CATEGORY @KWSYS_STL_HAS___ITERATOR_CATEGORY@
-
-/* Whether the stl allocator is the standard template.  */
-#define @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_TEMPLATE @KWSYS_STL_HAS_ALLOCATOR_TEMPLATE@
-
-/* Whether the stl allocator is not a template.  */
-#define @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_NONTEMPLATE @KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE@
-
-/* Whether the stl allocator has rebind.  */
-#define @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_REBIND @KWSYS_STL_HAS_ALLOCATOR_REBIND@
-
-/* Whether the stl allocator has a size argument for max_size.  */
-#define @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT @KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT@
-
-/* Whether the stl containers support allocator objects.  */
-#define @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_OBJECTS @KWSYS_STL_HAS_ALLOCATOR_OBJECTS@
-
 /* Whether struct stat has the st_mtim member for high resolution times.  */
 #define @KWSYS_NAMESPACE at _STAT_HAS_ST_MTIM @KWSYS_STAT_HAS_ST_MTIM@
 
@@ -141,38 +25,10 @@
    access to the macros without a configured namespace.  */
 #if defined(KWSYS_NAMESPACE)
 # if !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-#  define kwsys_stl @KWSYS_NAMESPACE at _stl
-#  define kwsys_ios @KWSYS_NAMESPACE at _ios
 #  define kwsys     @KWSYS_NAMESPACE@
-#  define kwsys_ios_binary @KWSYS_NAMESPACE at _ios_binary
 # endif
 # define KWSYS_NAME_IS_KWSYS            @KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define KWSYS_STL_HAVE_STD             @KWSYS_NAMESPACE at _STL_HAVE_STD
-# define KWSYS_IOS_HAVE_STD             @KWSYS_NAMESPACE at _IOS_HAVE_STD
-# define KWSYS_IOS_USE_ANSI             @KWSYS_NAMESPACE at _IOS_USE_ANSI
-# define KWSYS_IOS_USE_SSTREAM          @KWSYS_NAMESPACE at _IOS_USE_SSTREAM
-# define KWSYS_IOS_USE_STRSTREAM_H      @KWSYS_NAMESPACE at _IOS_USE_STRSTREAM_H
-# define KWSYS_IOS_USE_STRSTREA_H       @KWSYS_NAMESPACE at _IOS_USE_STRSTREA_H
-# define KWSYS_IOS_HAVE_BINARY          @KWSYS_NAMESPACE at _IOS_HAVE_BINARY
 # define KWSYS_STAT_HAS_ST_MTIM         @KWSYS_NAMESPACE at _STAT_HAS_ST_MTIM
-# define KWSYS_CXX_HAS_CSTDDEF          @KWSYS_NAMESPACE at _CXX_HAS_CSTDDEF
-# define KWSYS_STL_STRING_HAVE_OSTREAM  @KWSYS_NAMESPACE at _STL_STRING_HAVE_OSTREAM
-# define KWSYS_STL_STRING_HAVE_ISTREAM  @KWSYS_NAMESPACE at _STL_STRING_HAVE_ISTREAM
-# define KWSYS_STL_STRING_HAVE_NEQ_CHAR @KWSYS_NAMESPACE at _STL_STRING_HAVE_NEQ_CHAR
-# define KWSYS_CXX_NULL_TEMPLATE_ARGS   @KWSYS_NAMESPACE at _CXX_NULL_TEMPLATE_ARGS
-# define KWSYS_CXX_HAS_MEMBER_TEMPLATES @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
-# define KWSYS_CXX_HAS_FULL_SPECIALIZATION @KWSYS_NAMESPACE at _CXX_HAS_FULL_SPECIALIZATION
-# define KWSYS_CXX_DEFINE_SPECIALIZATION @KWSYS_NAMESPACE at _CXX_DEFINE_SPECIALIZATION
-# define KWSYS_CXX_DECL_TYPENAME        @KWSYS_NAMESPACE at _CXX_DECL_TYPENAME
-# define KWSYS_STL_HAS_ALLOCATOR_REBIND @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_REBIND
-# define KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
-# define KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP @KWSYS_NAMESPACE at _CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
-# define KWSYS_STL_HAS_ITERATOR_TRAITS @KWSYS_NAMESPACE at _STL_HAS_ITERATOR_TRAITS
-# define KWSYS_STL_HAS_ITERATOR_CATEGORY @KWSYS_NAMESPACE at _STL_HAS_ITERATOR_CATEGORY
-# define KWSYS_STL_HAS___ITERATOR_CATEGORY @KWSYS_NAMESPACE at _STL_HAS___ITERATOR_CATEGORY
-# define KWSYS_STL_HAS_ALLOCATOR_TEMPLATE @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_TEMPLATE
-# define KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_NONTEMPLATE
-# define KWSYS_STL_HAS_ALLOCATOR_OBJECTS @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_OBJECTS
 # define KWSYS_STL_HAS_WSTRING          @KWSYS_NAMESPACE at _STL_HAS_WSTRING
 #endif
 
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index 58cea63..c549792 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -16,20 +16,17 @@
 
 #include KWSYS_HEADER(Encoding.hxx)
 
-#include KWSYS_HEADER(stl/string)
-#include KWSYS_HEADER(stl/vector)
-
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
 # include "Directory.hxx.in"
 # include "Configure.hxx.in"
 # include "Encoding.hxx.in"
-# include "kwsys_stl.hxx.in"
-# include "kwsys_stl_string.hxx.in"
-# include "kwsys_stl_vector.hxx.in"
 #endif
 
+#include <string>
+#include <vector>
+
 namespace KWSYS_NAMESPACE
 {
 
@@ -38,10 +35,10 @@ class DirectoryInternals
 {
 public:
   // Array of Files
-  kwsys_stl::vector<kwsys_stl::string> Files;
+  std::vector<std::string> Files;
 
   // Path to Open'ed directory
-  kwsys_stl::string Path;
+  std::string Path;
 };
 
 //----------------------------------------------------------------------------
@@ -103,7 +100,7 @@ void Directory::Clear()
 namespace KWSYS_NAMESPACE
 {
 
-bool Directory::Load(const kwsys_stl::string& name)
+bool Directory::Load(const std::string& name)
 {
   this->Clear();
 #if _MSC_VER < 1300
@@ -153,7 +150,7 @@ bool Directory::Load(const kwsys_stl::string& name)
   return _findclose(srchHandle) != -1;
 }
 
-unsigned long Directory::GetNumberOfFilesInDirectory(const kwsys_stl::string& name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
 {
 #if _MSC_VER < 1300
   long srchHandle;
@@ -220,7 +217,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const kwsys_stl::string& na
 namespace KWSYS_NAMESPACE
 {
 
-bool Directory::Load(const kwsys_stl::string& name)
+bool Directory::Load(const std::string& name)
 {
   this->Clear();
    
@@ -240,7 +237,7 @@ bool Directory::Load(const kwsys_stl::string& name)
   return 1;
 }
 
-unsigned long Directory::GetNumberOfFilesInDirectory(const kwsys_stl::string& name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
 {
   DIR* dir = opendir(name.c_str());
 
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index 1bcf90e..e68f337 100644
--- a/Source/kwsys/Directory.hxx.in
+++ b/Source/kwsys/Directory.hxx.in
@@ -13,12 +13,7 @@
 #define @KWSYS_NAMESPACE at _Directory_hxx
 
 #include <@KWSYS_NAMESPACE@/Configure.h>
-#include <@KWSYS_NAMESPACE@/stl/string>
-
-/* Define these macros temporarily to keep the code readable.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE at _stl
-#endif
+#include <string>
 
 namespace @KWSYS_NAMESPACE@
 {
@@ -44,7 +39,7 @@ public:
    * in that directory. 0 is returned if the directory can not be
    * opened, 1 if it is opened.
    */
-  bool Load(const kwsys_stl::string&);
+  bool Load(const std::string&);
 
   /**
    * Return the number of files in the current directory.
@@ -55,7 +50,7 @@ public:
    * Return the number of files in the specified directory.
    * A higher performance static method.
    */
-  static unsigned long GetNumberOfFilesInDirectory(const kwsys_stl::string&);
+  static unsigned long GetNumberOfFilesInDirectory(const std::string&);
 
   /**
    * Return the file at the given index, the indexing is 0 based
@@ -83,9 +78,4 @@ private:
 
 } // namespace @KWSYS_NAMESPACE@
 
-/* Undefine temporary macros.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
 #endif
diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
index a776f97..1941d96 100644
--- a/Source/kwsys/DynamicLoader.cxx
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -40,7 +40,7 @@ namespace KWSYS_NAMESPACE
 {
 
 //----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
 {
   return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L);
 }
@@ -57,7 +57,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
 
 //----------------------------------------------------------------------------
 DynamicLoader::SymbolPointer
-DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym)
+DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const std::string& sym)
 {
   void* addr;
   int status;
@@ -115,7 +115,7 @@ namespace KWSYS_NAMESPACE
 {
 
 //----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
 {
   NSObjectFileImageReturnCode rc;
   NSObjectFileImage image = 0;
@@ -146,7 +146,7 @@ int DynamicLoader::CloseLibrary( DynamicLoader::LibraryHandle lib)
 
 //----------------------------------------------------------------------------
 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
-  DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym)
+  DynamicLoader::LibraryHandle lib, const std::string& sym)
 {
   void *result=0;
   // Need to prepend symbols with '_' on Apple-gcc compilers
@@ -187,7 +187,7 @@ namespace KWSYS_NAMESPACE
 {
 
 //----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname)
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname)
 {
   DynamicLoader::LibraryHandle lh;
   int length = MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, NULL, 0);
@@ -207,7 +207,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
 
 //----------------------------------------------------------------------------
 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
-  DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym)
+  DynamicLoader::LibraryHandle lib, const std::string& sym)
 {
   // TODO: The calling convention affects the name of the symbol.  We
   // should have a tool to help get the symbol with the desired
@@ -302,7 +302,7 @@ namespace KWSYS_NAMESPACE
 static image_id last_dynamic_err = B_OK;
 
 //----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
 {
   // image_id's are integers, errors are negative. Add one just in case we
   //  get a valid image_id of zero (is that even possible?).
@@ -340,7 +340,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
 
 //----------------------------------------------------------------------------
 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
-  DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym)
+  DynamicLoader::LibraryHandle lib, const std::string& sym)
 {
   // Hack to cast pointer-to-data to pointer-to-function.
   union 
@@ -393,7 +393,7 @@ namespace KWSYS_NAMESPACE
 {
 
 //----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
 {
   return 0;
 }
@@ -411,7 +411,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
 
 //----------------------------------------------------------------------------
 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
-    DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym)
+    DynamicLoader::LibraryHandle lib, const std::string& sym)
 {
   return 0;
 }
@@ -437,7 +437,7 @@ namespace KWSYS_NAMESPACE
 {
 
 //----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
 {
   char *name = (char *)calloc(1, libname.size() + 1);
   dld_init(program_invocation_name);
@@ -456,7 +456,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
 
 //----------------------------------------------------------------------------
 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
-  DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym)
+  DynamicLoader::LibraryHandle lib, const std::string& sym)
 {
   // Hack to cast pointer-to-data to pointer-to-function.
   union
@@ -489,7 +489,7 @@ namespace KWSYS_NAMESPACE
 {
 
 //----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
 {
   return dlopen(libname.c_str(), RTLD_LAZY);
 }
@@ -508,7 +508,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
 
 //----------------------------------------------------------------------------
 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
-  DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym)
+  DynamicLoader::LibraryHandle lib, const std::string& sym)
 {
   // Hack to cast pointer-to-data to pointer-to-function.
   union 
diff --git a/Source/kwsys/DynamicLoader.hxx.in b/Source/kwsys/DynamicLoader.hxx.in
index 75811ab..1e4a912 100644
--- a/Source/kwsys/DynamicLoader.hxx.in
+++ b/Source/kwsys/DynamicLoader.hxx.in
@@ -12,8 +12,8 @@
 #ifndef @KWSYS_NAMESPACE at _DynamicLoader_hxx
 #define @KWSYS_NAMESPACE at _DynamicLoader_hxx
 
-#include <@KWSYS_NAMESPACE@/Configure.h>
-#include <@KWSYS_NAMESPACE@/stl/string>
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+#include <string>
 
 #if defined(__hpux)
   #include <dl.h>
@@ -28,11 +28,6 @@
   #include <be/kernel/image.h>
 #endif
 
-/* Define these macros temporarily to keep the code readable.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE at _stl
-#endif
-
 namespace @KWSYS_NAMESPACE@
 {
 /** \class DynamicLoader
@@ -83,14 +78,14 @@ public:
   /** Load a dynamic library into the current process.
    * The returned LibraryHandle can be used to access the symbols in the
    * library. */
-  static LibraryHandle OpenLibrary(const kwsys_stl::string&);
+  static LibraryHandle OpenLibrary(const std::string&);
 
   /** Attempt to detach a dynamic library from the
    * process.  A value of true is returned if it is sucessful. */
   static int CloseLibrary(LibraryHandle);
 
   /** Find the address of the symbol in the given library. */
-  static SymbolPointer GetSymbolAddress(LibraryHandle, const kwsys_stl::string&);
+  static SymbolPointer GetSymbolAddress(LibraryHandle, const std::string&);
 
   /** Return the default module prefix for the current platform.  */
   static const char* LibPrefix() { return "@KWSYS_DynamicLoader_PREFIX@"; }
@@ -104,9 +99,4 @@ public:
 
 } // namespace @KWSYS_NAMESPACE@
 
-/* Undefine temporary macros.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
 #endif
diff --git a/Source/kwsys/Encoding.hxx.in b/Source/kwsys/Encoding.hxx.in
index aba4175..87b1c21 100644
--- a/Source/kwsys/Encoding.hxx.in
+++ b/Source/kwsys/Encoding.hxx.in
@@ -13,13 +13,8 @@
 #define @KWSYS_NAMESPACE at _Encoding_hxx
 
 #include <@KWSYS_NAMESPACE@/Configure.hxx>
-#include <@KWSYS_NAMESPACE@/stl/string>
-#include <@KWSYS_NAMESPACE@/stl/vector>
-
-/* Define these macros temporarily to keep the code readable.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE at _stl
-#endif
+#include <string>
+#include <vector>
 
 namespace @KWSYS_NAMESPACE@
 {
@@ -65,23 +60,18 @@ public:
   // Convert a narrow string to a wide string.
   // On Windows, UTF-8 is assumed, and on other platforms,
   // the current locale is assumed.
-  static kwsys_stl::wstring ToWide(const kwsys_stl::string& str);
-  static kwsys_stl::wstring ToWide(const char* str);
+  static std::wstring ToWide(const std::string& str);
+  static std::wstring ToWide(const char* str);
 
   // Convert a wide string to a narrow string.
   // On Windows, UTF-8 is assumed, and on other platforms,
   // the current locale is assumed.
-  static kwsys_stl::string ToNarrow(const kwsys_stl::wstring& str);
-  static kwsys_stl::string ToNarrow(const wchar_t* str);
+  static std::string ToNarrow(const std::wstring& str);
+  static std::string ToNarrow(const wchar_t* str);
 
 #endif // @KWSYS_NAMESPACE at _STL_HAS_WSTRING
 
 }; // class Encoding
 } // namespace @KWSYS_NAMESPACE@
 
-/* Undefine temporary macros.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
 #endif
diff --git a/Source/kwsys/EncodingC.c b/Source/kwsys/EncodingC.c
index ba2cec2..32b9bff 100644
--- a/Source/kwsys/EncodingC.c
+++ b/Source/kwsys/EncodingC.c
@@ -45,8 +45,11 @@ wchar_t* kwsysEncoding_DupToWide(const char* str)
   if(length > 0)
     {
     ret = (wchar_t*)malloc((length)*sizeof(wchar_t));
-    ret[0] = 0;
-    kwsysEncoding_mbstowcs(ret, str, length);
+    if(ret)
+      {
+      ret[0] = 0;
+      kwsysEncoding_mbstowcs(ret, str, length);
+      }
     }
   return ret;
 }
@@ -72,8 +75,11 @@ char* kwsysEncoding_DupToNarrow(const wchar_t* str)
   if(length > 0)
     {
     ret = (char*)malloc(length);
-    ret[0] = 0;
-    kwsysEncoding_wcstombs(ret, str, length);
+    if(ret)
+      {
+      ret[0] = 0;
+      kwsysEncoding_wcstombs(ret, str, length);
+      }
     }
   return ret;
 }
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index 251a56d..7d9b3e4 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -19,7 +19,6 @@
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(Encoding.hxx)
 #include KWSYS_HEADER(Encoding.h)
-#include KWSYS_HEADER(stl/vector)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
@@ -28,6 +27,7 @@
 # include "Encoding.h.in"
 #endif
 
+#include <vector>
 #include <stdlib.h>
 #include <string.h>
 
@@ -140,23 +140,23 @@ char const* const* Encoding::CommandLineArguments::argv() const
 
 #if KWSYS_STL_HAS_WSTRING
 
-kwsys_stl::wstring Encoding::ToWide(const kwsys_stl::string& str)
+std::wstring Encoding::ToWide(const std::string& str)
 {
   return ToWide(str.c_str());
 }
 
-kwsys_stl::string Encoding::ToNarrow(const kwsys_stl::wstring& str)
+std::string Encoding::ToNarrow(const std::wstring& str)
 {
   return ToNarrow(str.c_str());
 }
 
-kwsys_stl::wstring Encoding::ToWide(const char* cstr)
+std::wstring Encoding::ToWide(const char* cstr)
 {
-  kwsys_stl::wstring wstr;
+  std::wstring wstr;
   size_t length = kwsysEncoding_mbstowcs(0, cstr, 0) + 1;
   if(length > 0)
     {
-    kwsys_stl::vector<wchar_t> wchars(length);
+    std::vector<wchar_t> wchars(length);
     if(kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0)
       {
       wstr = &wchars[0];
@@ -165,9 +165,9 @@ kwsys_stl::wstring Encoding::ToWide(const char* cstr)
   return wstr;
 }
 
-kwsys_stl::string Encoding::ToNarrow(const wchar_t* wcstr)
+std::string Encoding::ToNarrow(const wchar_t* wcstr)
 {
-  kwsys_stl::string str;
+  std::string str;
   size_t length = kwsysEncoding_wcstombs(0, wcstr, 0) + 1;
   if(length > 0)
     {
diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in
index 37055d6..681e4d8 100644
--- a/Source/kwsys/FStream.hxx.in
+++ b/Source/kwsys/FStream.hxx.in
@@ -12,8 +12,8 @@
 #ifndef @KWSYS_NAMESPACE at _FStream_hxx
 #define @KWSYS_NAMESPACE at _FStream_hxx
 
-#include <@KWSYS_NAMESPACE@/ios/fstream>
 #include <@KWSYS_NAMESPACE@/Encoding.hxx>
+#include <fstream>
 
 namespace @KWSYS_NAMESPACE@
 {
@@ -167,8 +167,8 @@ class basic_ofstream : public std::basic_ostream<CharType,Traits>
 
 # undef @KWSYS_NAMESPACE at _FStream_NOEXCEPT
 #else
-  using @KWSYS_NAMESPACE at _ios_namespace::ofstream;
-  using @KWSYS_NAMESPACE at _ios_namespace::ifstream;
+  using std::ofstream;
+  using std::ifstream;
 #endif
 
   namespace FStream
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 11bfd16..9d63459 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -17,9 +17,6 @@
 #include KWSYS_HEADER(RegularExpression.hxx)
 #include KWSYS_HEADER(SystemTools.hxx)
 #include KWSYS_HEADER(Directory.hxx)
-#include KWSYS_HEADER(stl/string)
-#include KWSYS_HEADER(stl/vector)
-#include KWSYS_HEADER(stl/algorithm)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
@@ -29,12 +26,12 @@
 # include "Configure.hxx.in"
 # include "RegularExpression.hxx.in"
 # include "SystemTools.hxx.in"
-# include "kwsys_stl.hxx.in"
-# include "kwsys_stl_string.hxx.in"
-# include "kwsys_stl_vector.hxx.in"
-# include "kwsys_stl_algorithm.hxx.in"
 #endif
 
+#include <string>
+#include <vector>
+#include <algorithm>
+
 #include <ctype.h>
 #include <stdio.h>
 #include <string.h>
@@ -54,8 +51,8 @@ namespace KWSYS_NAMESPACE
 class GlobInternals
 {
 public:
-  kwsys_stl::vector<kwsys_stl::string> Files;
-  kwsys_stl::vector<kwsys::RegularExpression> Expressions;
+  std::vector<std::string> Files;
+  std::vector<kwsys::RegularExpression> Expressions;
 };
 
 //----------------------------------------------------------------------------
@@ -82,21 +79,21 @@ Glob::~Glob()
 }
 
 //----------------------------------------------------------------------------
-kwsys_stl::vector<kwsys_stl::string>& Glob::GetFiles()
+std::vector<std::string>& Glob::GetFiles()
 {
   return this->Internals->Files;
 }
 
 //----------------------------------------------------------------------------
-kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
+std::string Glob::PatternToRegex(const std::string& pattern,
                                        bool require_whole_string,
                                        bool preserve_case)
 {
   // Incrementally build the regular expression from the pattern.
-  kwsys_stl::string regex = require_whole_string? "^" : "";
-  kwsys_stl::string::const_iterator pattern_first = pattern.begin();
-  kwsys_stl::string::const_iterator pattern_last = pattern.end();
-  for(kwsys_stl::string::const_iterator i = pattern_first;
+  std::string regex = require_whole_string? "^" : "";
+  std::string::const_iterator pattern_first = pattern.begin();
+  std::string::const_iterator pattern_last = pattern.end();
+  for(std::string::const_iterator i = pattern_first;
       i != pattern_last; ++i)
     {
     int c = *i;
@@ -120,8 +117,8 @@ kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
       {
       // Parse out the bracket expression.  It begins just after the
       // opening character.
-      kwsys_stl::string::const_iterator bracket_first = i+1;
-      kwsys_stl::string::const_iterator bracket_last = bracket_first;
+      std::string::const_iterator bracket_first = i+1;
+      std::string::const_iterator bracket_last = bracket_first;
 
       // The first character may be complementation '!' or '^'.
       if(bracket_last != pattern_last &&
@@ -153,7 +150,7 @@ kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
       else
         {
         // Convert the bracket string to its regex equivalent.
-        kwsys_stl::string::const_iterator k = bracket_first;
+        std::string::const_iterator k = bracket_first;
 
         // Open the regex block.
         regex += "[";
@@ -221,8 +218,8 @@ kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
 }
 
 //----------------------------------------------------------------------------
-bool Glob::RecurseDirectory(kwsys_stl::string::size_type start,
-  const kwsys_stl::string& dir, GlobMessages* messages)
+bool Glob::RecurseDirectory(std::string::size_type start,
+  const std::string& dir, GlobMessages* messages)
 {
   kwsys::Directory d;
   if ( !d.Load(dir) )
@@ -230,8 +227,8 @@ bool Glob::RecurseDirectory(kwsys_stl::string::size_type start,
     return true;
     }
   unsigned long cc;
-  kwsys_stl::string realname;
-  kwsys_stl::string fname;
+  std::string realname;
+  std::string fname;
   for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
     {
     fname = d.GetFile(cc);
@@ -262,8 +259,8 @@ bool Glob::RecurseDirectory(kwsys_stl::string::size_type start,
       if (isSymLink)
         {
         ++this->FollowedSymlinkCount;
-        kwsys_stl::string realPathErrorMessage;
-        kwsys_stl::string canonicalPath(SystemTools::GetRealPath(dir,
+        std::string realPathErrorMessage;
+        std::string canonicalPath(SystemTools::GetRealPath(dir,
             &realPathErrorMessage));
 
         if(!realPathErrorMessage.empty())
@@ -277,7 +274,7 @@ bool Glob::RecurseDirectory(kwsys_stl::string::size_type start,
           return false;
           }
 
-        if(kwsys_stl::find(this->VisitedSymlinks.begin(),
+        if(std::find(this->VisitedSymlinks.begin(),
             this->VisitedSymlinks.end(),
             canonicalPath) == this->VisitedSymlinks.end())
           {
@@ -299,9 +296,9 @@ bool Glob::RecurseDirectory(kwsys_stl::string::size_type start,
         // else we have already visited this symlink - prevent cyclic recursion
         else if(messages)
           {
-          kwsys_stl::string message;
-          for(kwsys_stl::vector<kwsys_stl::string>::const_iterator
-                pathIt = kwsys_stl::find(this->VisitedSymlinks.begin(),
+          std::string message;
+          for(std::vector<std::string>::const_iterator
+                pathIt = std::find(this->VisitedSymlinks.begin(),
                                          this->VisitedSymlinks.end(),
                                          canonicalPath);
               pathIt != this->VisitedSymlinks.end(); ++pathIt)
@@ -338,10 +335,10 @@ bool Glob::RecurseDirectory(kwsys_stl::string::size_type start,
 }
 
 //----------------------------------------------------------------------------
-void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
-  const kwsys_stl::string& dir, GlobMessages* messages)
+void Glob::ProcessDirectory(std::string::size_type start,
+  const std::string& dir, GlobMessages* messages)
 {
-  //kwsys_ios::cout << "ProcessDirectory: " << dir << kwsys_ios::endl;
+  //std::cout << "ProcessDirectory: " << dir << std::endl;
   bool last = ( start == this->Internals->Expressions.size()-1 );
   if ( last && this->Recurse )
     {
@@ -360,8 +357,8 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
     return;
     }
   unsigned long cc;
-  kwsys_stl::string realname;
-  kwsys_stl::string fname;
+  std::string realname;
+  std::string fname;
   for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
     {
     fname = d.GetFile(cc);
@@ -384,10 +381,10 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
     fname = kwsys::SystemTools::LowerCase(fname);
 #endif
 
-    //kwsys_ios::cout << "Look at file: " << fname << kwsys_ios::endl;
-    //kwsys_ios::cout << "Match: "
-    // << this->Internals->TextExpressions[start].c_str() << kwsys_ios::endl;
-    //kwsys_ios::cout << "Real name: " << realname << kwsys_ios::endl;
+    //std::cout << "Look at file: " << fname << std::endl;
+    //std::cout << "Match: "
+    // << this->Internals->TextExpressions[start].c_str() << std::endl;
+    //std::cout << "Real name: " << realname << std::endl;
 
     if( (!last && !kwsys::SystemTools::FileIsDirectory(realname))
       || (!this->ListDirs && last &&
@@ -411,11 +408,11 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
 }
 
 //----------------------------------------------------------------------------
-bool Glob::FindFiles(const kwsys_stl::string& inexpr, GlobMessages* messages)
+bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages)
 {
-  kwsys_stl::string cexpr;
-  kwsys_stl::string::size_type cc;
-  kwsys_stl::string expr = inexpr;
+  std::string cexpr;
+  std::string::size_type cc;
+  std::string expr = inexpr;
 
   this->Internals->Expressions.clear();
   this->Internals->Files.clear();
@@ -425,10 +422,10 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr, GlobMessages* messages)
     expr = kwsys::SystemTools::GetCurrentWorkingDirectory();
     expr += "/" + inexpr;
     }
-  kwsys_stl::string fexpr = expr;
+  std::string fexpr = expr;
 
-  kwsys_stl::string::size_type skip = 0;
-  kwsys_stl::string::size_type last_slash = 0;
+  std::string::size_type skip = 0;
+  std::string::size_type last_slash = 0;
   for ( cc = 0; cc < expr.size(); cc ++ )
     {
     if ( cc > 0 && expr[cc] == '/' && expr[cc-1] != '\\' )
@@ -444,8 +441,8 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr, GlobMessages* messages)
     }
   if ( last_slash > 0 )
     {
-    //kwsys_ios::cout << "I can skip: " << fexpr.substr(0, last_slash)
-    // << kwsys_ios::endl;
+    //std::cout << "I can skip: " << fexpr.substr(0, last_slash)
+    // << std::endl;
     skip = last_slash;
     }
   if ( skip == 0 )
@@ -517,7 +514,7 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr, GlobMessages* messages)
 }
 
 //----------------------------------------------------------------------------
-void Glob::AddExpression(const kwsys_stl::string& expr)
+void Glob::AddExpression(const std::string& expr)
 {
   this->Internals->Expressions.push_back(
     kwsys::RegularExpression(
@@ -546,7 +543,7 @@ const char* Glob::GetRelative()
 }
 
 //----------------------------------------------------------------------------
-void Glob::AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const kwsys_stl::string& file)
+void Glob::AddFile(std::vector<std::string>& files, const std::string& file)
 {
   if ( !this->Relative.empty() )
     {
diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
index 5239ccd..ffee9ca 100644
--- a/Source/kwsys/Glob.hxx.in
+++ b/Source/kwsys/Glob.hxx.in
@@ -15,13 +15,8 @@
 #include <@KWSYS_NAMESPACE@/Configure.h>
 #include <@KWSYS_NAMESPACE@/Configure.hxx>
 
-#include <@KWSYS_NAMESPACE@/stl/string>
-#include <@KWSYS_NAMESPACE@/stl/vector>
-
-/* Define this macro temporarily to keep the code readable.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE at _stl
-#endif
+#include <string>
+#include <vector>
 
 namespace @KWSYS_NAMESPACE@
 {
@@ -49,9 +44,9 @@ public:
   struct Message
   {
     MessageType type;
-    kwsys_stl::string content;
+    std::string content;
 
-    Message(MessageType t, const kwsys_stl::string& c) :
+    Message(MessageType t, const std::string& c) :
       type(t),
       content(c)
     {}
@@ -67,18 +62,18 @@ public:
       }
   };
 
-  typedef kwsys_stl::vector<Message> GlobMessages;
-  typedef kwsys_stl::vector<Message>::iterator GlobMessagesIterator;
+  typedef std::vector<Message> GlobMessages;
+  typedef std::vector<Message>::iterator GlobMessagesIterator;
 public:
   Glob();
   ~Glob();
 
   //! Find all files that match the pattern.
-  bool FindFiles(const kwsys_stl::string& inexpr,
+  bool FindFiles(const std::string& inexpr,
     GlobMessages* messages = 0);
 
   //! Return the list of files that matched.
-  kwsys_stl::vector<kwsys_stl::string>& GetFiles();
+  std::vector<std::string>& GetFiles();
 
   //! Set recurse to true to match subdirectories.
   void RecurseOn() { this->SetRecurse(true); }
@@ -107,7 +102,7 @@ public:
       string.  This is on by default because patterns always match
       whole strings, but may be disabled to support concatenating
       expressions more easily (regex1|regex2|etc).  */
-  static kwsys_stl::string PatternToRegex(const kwsys_stl::string& pattern,
+  static std::string PatternToRegex(const std::string& pattern,
                                           bool require_whole_string = true,
                                           bool preserve_case = false);
 
@@ -122,28 +117,28 @@ public:
 
 protected:
   //! Process directory
-  void ProcessDirectory(kwsys_stl::string::size_type start,
-    const kwsys_stl::string& dir,
+  void ProcessDirectory(std::string::size_type start,
+    const std::string& dir,
     GlobMessages* messages);
 
   //! Process last directory, but only when recurse flags is on. That is
   // effectively like saying: /path/to/file/**/file
-  bool RecurseDirectory(kwsys_stl::string::size_type start,
-    const kwsys_stl::string& dir,
+  bool RecurseDirectory(std::string::size_type start,
+    const std::string& dir,
     GlobMessages* messages);
 
   //! Add regular expression
-  void AddExpression(const kwsys_stl::string& expr);
+  void AddExpression(const std::string& expr);
 
   //! Add a file to the list
-  void AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const kwsys_stl::string& file);
+  void AddFile(std::vector<std::string>& files, const std::string& file);
 
   GlobInternals* Internals;
   bool Recurse;
-  kwsys_stl::string Relative;
+  std::string Relative;
   bool RecurseThroughSymlinks;
   unsigned int FollowedSymlinkCount;
-  kwsys_stl::vector<kwsys_stl::string> VisitedSymlinks;
+  std::vector<std::string> VisitedSymlinks;
   bool ListDirs;
   bool RecurseListDirs;
 
@@ -154,9 +149,4 @@ private:
 
 } // namespace @KWSYS_NAMESPACE@
 
-/* Undefine temporary macro.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
 #endif
diff --git a/Source/kwsys/IOStream.cxx b/Source/kwsys/IOStream.cxx
index a31f8c8..81c6a73 100644
--- a/Source/kwsys/IOStream.cxx
+++ b/Source/kwsys/IOStream.cxx
@@ -12,25 +12,14 @@
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(Configure.hxx)
 
-// Configure the implementation for the current streams library.
-#if !KWSYS_IOS_USE_ANSI
-# define ios_base ios
-# if defined(__HP_aCC)
-#  define protected public
-#  include <iostream.h> // Hack access to some private stream methods.
-#  undef protected
-# endif
-#endif
-
 // Include the streams library.
-#include KWSYS_HEADER(ios/iostream)
+#include <iostream>
 #include KWSYS_HEADER(IOStream.hxx)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
 # include "Configure.hxx.in"
-# include "kwsys_ios_iostream.hxx.in"
 # include "IOStream.hxx.in"
 #endif
 
@@ -50,7 +39,7 @@ namespace KWSYS_NAMESPACE
 {
 
 // Scan an input stream for an integer value.
-static int IOStreamScanStream(kwsys_ios::istream& is, char* buffer)
+static int IOStreamScanStream(std::istream& is, char* buffer)
 {
   // Prepare to write to buffer.
   char* out = buffer;
@@ -64,10 +53,10 @@ static int IOStreamScanStream(kwsys_ios::istream& is, char* buffer)
   // detect it from the input.  A leading 0x means hex, and a leading
   // 0 alone means octal.
   int base = 0;
-  int flags = is.flags() & kwsys_ios::ios_base::basefield;
-  if(flags == kwsys_ios::ios_base::oct) { base = 8; }
-  else if(flags == kwsys_ios::ios_base::dec) { base = 10; }
-  else if(flags == kwsys_ios::ios_base::hex) { base = 16; }
+  int flags = is.flags() & std::ios_base::basefield;
+  if(flags == std::ios_base::oct) { base = 8; }
+  else if(flags == std::ios_base::dec) { base = 10; }
+  else if(flags == std::ios_base::hex) { base = 16; }
   bool foundDigit = false;
   bool foundNonZero = false;
   if(is.peek() == '0')
@@ -134,24 +123,17 @@ static int IOStreamScanStream(kwsys_ios::istream& is, char* buffer)
 
 // Read an integer value from an input stream.
 template <class T>
-kwsys_ios::istream&
-IOStreamScanTemplate(kwsys_ios::istream& is, T& value, char type)
+std::istream&
+IOStreamScanTemplate(std::istream& is, T& value, char type)
 {
-  int state = kwsys_ios::ios_base::goodbit;
+  int state = std::ios_base::goodbit;
 
   // Skip leading whitespace.
-# if KWSYS_IOS_USE_ANSI
-  kwsys_ios::istream::sentry okay(is);
-# else
-  is.eatwhite();
-  kwsys_ios::istream& okay = is;
-# endif
+  std::istream::sentry okay(is);
 
   if(okay)
     {
-#   if KWSYS_IOS_USE_ANSI
     try {
-#   endif
     // Copy the string to a buffer and construct the format string.
     char buffer[KWSYS_IOS_INT64_MAX_DIG];
 #   if defined(_MSC_VER)
@@ -174,52 +156,40 @@ IOStreamScanTemplate(kwsys_ios::istream& is, T& value, char type)
     int success = (sscanf(buffer, format, &result) == 1)?1:0;
 
     // Set flags for resulting state.
-    if(is.peek() == EOF) { state |= kwsys_ios::ios_base::eofbit; }
-    if(!success) { state |= kwsys_ios::ios_base::failbit; }
+    if(is.peek() == EOF) { state |= std::ios_base::eofbit; }
+    if(!success) { state |= std::ios_base::failbit; }
     else { value = result; }
-#   if KWSYS_IOS_USE_ANSI
-    } catch(...) { state |= kwsys_ios::ios_base::badbit; }
-#   endif
+    } catch(...) { state |= std::ios_base::badbit; }
     }
 
-# if KWSYS_IOS_USE_ANSI
-  is.setstate(kwsys_ios::ios_base::iostate(state));
-# else
-  is.clear(state);
-# endif
+  is.setstate(std::ios_base::iostate(state));
   return is;
 }
 
 // Print an integer value to an output stream.
 template <class T>
-kwsys_ios::ostream&
-IOStreamPrintTemplate(kwsys_ios::ostream& os, T value, char type)
+std::ostream&
+IOStreamPrintTemplate(std::ostream& os, T value, char type)
 {
-# if KWSYS_IOS_USE_ANSI
-  kwsys_ios::ostream::sentry okay(os);
-# else
-  kwsys_ios::ostream& okay = os;
-# endif
+  std::ostream::sentry okay(os);
   if(okay)
     {
-#   if KWSYS_IOS_USE_ANSI
     try {
-#   endif
     // Construct the format string.
     char format[8];
     char* f = format;
     *f++ = '%';
-    if(os.flags() & kwsys_ios::ios_base::showpos) { *f++ = '+'; }
-    if(os.flags() & kwsys_ios::ios_base::showbase) { *f++ = '#'; }
+    if(os.flags() & std::ios_base::showpos) { *f++ = '+'; }
+    if(os.flags() & std::ios_base::showbase) { *f++ = '#'; }
 #   if defined(_MSC_VER)
     *f++ = 'I'; *f++ = '6'; *f++ = '4';
 #   else
     *f++ = 'l'; *f++ = 'l';
 #   endif
-    long bflags = os.flags() & kwsys_ios::ios_base::basefield;
-    if(bflags == kwsys_ios::ios_base::oct) { *f++ = 'o'; }
-    else if(bflags != kwsys_ios::ios_base::hex) { *f++ = type; }
-    else if(os.flags() & kwsys_ios::ios_base::uppercase) { *f++ = 'X'; }
+    long bflags = os.flags() & std::ios_base::basefield;
+    if(bflags == std::ios_base::oct) { *f++ = 'o'; }
+    else if(bflags != std::ios_base::hex) { *f++ = type; }
+    else if(os.flags() & std::ios_base::uppercase) { *f++ = 'X'; }
     else { *f++ = 'x'; }
     *f = '\0';
 
@@ -228,22 +198,20 @@ IOStreamPrintTemplate(kwsys_ios::ostream& os, T value, char type)
     char buffer[2*KWSYS_IOS_INT64_MAX_DIG];
     sprintf(buffer, format, value);
     os << buffer;
-#   if KWSYS_IOS_USE_ANSI
-    } catch(...) { os.clear(os.rdstate() | kwsys_ios::ios_base::badbit); }
-#   endif
+    } catch(...) { os.clear(os.rdstate() | std::ios_base::badbit); }
     }
   return os;
 }
 
 # if !KWSYS_IOS_HAS_ISTREAM_LONG_LONG
 // Implement input stream operator for IOStreamSLL.
-kwsys_ios::istream& IOStreamScan(kwsys_ios::istream& is, IOStreamSLL& value)
+std::istream& IOStreamScan(std::istream& is, IOStreamSLL& value)
 {
   return IOStreamScanTemplate(is, value, 'd');
 }
 
 // Implement input stream operator for IOStreamULL.
-kwsys_ios::istream& IOStreamScan(kwsys_ios::istream& is, IOStreamULL& value)
+std::istream& IOStreamScan(std::istream& is, IOStreamULL& value)
 {
   return IOStreamScanTemplate(is, value, 'u');
 }
@@ -251,13 +219,13 @@ kwsys_ios::istream& IOStreamScan(kwsys_ios::istream& is, IOStreamULL& value)
 
 # if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG
 // Implement output stream operator for IOStreamSLL.
-kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream& os, IOStreamSLL value)
+std::ostream& IOStreamPrint(std::ostream& os, IOStreamSLL value)
 {
   return IOStreamPrintTemplate(os, value, 'd');
 }
 
 // Implement output stream operator for IOStreamULL.
-kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream& os, IOStreamULL value)
+std::ostream& IOStreamPrint(std::ostream& os, IOStreamULL value)
 {
   return IOStreamPrintTemplate(os, value, 'u');
 }
diff --git a/Source/kwsys/IOStream.hxx.in b/Source/kwsys/IOStream.hxx.in
index 2eeedf2..c101909 100644
--- a/Source/kwsys/IOStream.hxx.in
+++ b/Source/kwsys/IOStream.hxx.in
@@ -12,12 +12,11 @@
 #ifndef @KWSYS_NAMESPACE at _IOStream_hxx
 #define @KWSYS_NAMESPACE at _IOStream_hxx
 
-#include <@KWSYS_NAMESPACE@/ios/iosfwd>
+#include <iosfwd>
 
 /* Define these macros temporarily to keep the code readable.  */
 #if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
 # define kwsysEXPORT @KWSYS_NAMESPACE at _EXPORT
-# define kwsys_ios @KWSYS_NAMESPACE at _ios
 #endif
 
 /* Whether istream supports long long.  */
@@ -56,10 +55,8 @@
 /* Input stream operator implementation functions.  */
 namespace @KWSYS_NAMESPACE@
 {
-kwsysEXPORT kwsys_ios::istream& IOStreamScan(kwsys_ios::istream&,
-                                             IOStreamSLL&);
-kwsysEXPORT kwsys_ios::istream& IOStreamScan(kwsys_ios::istream&,
-                                             IOStreamULL&);
+kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamSLL&);
+kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamULL&);
 }
 
 /* Provide input stream operator for long long.  */
@@ -67,8 +64,8 @@ kwsysEXPORT kwsys_ios::istream& IOStreamScan(kwsys_ios::istream&,
       !defined(KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED)
 #   define KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED
 #   define @KWSYS_NAMESPACE at _IOS_ISTREAM_LONG_LONG_DEFINED
-inline kwsys_ios::istream&
-operator>>(kwsys_ios::istream& is, @KWSYS_NAMESPACE@::IOStreamSLL& value)
+inline std::istream&
+operator>>(std::istream& is, @KWSYS_NAMESPACE@::IOStreamSLL& value)
 {
   return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
 }
@@ -79,8 +76,8 @@ operator>>(kwsys_ios::istream& is, @KWSYS_NAMESPACE@::IOStreamSLL& value)
       !defined(KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED)
 #   define KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
 #   define @KWSYS_NAMESPACE at _IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
-inline kwsys_ios::istream&
-operator>>(kwsys_ios::istream& is, @KWSYS_NAMESPACE@::IOStreamULL& value)
+inline std::istream&
+operator>>(std::istream& is, @KWSYS_NAMESPACE@::IOStreamULL& value)
 {
   return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
 }
@@ -92,10 +89,8 @@ operator>>(kwsys_ios::istream& is, @KWSYS_NAMESPACE@::IOStreamULL& value)
 /* Output stream operator implementation functions.  */
 namespace @KWSYS_NAMESPACE@
 {
-kwsysEXPORT kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream&,
-                                              IOStreamSLL);
-kwsysEXPORT kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream&,
-                                              IOStreamULL);
+kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamSLL);
+kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamULL);
 }
 
 /* Provide output stream operator for long long.  */
@@ -103,8 +98,8 @@ kwsysEXPORT kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream&,
       !defined(KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED)
 #   define KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED
 #   define @KWSYS_NAMESPACE at _IOS_OSTREAM_LONG_LONG_DEFINED
-inline kwsys_ios::ostream&
-operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamSLL value)
+inline std::ostream&
+operator<<(std::ostream& os, @KWSYS_NAMESPACE@::IOStreamSLL value)
 {
   return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
 }
@@ -115,8 +110,8 @@ operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamSLL value)
       !defined(KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED)
 #   define KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
 #   define @KWSYS_NAMESPACE at _IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
-inline kwsys_ios::ostream&
-operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value)
+inline std::ostream&
+operator<<(std::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value)
 {
   return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
 }
@@ -127,7 +122,6 @@ operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value)
 /* Undefine temporary macros.  */
 #if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
 # undef kwsysEXPORT
-# undef kwsys_ios
 #endif
 
 /* If building a C++ file in kwsys itself, give the source file
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
index e35939f..c5ebc97 100644
--- a/Source/kwsys/Process.h.in
+++ b/Source/kwsys/Process.h.in
@@ -23,58 +23,60 @@
 # define kwsysEXPORT @KWSYS_NAMESPACE at _EXPORT
 #endif
 #if !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsysProcess                     kwsys_ns(Process)
-# define kwsysProcess_s                   kwsys_ns(Process_s)
-# define kwsysProcess_New                 kwsys_ns(Process_New)
-# define kwsysProcess_Delete              kwsys_ns(Process_Delete)
-# define kwsysProcess_SetCommand          kwsys_ns(Process_SetCommand)
-# define kwsysProcess_AddCommand          kwsys_ns(Process_AddCommand)
-# define kwsysProcess_SetTimeout          kwsys_ns(Process_SetTimeout)
-# define kwsysProcess_SetWorkingDirectory kwsys_ns(Process_SetWorkingDirectory)
-# define kwsysProcess_SetPipeFile         kwsys_ns(Process_SetPipeFile)
-# define kwsysProcess_SetPipeNative       kwsys_ns(Process_SetPipeNative)
-# define kwsysProcess_SetPipeShared       kwsys_ns(Process_SetPipeShared)
-# define kwsysProcess_Option_Detach       kwsys_ns(Process_Option_Detach)
-# define kwsysProcess_Option_HideWindow   kwsys_ns(Process_Option_HideWindow)
-# define kwsysProcess_Option_MergeOutput  kwsys_ns(Process_Option_MergeOutput)
-# define kwsysProcess_Option_Verbatim     kwsys_ns(Process_Option_Verbatim)
-# define kwsysProcess_GetOption           kwsys_ns(Process_GetOption)
-# define kwsysProcess_SetOption           kwsys_ns(Process_SetOption)
-# define kwsysProcess_Option_e            kwsys_ns(Process_Option_e)
-# define kwsysProcess_State_Starting      kwsys_ns(Process_State_Starting)
-# define kwsysProcess_State_Error         kwsys_ns(Process_State_Error)
-# define kwsysProcess_State_Exception     kwsys_ns(Process_State_Exception)
-# define kwsysProcess_State_Executing     kwsys_ns(Process_State_Executing)
-# define kwsysProcess_State_Exited        kwsys_ns(Process_State_Exited)
-# define kwsysProcess_State_Expired       kwsys_ns(Process_State_Expired)
-# define kwsysProcess_State_Killed        kwsys_ns(Process_State_Killed)
-# define kwsysProcess_State_Disowned      kwsys_ns(Process_State_Disowned)
-# define kwsysProcess_GetState            kwsys_ns(Process_GetState)
-# define kwsysProcess_State_e             kwsys_ns(Process_State_e)
-# define kwsysProcess_Exception_None      kwsys_ns(Process_Exception_None)
-# define kwsysProcess_Exception_Fault     kwsys_ns(Process_Exception_Fault)
-# define kwsysProcess_Exception_Illegal   kwsys_ns(Process_Exception_Illegal)
-# define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt)
-# define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical)
-# define kwsysProcess_Exception_Other     kwsys_ns(Process_Exception_Other)
-# define kwsysProcess_GetExitException    kwsys_ns(Process_GetExitException)
-# define kwsysProcess_Exception_e         kwsys_ns(Process_Exception_e)
-# define kwsysProcess_GetExitCode         kwsys_ns(Process_GetExitCode)
-# define kwsysProcess_GetExitValue        kwsys_ns(Process_GetExitValue)
-# define kwsysProcess_GetErrorString      kwsys_ns(Process_GetErrorString)
-# define kwsysProcess_GetExceptionString  kwsys_ns(Process_GetExceptionString)
-# define kwsysProcess_Execute             kwsys_ns(Process_Execute)
-# define kwsysProcess_Disown              kwsys_ns(Process_Disown)
-# define kwsysProcess_WaitForData         kwsys_ns(Process_WaitForData)
-# define kwsysProcess_Pipes_e             kwsys_ns(Process_Pipes_e)
-# define kwsysProcess_Pipe_None           kwsys_ns(Process_Pipe_None)
-# define kwsysProcess_Pipe_STDIN          kwsys_ns(Process_Pipe_STDIN)
-# define kwsysProcess_Pipe_STDOUT         kwsys_ns(Process_Pipe_STDOUT)
-# define kwsysProcess_Pipe_STDERR         kwsys_ns(Process_Pipe_STDERR)
-# define kwsysProcess_Pipe_Timeout        kwsys_ns(Process_Pipe_Timeout)
-# define kwsysProcess_Pipe_Handle         kwsys_ns(Process_Pipe_Handle)
-# define kwsysProcess_WaitForExit         kwsys_ns(Process_WaitForExit)
-# define kwsysProcess_Kill                kwsys_ns(Process_Kill)
+# define kwsysProcess                           kwsys_ns(Process)
+# define kwsysProcess_s                         kwsys_ns(Process_s)
+# define kwsysProcess_New                       kwsys_ns(Process_New)
+# define kwsysProcess_Delete                    kwsys_ns(Process_Delete)
+# define kwsysProcess_SetCommand                kwsys_ns(Process_SetCommand)
+# define kwsysProcess_AddCommand                kwsys_ns(Process_AddCommand)
+# define kwsysProcess_SetTimeout                kwsys_ns(Process_SetTimeout)
+# define kwsysProcess_SetWorkingDirectory       kwsys_ns(Process_SetWorkingDirectory)
+# define kwsysProcess_SetPipeFile               kwsys_ns(Process_SetPipeFile)
+# define kwsysProcess_SetPipeNative             kwsys_ns(Process_SetPipeNative)
+# define kwsysProcess_SetPipeShared             kwsys_ns(Process_SetPipeShared)
+# define kwsysProcess_Option_Detach             kwsys_ns(Process_Option_Detach)
+# define kwsysProcess_Option_HideWindow         kwsys_ns(Process_Option_HideWindow)
+# define kwsysProcess_Option_MergeOutput        kwsys_ns(Process_Option_MergeOutput)
+# define kwsysProcess_Option_Verbatim           kwsys_ns(Process_Option_Verbatim)
+# define kwsysProcess_Option_CreateProcessGroup kwsys_ns(Process_Option_CreateProcessGroup)
+# define kwsysProcess_GetOption                 kwsys_ns(Process_GetOption)
+# define kwsysProcess_SetOption                 kwsys_ns(Process_SetOption)
+# define kwsysProcess_Option_e                  kwsys_ns(Process_Option_e)
+# define kwsysProcess_State_Starting            kwsys_ns(Process_State_Starting)
+# define kwsysProcess_State_Error               kwsys_ns(Process_State_Error)
+# define kwsysProcess_State_Exception           kwsys_ns(Process_State_Exception)
+# define kwsysProcess_State_Executing           kwsys_ns(Process_State_Executing)
+# define kwsysProcess_State_Exited              kwsys_ns(Process_State_Exited)
+# define kwsysProcess_State_Expired             kwsys_ns(Process_State_Expired)
+# define kwsysProcess_State_Killed              kwsys_ns(Process_State_Killed)
+# define kwsysProcess_State_Disowned            kwsys_ns(Process_State_Disowned)
+# define kwsysProcess_GetState                  kwsys_ns(Process_GetState)
+# define kwsysProcess_State_e                   kwsys_ns(Process_State_e)
+# define kwsysProcess_Exception_None            kwsys_ns(Process_Exception_None)
+# define kwsysProcess_Exception_Fault           kwsys_ns(Process_Exception_Fault)
+# define kwsysProcess_Exception_Illegal         kwsys_ns(Process_Exception_Illegal)
+# define kwsysProcess_Exception_Interrupt       kwsys_ns(Process_Exception_Interrupt)
+# define kwsysProcess_Exception_Numerical       kwsys_ns(Process_Exception_Numerical)
+# define kwsysProcess_Exception_Other           kwsys_ns(Process_Exception_Other)
+# define kwsysProcess_GetExitException          kwsys_ns(Process_GetExitException)
+# define kwsysProcess_Exception_e               kwsys_ns(Process_Exception_e)
+# define kwsysProcess_GetExitCode               kwsys_ns(Process_GetExitCode)
+# define kwsysProcess_GetExitValue              kwsys_ns(Process_GetExitValue)
+# define kwsysProcess_GetErrorString            kwsys_ns(Process_GetErrorString)
+# define kwsysProcess_GetExceptionString        kwsys_ns(Process_GetExceptionString)
+# define kwsysProcess_Execute                   kwsys_ns(Process_Execute)
+# define kwsysProcess_Disown                    kwsys_ns(Process_Disown)
+# define kwsysProcess_WaitForData               kwsys_ns(Process_WaitForData)
+# define kwsysProcess_Pipes_e                   kwsys_ns(Process_Pipes_e)
+# define kwsysProcess_Pipe_None                 kwsys_ns(Process_Pipe_None)
+# define kwsysProcess_Pipe_STDIN                kwsys_ns(Process_Pipe_STDIN)
+# define kwsysProcess_Pipe_STDOUT               kwsys_ns(Process_Pipe_STDOUT)
+# define kwsysProcess_Pipe_STDERR               kwsys_ns(Process_Pipe_STDERR)
+# define kwsysProcess_Pipe_Timeout              kwsys_ns(Process_Pipe_Timeout)
+# define kwsysProcess_Pipe_Handle               kwsys_ns(Process_Pipe_Handle)
+# define kwsysProcess_WaitForExit               kwsys_ns(Process_WaitForExit)
+# define kwsysProcess_Interrupt                 kwsys_ns(Process_Interrupt)
+# define kwsysProcess_Kill                      kwsys_ns(Process_Kill)
 #endif
 
 #if defined(__cplusplus)
@@ -199,6 +201,15 @@ kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe,
  *                                 and ignore the rest of the arguments.
  *         0 = No (default)
  *         1 = Yes
+ *
+ *  kwsysProcess_Option_CreateProcessGroup = Whether to place the process in a
+ *                                           new process group.  This is
+ *                                           useful if you want to send Ctrl+C
+ *                                           to the process.  On UNIX, also
+ *                                           places the process in a new
+ *                                           session.
+ *         0 = No (default)
+ *         1 = Yes
  */
 kwsysEXPORT int kwsysProcess_GetOption(kwsysProcess* cp, int optionId);
 kwsysEXPORT void kwsysProcess_SetOption(kwsysProcess* cp, int optionId,
@@ -208,7 +219,8 @@ enum kwsysProcess_Option_e
   kwsysProcess_Option_HideWindow,
   kwsysProcess_Option_Detach,
   kwsysProcess_Option_MergeOutput,
-  kwsysProcess_Option_Verbatim
+  kwsysProcess_Option_Verbatim,
+  kwsysProcess_Option_CreateProcessGroup
 };
 
 /**
@@ -363,6 +375,17 @@ enum kwsysProcess_Pipes_e
 kwsysEXPORT int kwsysProcess_WaitForExit(kwsysProcess* cp, double* timeout);
 
 /**
+ * Interrupt the process group for the child process that is currently
+ * running by sending it the appropriate operating-system specific signal.
+ * The caller should call WaitForExit after this returns to wait for the
+ * child to terminate.
+ *
+ * WARNING:  If you didn't specify kwsysProcess_Option_CreateProcessGroup,
+ * you will interrupt your own process group.
+ */
+kwsysEXPORT void kwsysProcess_Interrupt(kwsysProcess* cp);
+
+/**
  * Forcefully terminate the child process that is currently running.
  * The caller should call WaitForExit after this returns to wait for
  * the child to terminate.
@@ -394,6 +417,7 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
 #  undef kwsysProcess_Option_HideWindow
 #  undef kwsysProcess_Option_MergeOutput
 #  undef kwsysProcess_Option_Verbatim
+#  undef kwsysProcess_Option_CreateProcessGroup
 #  undef kwsysProcess_GetOption
 #  undef kwsysProcess_SetOption
 #  undef kwsysProcess_Option_e
@@ -430,6 +454,7 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
 #  undef kwsysProcess_Pipe_Timeout
 #  undef kwsysProcess_Pipe_Handle
 #  undef kwsysProcess_WaitForExit
+#  undef kwsysProcess_Interrupt
 #  undef kwsysProcess_Kill
 # endif
 #endif
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 0393a6d..6d9b109 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -88,7 +88,7 @@ typedef ssize_t kwsysProcess_ssize_t;
 typedef int kwsysProcess_ssize_t;
 #endif
 
-#if defined(__BEOS__) && !defined(__ZETA__) 
+#if defined(__BEOS__) && !defined(__ZETA__)
 /* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */
 # include <be/kernel/OS.h>
 static inline void kwsysProcess_usleep(unsigned int msec)
@@ -151,6 +151,7 @@ typedef struct kwsysProcessCreateInformation_s
 } kwsysProcessCreateInformation;
 
 /*--------------------------------------------------------------------------*/
+static void kwsysProcessVolatileFree(volatile void* p);
 static int kwsysProcessInitialize(kwsysProcess* cp);
 static void kwsysProcessCleanup(kwsysProcess* cp, int error);
 static void kwsysProcessCleanupDescriptor(int* pfd);
@@ -197,7 +198,7 @@ struct kwsysProcess_s
 {
   /* The command lines to execute.  */
   char*** Commands;
-  int NumberOfCommands;
+  volatile int NumberOfCommands;
 
   /* Descriptors for the read ends of the child's output pipes and
      the signal pipe. */
@@ -213,8 +214,10 @@ struct kwsysProcess_s
   /* Buffer for pipe data.  */
   char PipeBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
 
-  /* Process IDs returned by the calls to fork.  */
-  pid_t* ForkPIDs;
+  /* Process IDs returned by the calls to fork.  Everything is volatile
+     because the signal handler accesses them.  You must be very careful
+     when reaping PIDs or modifying this array to avoid race conditions.  */
+  volatile pid_t* volatile ForkPIDs;
 
   /* Flag for whether the children were terminated by a faild select.  */
   int SelectError;
@@ -237,6 +240,9 @@ struct kwsysProcess_s
   /* Whether to merge stdout/stderr of the child.  */
   int MergeOutput;
 
+  /* Whether to create the process in a new process group.  */
+  volatile sig_atomic_t CreateProcessGroup;
+
   /* Time at which the child started.  Negative for no timeout.  */
   kwsysProcessTime StartTime;
 
@@ -257,8 +263,9 @@ struct kwsysProcess_s
   /* The number of children still executing.  */
   int CommandsLeft;
 
-  /* The current status of the child process. */
-  int State;
+  /* The current status of the child process.  Must be atomic because
+     the signal handler checks this to avoid a race.  */
+  volatile sig_atomic_t State;
 
   /* The exceptional behavior that terminated the child process, if
    * any.  */
@@ -271,7 +278,7 @@ struct kwsysProcess_s
   int ExitValue;
 
   /* Whether the process was killed.  */
-  int Killed;
+  volatile sig_atomic_t Killed;
 
   /* Buffer for error message in case of failure.  */
   char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
@@ -649,6 +656,8 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
     case kwsysProcess_Option_Detach: return cp->OptionDetach;
     case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
     case kwsysProcess_Option_Verbatim: return cp->Verbatim;
+    case kwsysProcess_Option_CreateProcessGroup:
+      return cp->CreateProcessGroup;
     default: return 0;
     }
 }
@@ -666,6 +675,8 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
     case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
     case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
     case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
+    case kwsysProcess_Option_CreateProcessGroup:
+      cp->CreateProcessGroup = value; break;
     default: break;
     }
 }
@@ -1490,6 +1501,45 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
 }
 
 /*--------------------------------------------------------------------------*/
+void kwsysProcess_Interrupt(kwsysProcess* cp)
+{
+  int i;
+  /* Make sure we are executing a process.  */
+  if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
+     cp->Killed)
+    {
+    return;
+    }
+
+  /* Interrupt the children.  */
+  if (cp->CreateProcessGroup)
+    {
+    if(cp->ForkPIDs)
+      {
+      for(i=0; i < cp->NumberOfCommands; ++i)
+        {
+        /* Make sure the PID is still valid. */
+        if(cp->ForkPIDs[i])
+          {
+          /* The user created a process group for this process.  The group ID
+             is the process ID for the original process in the group.  */
+          kill(-cp->ForkPIDs[i], SIGINT);
+          }
+        }
+      }
+    }
+  else
+    {
+    /* No process group was created.  Kill our own process group.
+       NOTE:  While one could argue that we could call kill(cp->ForkPIDs[i],
+       SIGINT) as a way to still interrupt the process even though it's not in
+       a special group, this is not an option on Windows.  Therefore, we kill
+       the current process group for consistency with Windows.  */
+    kill(0, SIGINT);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
 void kwsysProcess_Kill(kwsysProcess* cp)
 {
   int i;
@@ -1539,10 +1589,28 @@ void kwsysProcess_Kill(kwsysProcess* cp)
 }
 
 /*--------------------------------------------------------------------------*/
+/* Call the free() function with a pointer to volatile without causing
+   compiler warnings.  */
+static void kwsysProcessVolatileFree(volatile void* p)
+{
+  /* clang has made it impossible to free memory that points to volatile
+     without first using special pragmas to disable a warning...  */
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wcast-qual"
+#endif
+  free((void*)p); /* The cast will silence most compilers, but not clang.  */
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
 /* Initialize a process control structure for kwsysProcess_Execute.  */
 static int kwsysProcessInitialize(kwsysProcess* cp)
 {
   int i;
+  volatile pid_t* oldForkPIDs;
   for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
     {
     cp->PipeReadEnds[i] = -1;
@@ -1571,16 +1639,21 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
   cp->ErrorMessage[0] = 0;
   strcpy(cp->ExitExceptionString, "No exception");
 
-  if(cp->ForkPIDs)
+  oldForkPIDs = cp->ForkPIDs;
+  cp->ForkPIDs = (volatile pid_t*)malloc(
+    sizeof(volatile pid_t)*(size_t)(cp->NumberOfCommands));
+  if(oldForkPIDs)
     {
-    free(cp->ForkPIDs);
+    kwsysProcessVolatileFree(oldForkPIDs);
     }
-  cp->ForkPIDs = (pid_t*)malloc(sizeof(pid_t)*(size_t)(cp->NumberOfCommands));
   if(!cp->ForkPIDs)
     {
     return 0;
     }
-  memset(cp->ForkPIDs, 0, sizeof(pid_t)*(size_t)(cp->NumberOfCommands));
+  for(i=0; i < cp->NumberOfCommands; ++i)
+    {
+    cp->ForkPIDs[i] = 0; /* can't use memset due to volatile */
+    }
 
   if(cp->CommandExitCodes)
     {
@@ -1671,7 +1744,7 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error)
   /* Free memory.  */
   if(cp->ForkPIDs)
     {
-    free(cp->ForkPIDs);
+    kwsysProcessVolatileFree(cp->ForkPIDs);
     cp->ForkPIDs = 0;
     }
   if(cp->RealWorkingDirectory)
@@ -1758,15 +1831,49 @@ int decc$set_child_standard_streams(int fd1, int fd2, int fd3);
 static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
                               kwsysProcessCreateInformation* si)
 {
+  sigset_t mask, old_mask;
+  int pgidPipe[2];
+  char tmp;
+  ssize_t readRes;
+
   /* Create the error reporting pipe.  */
   if(pipe(si->ErrorPipe) < 0)
     {
     return 0;
     }
 
-  /* Set close-on-exec flag on the error pipe's write end.  */
-  if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0)
+  /* Create a pipe for detecting that the child process has created a process
+     group and session.  */
+  if(pipe(pgidPipe) < 0)
     {
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+    return 0;
+    }
+
+  /* Set close-on-exec flag on the pipe's write end.  */
+  if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0 ||
+     fcntl(pgidPipe[1], F_SETFD, FD_CLOEXEC) < 0)
+    {
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+    kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+    kwsysProcessCleanupDescriptor(&pgidPipe[1]);
+    return 0;
+    }
+
+  /* Block SIGINT / SIGTERM while we start.  The purpose is so that our signal
+     handler doesn't get called from the child process after the fork and
+     before the exec, and subsequently start kill()'ing PIDs from ForkPIDs. */
+  sigemptyset(&mask);
+  sigaddset(&mask, SIGINT);
+  sigaddset(&mask, SIGTERM);
+  if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
+    {
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+    kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+    kwsysProcessCleanupDescriptor(&pgidPipe[1]);
     return 0;
     }
 
@@ -1774,13 +1881,19 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
 #if defined(__VMS)
   /* VMS needs vfork and execvp to be in the same function because
      they use setjmp/longjmp to run the child startup code in the
-     parent!  TODO: OptionDetach.  */
+     parent!  TODO: OptionDetach.  Also
+     TODO:  CreateProcessGroup.  */
   cp->ForkPIDs[prIndex] = vfork();
 #else
   cp->ForkPIDs[prIndex] = kwsysProcessFork(cp, si);
 #endif
   if(cp->ForkPIDs[prIndex] < 0)
     {
+    sigprocmask(SIG_SETMASK, &old_mask, 0);
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+    kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+    kwsysProcessCleanupDescriptor(&pgidPipe[1]);
     return 0;
     }
 
@@ -1790,8 +1903,10 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
     /* Specify standard pipes for child process.  */
     decc$set_child_standard_streams(si->StdIn, si->StdOut, si->StdErr);
 #else
-    /* Close the read end of the error reporting pipe.  */
+    /* Close the read end of the error reporting / process group
+       setup pipe.  */
     close(si->ErrorPipe[0]);
+    close(pgidPipe[0]);
 
     /* Setup the stdin, stdout, and stderr pipes.  */
     if(si->StdIn > 0)
@@ -1819,11 +1934,25 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
 
     /* Restore all default signal handlers. */
     kwsysProcessRestoreDefaultSignalHandlers();
+
+    /* Now that we have restored default signal handling and created the
+       process group, restore mask.  */
+    sigprocmask(SIG_SETMASK, &old_mask, 0);
+
+    /* Create new process group.  We use setsid instead of setpgid to avoid
+       the child getting hung up on signals like SIGTTOU.  (In the real world,
+       this has been observed where "git svn" ends up calling the "resize"
+       program which opens /dev/tty.  */
+    if(cp->CreateProcessGroup && setsid() < 0)
+      {
+      kwsysProcessChildErrorExit(si->ErrorPipe[1]);
+      }
 #endif
 
     /* Execute the real process.  If successful, this does not return.  */
     execvp(cp->Commands[prIndex][0], cp->Commands[prIndex]);
     /* TODO: What does VMS do if the child fails to start?  */
+    /* TODO: On VMS, how do we put the process in a new group?  */
 
     /* Failure.  Report error to parent and terminate.  */
     kwsysProcessChildErrorExit(si->ErrorPipe[1]);
@@ -1834,12 +1963,34 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
   decc$set_child_standard_streams(0, 1, 2);
 #endif
 
+  /* We are done with the error reporting pipe and process group setup pipe
+     write end.  */
+  kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+  kwsysProcessCleanupDescriptor(&pgidPipe[1]);
+
+  /* Make sure the child is in the process group before we proceed.  This
+     avoids race conditions with calls to the kill function that we make for
+     signalling process groups.  */
+  while((readRes = read(pgidPipe[0], &tmp, 1)) > 0);
+  if(readRes < 0)
+    {
+    sigprocmask(SIG_SETMASK, &old_mask, 0);
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+    kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+    return 0;
+    }
+  kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+
+  /* Unmask signals.  */
+  if(sigprocmask(SIG_SETMASK, &old_mask, 0) < 0)
+    {
+    kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+    return 0;
+    }
+
   /* A child has been created.  */
   ++cp->CommandsLeft;
 
-  /* We are done with the error reporting pipe write end.  */
-  kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
-
   /* Block until the child's exec call succeeds and closes the error
      pipe or writes data to the pipe to report an error.  */
   {
@@ -1877,6 +2028,17 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
   /* A child process has terminated.  Reap it if it is one handled by
      this object.  */
   int i;
+  /* Temporarily disable signals that access ForkPIDs.  We don't want them to
+     read a reaped PID, and writes to ForkPIDs are not atomic.  */
+  sigset_t mask, old_mask;
+  sigemptyset(&mask);
+  sigaddset(&mask, SIGINT);
+  sigaddset(&mask, SIGTERM);
+  if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
+    {
+    return;
+    }
+
   for(i=0; i < cp->NumberOfCommands; ++i)
     {
     if(cp->ForkPIDs[i])
@@ -1910,6 +2072,9 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
         }
       }
     }
+
+  /* Re-enable signals.  */
+  sigprocmask(SIG_SETMASK, &old_mask, 0);
 }
 
 /*--------------------------------------------------------------------------*/
@@ -1938,7 +2103,7 @@ static int kwsysProcessSetupOutputPipeFile(int* p, const char* name)
 
   /* Assign the replacement descriptor.  */
   *p = fout;
-  return 1;  
+  return 1;
 }
 
 /*--------------------------------------------------------------------------*/
@@ -2582,19 +2747,23 @@ typedef struct kwsysProcessInstances_s
 } kwsysProcessInstances;
 static kwsysProcessInstances kwsysProcesses;
 
-/* The old SIGCHLD handler.  */
+/* The old SIGCHLD / SIGINT / SIGTERM handlers.  */
 static struct sigaction kwsysProcessesOldSigChldAction;
+static struct sigaction kwsysProcessesOldSigIntAction;
+static struct sigaction kwsysProcessesOldSigTermAction;
 
 /*--------------------------------------------------------------------------*/
 static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses)
 {
-  /* Block SIGCHLD while we update the set of pipes to check.
+  /* Block signals while we update the set of pipes to check.
      TODO: sigprocmask is undefined for threaded apps.  See
      pthread_sigmask.  */
   sigset_t newset;
   sigset_t oldset;
   sigemptyset(&newset);
   sigaddset(&newset, SIGCHLD);
+  sigaddset(&newset, SIGINT);
+  sigaddset(&newset, SIGTERM);
   sigprocmask(SIG_BLOCK, &newset, &oldset);
 
   /* Store the new set in that seen by the signal handler.  */
@@ -2686,21 +2855,36 @@ static int kwsysProcessesAdd(kwsysProcess* cp)
     {
     /* Install our handler for SIGCHLD.  Repeat call until it is not
        interrupted.  */
-    struct sigaction newSigChldAction;
-    memset(&newSigChldAction, 0, sizeof(struct sigaction));
+    struct sigaction newSigAction;
+    memset(&newSigAction, 0, sizeof(struct sigaction));
 #if KWSYSPE_USE_SIGINFO
-    newSigChldAction.sa_sigaction = kwsysProcessesSignalHandler;
-    newSigChldAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
+    newSigAction.sa_sigaction = kwsysProcessesSignalHandler;
+    newSigAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
 # ifdef SA_RESTART
-    newSigChldAction.sa_flags |= SA_RESTART;
+    newSigAction.sa_flags |= SA_RESTART;
 # endif
 #else
-    newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
-    newSigChldAction.sa_flags = SA_NOCLDSTOP;
+    newSigAction.sa_handler = kwsysProcessesSignalHandler;
+    newSigAction.sa_flags = SA_NOCLDSTOP;
 #endif
-    while((sigaction(SIGCHLD, &newSigChldAction,
+    sigemptyset(&newSigAction.sa_mask);
+    while((sigaction(SIGCHLD, &newSigAction,
                      &kwsysProcessesOldSigChldAction) < 0) &&
           (errno == EINTR));
+
+    /* Install our handler for SIGINT / SIGTERM.  Repeat call until
+       it is not interrupted.  */
+    sigemptyset(&newSigAction.sa_mask);
+    sigaddset(&newSigAction.sa_mask, SIGTERM);
+    while((sigaction(SIGINT, &newSigAction,
+                     &kwsysProcessesOldSigIntAction) < 0) &&
+          (errno == EINTR));
+
+    sigemptyset(&newSigAction.sa_mask);
+    sigaddset(&newSigAction.sa_mask, SIGINT);
+    while((sigaction(SIGTERM, &newSigAction,
+                     &kwsysProcessesOldSigIntAction) < 0) &&
+          (errno == EINTR));
     }
   }
 
@@ -2734,10 +2918,14 @@ static void kwsysProcessesRemove(kwsysProcess* cp)
     /* If this was the last process, disable the signal handler.  */
     if(newProcesses.Count == 0)
       {
-      /* Restore the SIGCHLD handler.  Repeat call until it is not
+      /* Restore the signal handlers.  Repeat call until it is not
          interrupted.  */
       while((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
             (errno == EINTR));
+      while((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) &&
+            (errno == EINTR));
+      while((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) &&
+            (errno == EINTR));
 
       /* Free the table of process pointers since it is now empty.
          This is safe because the signal handler has been removed.  */
@@ -2763,39 +2951,108 @@ static void kwsysProcessesSignalHandler(int signum
 #endif
   )
 {
-  (void)signum;
+  int i, j, procStatus, old_errno = errno;
 #if KWSYSPE_USE_SIGINFO
   (void)info;
   (void)ucontext;
 #endif
 
   /* Signal all process objects that a child has terminated.  */
-  {
-  int i;
-  for(i=0; i < kwsysProcesses.Count; ++i)
+  switch(signum)
     {
-    /* Set the pipe in a signalled state.  */
-    char buf = 1;
-    kwsysProcess* cp = kwsysProcesses.Processes[i];
-    kwsysProcess_ssize_t status=
-      read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
-    (void)status;
-    status=write(cp->SignalPipe, &buf, 1);
-    (void)status;
+    case SIGCHLD:
+      for(i=0; i < kwsysProcesses.Count; ++i)
+        {
+        /* Set the pipe in a signalled state.  */
+        char buf = 1;
+        kwsysProcess* cp = kwsysProcesses.Processes[i];
+        kwsysProcess_ssize_t pipeStatus=
+          read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
+        (void)pipeStatus;
+        pipeStatus=write(cp->SignalPipe, &buf, 1);
+        (void)pipeStatus;
+        }
+      break;
+    case SIGINT:
+    case SIGTERM:
+      /* Signal child processes that are running in new process groups.  */
+      for(i=0; i < kwsysProcesses.Count; ++i)
+        {
+        kwsysProcess* cp = kwsysProcesses.Processes[i];
+        /* Check Killed to avoid data race condition when killing.
+           Check State to avoid data race condition in kwsysProcessCleanup
+           when there is an error (it leaves a reaped PID).  */
+        if(cp->CreateProcessGroup && !cp->Killed &&
+           cp->State != kwsysProcess_State_Error && cp->ForkPIDs)
+          {
+          for(j=0; j < cp->NumberOfCommands; ++j)
+            {
+            /* Make sure the PID is still valid. */
+            if(cp->ForkPIDs[j])
+              {
+              /* The user created a process group for this process.  The group ID
+                 is the process ID for the original process in the group.  */
+              kill(-cp->ForkPIDs[j], SIGINT);
+              }
+            }
+          }
+        }
+
+      /* Wait for all processes to terminate.  */
+      while(wait(&procStatus) >= 0 || errno != ECHILD)
+        {
+        }
+
+      /* Terminate the process, which is now in an inconsistent state
+         because we reaped all the PIDs that it may have been reaping
+         or may have reaped in the future.  Reraise the signal so that
+         the proper exit code is returned.  */
+      {
+      /* Install default signal handler.  */
+      struct sigaction defSigAction;
+      sigset_t unblockSet;
+      memset(&defSigAction, 0, sizeof(defSigAction));
+      defSigAction.sa_handler = SIG_DFL;
+      sigemptyset(&defSigAction.sa_mask);
+      while((sigaction(signum, &defSigAction, 0) < 0) &&
+            (errno == EINTR));
+      /* Unmask the signal.  */
+      sigemptyset(&unblockSet);
+      sigaddset(&unblockSet, signum);
+      sigprocmask(SIG_UNBLOCK, &unblockSet, 0);
+      /* Raise the signal again.  */
+      raise(signum);
+      /* We shouldn't get here... but if we do... */
+      _exit(1);
+      }
+      /* break omitted to silence unreachable code clang compiler warning.  */
     }
-  }
 
 #if !KWSYSPE_USE_SIGINFO
-  /* Re-Install our handler for SIGCHLD.  Repeat call until it is not
-     interrupted.  */
+  /* Re-Install our handler.  Repeat call until it is not interrupted.  */
   {
-  struct sigaction newSigChldAction;
-  memset(&newSigChldAction, 0, sizeof(struct sigaction));
+  struct sigaction newSigAction;
+  struct sigaction &oldSigAction;
+  memset(&newSigAction, 0, sizeof(struct sigaction));
   newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
   newSigChldAction.sa_flags = SA_NOCLDSTOP;
-  while((sigaction(SIGCHLD, &newSigChldAction,
-                   &kwsysProcessesOldSigChldAction) < 0) &&
+  sigemptyset(&newSigAction.sa_mask);
+  switch(signum)
+    {
+    case SIGCHLD: oldSigAction = &kwsysProcessesOldSigChldAction; break;
+    case SIGINT:
+      sigaddset(&newSigAction.sa_mask, SIGTERM);
+      oldSigAction = &kwsysProcessesOldSigIntAction; break;
+    case SIGTERM:
+      sigaddset(&newSigAction.sa_mask, SIGINT);
+      oldSigAction = &kwsysProcessesOldSigTermAction; break;
+    default: return 0;
+    }
+  while((sigaction(signum, &newSigAction,
+                   oldSigAction) < 0) &&
         (errno == EINTR));
   }
 #endif
+
+  errno = old_errno;
 }
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index f630171..1f8749f 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -11,14 +11,12 @@
 ============================================================================*/
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(Process.h)
-#include KWSYS_HEADER(System.h)
 #include KWSYS_HEADER(Encoding.h)
 
 /* Work-around CMake dependency scanning limitation.  This must
    duplicate the above list of headers.  */
 #if 0
 # include "Process.h.in"
-# include "System.h.in"
 # include "Encoding_c.h.in"
 #endif
 
@@ -111,20 +109,16 @@ static DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd);
 static void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp,
                                            kwsysProcessPipeData* td);
 static int kwsysProcessInitialize(kwsysProcess* cp);
-static int kwsysProcessCreate(kwsysProcess* cp, int index,
-                              kwsysProcessCreateInformation* si);
+static DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
+                                kwsysProcessCreateInformation* si);
 static void kwsysProcessDestroy(kwsysProcess* cp, int event);
-static int kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name);
+static DWORD kwsysProcessSetupOutputPipeFile(PHANDLE handle,
+                                             const char* name);
 static void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
 static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle);
 static void kwsysProcessCleanupHandle(PHANDLE h);
-static void kwsysProcessCleanup(kwsysProcess* cp, int error);
+static void kwsysProcessCleanup(kwsysProcess* cp, DWORD error);
 static void kwsysProcessCleanErrorMessage(kwsysProcess* cp);
-static int kwsysProcessComputeCommandLength(kwsysProcess* cp,
-                                            char const* const* command);
-static void kwsysProcessComputeCommandLine(kwsysProcess* cp,
-                                           char const* const* command,
-                                           char* cmd);
 static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
                                       kwsysProcessTime* timeoutTime);
 static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
@@ -140,6 +134,13 @@ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProc
 static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
 static void kwsysProcessKillTree(int pid);
 static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
+static int kwsysProcessesInitialize(void);
+static int kwsysTryEnterCreateProcessSection(void);
+static void kwsysLeaveCreateProcessSection(void);
+static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessId,
+                             int newProcessGroup);
+static void kwsysProcessesRemove(HANDLE hProcess);
+static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType);
 
 /*--------------------------------------------------------------------------*/
 /* A structure containing synchronization data for each thread.  */
@@ -229,6 +230,9 @@ struct kwsysProcess_s
   /* Whether to merge stdout/stderr of the child.  */
   int MergeOutput;
 
+  /* Whether to create the process in a new process group.  */
+  int CreateProcessGroup;
+
   /* Mutex to protect the shared index used by threads to report data.  */
   HANDLE SharedIndexMutex;
 
@@ -328,6 +332,16 @@ kwsysProcess* kwsysProcess_New(void)
   /* Windows version number data.  */
   OSVERSIONINFO osv;
 
+  /* Initialize list of processes before we get any farther.  It's especially
+     important that the console Ctrl handler be added BEFORE starting the
+     first process.  This prevents the risk of an orphaned process being
+     started by the main thread while the default Ctrl handler is in
+     progress.  */
+  if(!kwsysProcessesInitialize())
+    {
+    return 0;
+    }
+
   /* Allocate a process control structure.  */
   cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
   if(!cp)
@@ -602,37 +616,69 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
     }
   }
 
-  /* We need to construct a single string representing the command
-     and its arguments.  We will surround each argument containing
-     spaces with double-quotes.  Inside a double-quoted argument, we
-     need to escape double-quotes and all backslashes before them.
-     We also need to escape backslashes at the end of an argument
-     because they come before the closing double-quote for the
-     argument.  */
-  {
-  /* First determine the length of the final string.  */
-  int length = kwsysProcessComputeCommandLength(cp, command);
-
-  /* Allocate enough space for the command.  We do not need an extra
-     byte for the terminating null because we allocated a space for
-     the first argument that we will not use.  */
-  char* new_cmd = malloc(length);
-  if(!new_cmd)
+  if (cp->Verbatim)
     {
-    /* Out of memory.  */
+    /* Copy the verbatim command line into the buffer.  */
+    newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(*command);
+    }
+  else
+    {
+    /* Encode the arguments so CommandLineToArgvW can decode
+       them from the command line string in the child.  */
+    char buffer[32768]; /* CreateProcess max command-line length.  */
+    char* end = buffer + sizeof(buffer);
+    char* out = buffer;
+    char const* const* a;
+    for (a = command; *a; ++a)
+      {
+      int quote = !**a; /* Quote the empty string.  */
+      int slashes = 0;
+      char const* c;
+      if (a != command && out != end) { *out++ = ' '; }
+      for (c = *a; !quote && *c; ++c)
+        { quote = (*c == ' ' || *c == '\t'); }
+      if (quote && out != end) { *out++ = '"'; }
+      for (c = *a; *c; ++c)
+        {
+        if (*c == '\\')
+          {
+          ++slashes;
+          }
+        else
+          {
+          if (*c == '"')
+            {
+            // Add n+1 backslashes to total 2n+1 before internal '"'.
+            while(slashes-- >= 0 && out != end) { *out++ = '\\'; }
+            }
+          slashes = 0;
+          }
+        if (out != end) { *out++ = *c; }
+        }
+      if (quote)
+        {
+        // Add n backslashes to total 2n before ending '"'.
+        while (slashes-- > 0 && out != end) { *out++ = '\\'; }
+        if (out != end) { *out++ = '"'; }
+        }
+      }
+    if(out != end)
+      {
+      *out = '\0';
+      newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(buffer);
+      }
+    else
+      {
+      newCommands[cp->NumberOfCommands] = 0;
+      }
+    }
+  if (!newCommands[cp->NumberOfCommands])
+    {
+    /* Out of memory or command line too long.  */
     free(newCommands);
     return 0;
     }
 
-  /* Construct the command line in the allocated buffer.  */
-  kwsysProcessComputeCommandLine(cp, command,
-                                 new_cmd);
-
-  newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(new_cmd);
-  free(new_cmd);
-  }
-
-
   /* Save the new array of commands.  */
   free(cp->Commands);
   cp->Commands = newCommands;
@@ -811,6 +857,8 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
     case kwsysProcess_Option_HideWindow: return cp->HideWindow;
     case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
     case kwsysProcess_Option_Verbatim: return cp->Verbatim;
+    case kwsysProcess_Option_CreateProcessGroup:
+      return cp->CreateProcessGroup;
     default: return 0;
     }
 }
@@ -829,6 +877,8 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
     case kwsysProcess_Option_HideWindow: cp->HideWindow = value; break;
     case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
     case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
+    case kwsysProcess_Option_CreateProcessGroup:
+      cp->CreateProcessGroup = value; break;
     default: break;
     }
 }
@@ -920,7 +970,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
     if(!GetCurrentDirectoryW(cp->RealWorkingDirectoryLength,
                             cp->RealWorkingDirectory))
       {
-      kwsysProcessCleanup(cp, 1);
+      kwsysProcessCleanup(cp, GetLastError());
       return;
       }
     SetCurrentDirectoryW(cp->WorkingDirectory);
@@ -932,14 +982,16 @@ void kwsysProcess_Execute(kwsysProcess* cp)
     {
     /* Create a handle to read a file for stdin.  */
     wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN);
+    DWORD error;
     cp->PipeChildStd[0] =
       CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE,
                   FILE_SHARE_READ|FILE_SHARE_WRITE,
                   0, OPEN_EXISTING, 0, 0);
+    error = GetLastError(); /* Check now in case free changes this.  */
     free(wstdin);
     if(cp->PipeChildStd[0] == INVALID_HANDLE_VALUE)
       {
-      kwsysProcessCleanup(cp, 1);
+      kwsysProcessCleanup(cp, error);
       return;
       }
     }
@@ -965,17 +1017,18 @@ void kwsysProcess_Execute(kwsysProcess* cp)
   if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDOUT].Read,
                  &cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, 0, 0))
     {
-    kwsysProcessCleanup(cp, 1);
+    kwsysProcessCleanup(cp, GetLastError());
     return;
     }
 
   if(cp->PipeFileSTDOUT)
     {
     /* Use a file for stdout.  */
-    if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
-                                        cp->PipeFileSTDOUT))
+    DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
+                                                  cp->PipeFileSTDOUT);
+    if(error)
       {
-      kwsysProcessCleanup(cp, 1);
+      kwsysProcessCleanup(cp, error);
       return;
       }
     }
@@ -998,7 +1051,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
                         GetCurrentProcess(), &cp->PipeChildStd[1],
                         0, FALSE, DUPLICATE_SAME_ACCESS))
       {
-      kwsysProcessCleanup(cp, 1);
+      kwsysProcessCleanup(cp, GetLastError());
       return;
       }
     }
@@ -1009,17 +1062,18 @@ void kwsysProcess_Execute(kwsysProcess* cp)
   if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
                  &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
     {
-    kwsysProcessCleanup(cp, 1);
+    kwsysProcessCleanup(cp, GetLastError());
     return;
     }
 
   if(cp->PipeFileSTDERR)
     {
     /* Use a file for stderr.  */
-    if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
-                                        cp->PipeFileSTDERR))
+    DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
+                                                  cp->PipeFileSTDERR);
+    if(error)
       {
-      kwsysProcessCleanup(cp, 1);
+      kwsysProcessCleanup(cp, error);
       return;
       }
     }
@@ -1042,7 +1096,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
                         GetCurrentProcess(), &cp->PipeChildStd[2],
                         0, FALSE, DUPLICATE_SAME_ACCESS))
       {
-      kwsysProcessCleanup(cp, 1);
+      kwsysProcessCleanup(cp, GetLastError());
       return;
       }
     }
@@ -1081,11 +1135,12 @@ void kwsysProcess_Execute(kwsysProcess* cp)
       HANDLE p[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
       if (!CreatePipe(&p[0], &p[1], 0, 0))
         {
+        DWORD error = GetLastError();
         if (nextStdInput != cp->PipeChildStd[0])
           {
           kwsysProcessCleanupHandle(&nextStdInput);
           }
-        kwsysProcessCleanup(cp, 1);
+        kwsysProcessCleanup(cp, error);
         return;
         }
       nextStdInput = p[0];
@@ -1094,7 +1149,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
     si.hStdError = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
 
     {
-    int res = kwsysProcessCreate(cp, i, &si);
+    DWORD error = kwsysProcessCreate(cp, i, &si);
 
     /* Close our copies of pipes used between children.  */
     if (si.hStdInput != cp->PipeChildStd[0])
@@ -1109,7 +1164,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
       {
       kwsysProcessCleanupHandle(&si.hStdError);
       }
-    if (res)
+    if (!error)
       {
       cp->ProcessEvents[i+1] = cp->ProcessInformation[i].hProcess;
       }
@@ -1119,7 +1174,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
         {
         kwsysProcessCleanupHandle(&nextStdInput);
         }
-      kwsysProcessCleanup(cp, 1);
+      kwsysProcessCleanup(cp, error);
       return;
       }
     }
@@ -1435,6 +1490,52 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
 }
 
 /*--------------------------------------------------------------------------*/
+void kwsysProcess_Interrupt(kwsysProcess* cp)
+{
+  int i;
+  /* Make sure we are executing a process.  */
+  if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
+     cp->Killed)
+    {
+    KWSYSPE_DEBUG((stderr, "interrupt: child not executing\n"));
+    return;
+    }
+
+  /* Skip actually interrupting the child if it has already terminated.  */
+  if(cp->Terminated)
+    {
+    KWSYSPE_DEBUG((stderr, "interrupt: child already terminated\n"));
+    return;
+    }
+
+  /* Interrupt the children.  */
+  if (cp->CreateProcessGroup)
+    {
+    if(cp->ProcessInformation)
+      {
+      for(i=0; i < cp->NumberOfCommands; ++i)
+        {
+        /* Make sure the process handle isn't closed (e.g. from disowning). */
+        if(cp->ProcessInformation[i].hProcess)
+          {
+          /* The user created a process group for this process.  The group ID
+             is the process ID for the original process in the group.  Note
+             that we have to use Ctrl+Break: Ctrl+C is not allowed for process
+             groups.  */
+          GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
+                                   cp->ProcessInformation[i].dwProcessId);
+          }
+        }
+      }
+    }
+  else
+    {
+    /* No process group was created.  Kill our own process group...  */
+    GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
 void kwsysProcess_Kill(kwsysProcess* cp)
 {
   int i;
@@ -1462,7 +1563,8 @@ void kwsysProcess_Kill(kwsysProcess* cp)
   for(i=0; i < cp->NumberOfCommands; ++i)
     {
     kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
-    // close the handle if we kill it
+    /* Remove from global list of processes and close handles.  */
+    kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
     kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
     kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
     }
@@ -1661,7 +1763,7 @@ int kwsysProcessInitialize(kwsysProcess* cp)
 }
 
 /*--------------------------------------------------------------------------*/
-static int kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
+static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
 {
   DWORD flags;
 
@@ -1672,13 +1774,19 @@ static int kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
     if (flags & HANDLE_FLAG_INHERIT)
       {
       *out = in;
-      return 1;
+      return ERROR_SUCCESS;
       }
 
     /* Create an inherited copy of this handle.  */
-    return DuplicateHandle(GetCurrentProcess(), in,
-                           GetCurrentProcess(), out,
-                           0, TRUE, DUPLICATE_SAME_ACCESS);
+    if (DuplicateHandle(GetCurrentProcess(), in, GetCurrentProcess(), out,
+                        0, TRUE, DUPLICATE_SAME_ACCESS))
+      {
+      return ERROR_SUCCESS;
+      }
+    else
+      {
+      return GetLastError();
+      }
     }
   else
     {
@@ -1694,29 +1802,46 @@ static int kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
                         (GENERIC_WRITE | FILE_READ_ATTRIBUTES)),
                        FILE_SHARE_READ|FILE_SHARE_WRITE,
                        &sa, OPEN_EXISTING, 0, 0);
-    return *out != INVALID_HANDLE_VALUE;
+    return (*out != INVALID_HANDLE_VALUE) ? ERROR_SUCCESS : GetLastError();
     }
-
 }
 
 /*--------------------------------------------------------------------------*/
-int kwsysProcessCreate(kwsysProcess* cp, int index,
-                       kwsysProcessCreateInformation* si)
+DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
+                         kwsysProcessCreateInformation* si)
 {
-  int res =
+  DWORD creationFlags;
+  DWORD error = ERROR_SUCCESS;
 
-    /* Create inherited copies the handles.  */
-    kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput,
-                                  si->hStdInput, 1) &&
-    kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
-                                  si->hStdOutput, 0) &&
-    kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
-                                  si->hStdError, 0) &&
+  /* Check if we are currently exiting.  */
+  if (!kwsysTryEnterCreateProcessSection())
+    {
+    /* The Ctrl handler is currently working on exiting our process.  Rather
+    than return an error code, which could cause incorrect conclusions to be
+    reached by the caller, we simply hang.  (For example, a CMake try_run
+    configure step might cause the project to configure wrong.)  */
+    Sleep(INFINITE);
+    }
+
+  /* Create the child in a suspended state so we can wait until all
+     children have been created before running any one.  */
+  creationFlags = CREATE_SUSPENDED;
+  if (cp->CreateProcessGroup)
+    {
+    creationFlags |= CREATE_NEW_PROCESS_GROUP;
+    }
 
-    /* Create the child in a suspended state so we can wait until all
-       children have been created before running any one.  */
-    CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0,
-                   0, &si->StartupInfo, &cp->ProcessInformation[index]);
+  /* Create inherited copies of the handles.  */
+  (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput,
+                                          si->hStdInput, 1)) ||
+  (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
+                                          si->hStdOutput, 0)) ||
+  (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
+                                          si->hStdError, 0)) ||
+  /* Create the process.  */
+  (!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, creationFlags, 0,
+                  0, &si->StartupInfo, &cp->ProcessInformation[index]) &&
+    (error = GetLastError()));
 
   /* Close the inherited copies of the handles. */
   if (si->StartupInfo.hStdInput != si->hStdInput)
@@ -1732,7 +1857,23 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
     kwsysProcessCleanupHandle(&si->StartupInfo.hStdError);
     }
 
-  return res;
+  /* Add the process to the global list of processes. */
+  if (!error &&
+      !kwsysProcessesAdd(cp->ProcessInformation[index].hProcess,
+      cp->ProcessInformation[index].dwProcessId, cp->CreateProcessGroup))
+    {
+    /* This failed for some reason.  Kill the suspended process. */
+    TerminateProcess(cp->ProcessInformation[index].hProcess, 1);
+    /* And clean up... */
+    kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
+    kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
+    strcpy(cp->ErrorMessage, "kwsysProcessesAdd function failed");
+    error = ERROR_NOT_ENOUGH_MEMORY; /* Most likely reason.  */
+    }
+
+  /* If the console Ctrl handler is waiting for us, this will release it... */
+  kwsysLeaveCreateProcessSection();
+  return error;
 }
 
 /*--------------------------------------------------------------------------*/
@@ -1754,6 +1895,9 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event)
   GetExitCodeProcess(cp->ProcessInformation[index].hProcess,
                      &cp->CommandExitCodes[index]);
 
+  /* Remove from global list of processes.  */
+  kwsysProcessesRemove(cp->ProcessInformation[index].hProcess);
+
   /* Close the process handle for the terminated process.  */
   kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
 
@@ -1788,13 +1932,14 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event)
 }
 
 /*--------------------------------------------------------------------------*/
-int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
+DWORD kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
 {
   HANDLE fout;
   wchar_t* wname;
+  DWORD error;
   if(!name)
     {
-    return 1;
+    return ERROR_INVALID_PARAMETER;
     }
 
   /* Close the existing handle.  */
@@ -1804,15 +1949,16 @@ int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
   wname = kwsysEncoding_DupToWide(name);
   fout = CreateFileW(wname, GENERIC_WRITE, FILE_SHARE_READ, 0,
                     CREATE_ALWAYS, 0, 0);
+  error = GetLastError();
   free(wname);
   if(fout == INVALID_HANDLE_VALUE)
     {
-    return 0;
+    return error;
     }
 
   /* Assign the replacement handle.  */
   *phandle = fout;
-  return 1;
+  return ERROR_SUCCESS;
 }
 
 /*--------------------------------------------------------------------------*/
@@ -1851,7 +1997,7 @@ void kwsysProcessCleanupHandle(PHANDLE h)
 /*--------------------------------------------------------------------------*/
 
 /* Close all handles created by kwsysProcess_Execute.  */
-void kwsysProcessCleanup(kwsysProcess* cp, int error)
+void kwsysProcessCleanup(kwsysProcess* cp, DWORD error)
 {
   int i;
   /* If this is an error case, report the error.  */
@@ -1861,21 +2007,27 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
     if(cp->ErrorMessage[0] == 0)
       {
       /* Format the error message.  */
-      DWORD original = GetLastError();
       wchar_t err_msg[KWSYSPE_PIPE_BUFFER_SIZE];
       DWORD length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
-                                   FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
+                                   FORMAT_MESSAGE_IGNORE_INSERTS, 0, error,
                                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                                    err_msg, KWSYSPE_PIPE_BUFFER_SIZE, 0);
-      WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage,
-                          KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL);
       if(length < 1)
         {
         /* FormatMessage failed.  Use a default message.  */
         _snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
                   "Process execution failed with error 0x%X.  "
                   "FormatMessage failed with error 0x%X",
-                  original, GetLastError());
+                  error, GetLastError());
+        }
+      if(!WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage,
+                              KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL))
+        {
+        /* WideCharToMultiByte failed.  Use a default message.  */
+        _snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
+                  "Process execution failed with error 0x%X.  "
+                  "WideCharToMultiByte failed with error 0x%X",
+                  error, GetLastError());
         }
       }
 
@@ -1898,6 +2050,8 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
         }
       for(i=0; i < cp->NumberOfCommands; ++i)
         {
+        /* Remove from global list of processes and close handles.  */
+        kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
         kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
         kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
         }
@@ -1962,66 +2116,6 @@ void kwsysProcessCleanErrorMessage(kwsysProcess* cp)
 }
 
 /*--------------------------------------------------------------------------*/
-int kwsysProcessComputeCommandLength(kwsysProcess* cp,
-                                     char const* const* command)
-{
-  int length = 0;
-  if(cp->Verbatim)
-    {
-    /* Treat the first argument as a verbatim command line.  Use its
-       length directly and add space for the null-terminator.  */
-    length = (int)strlen(*command)+1;
-    }
-  else
-    {
-    /* Compute the length of the command line when it is converted to
-       a single string.  Space for the null-terminator is allocated by
-       the whitespace character allocated for the first argument that
-       will not be used.  */
-    char const* const* arg;
-    for(arg = command; *arg; ++arg)
-      {
-      /* Add the length of this argument.  It already includes room
-         for a separating space or terminating null.  */
-      length += kwsysSystem_Shell_GetArgumentSizeForWindows(*arg, 0);
-      }
-    }
-
-  return length;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcessComputeCommandLine(kwsysProcess* cp,
-                                    char const* const* command,
-                                    char* cmd)
-{
-  if(cp->Verbatim)
-    {
-    /* Copy the verbatim command line into the buffer.  */
-    strcpy(cmd, *command);
-    }
-  else
-    {
-    /* Construct the command line in the allocated buffer.  */
-    char const* const* arg;
-    for(arg = command; *arg; ++arg)
-      {
-      /* Add the separating space if this is not the first argument.  */
-      if(arg != command)
-        {
-        *cmd++ = ' ';
-        }
-
-      /* Add the current argument.  */
-      cmd = kwsysSystem_Shell_GetArgumentForWindows(*arg, cmd, 0);
-      }
-
-    /* Add the terminating null character to the command line.  */
-    *cmd = 0;
-    }
-}
-
-/*--------------------------------------------------------------------------*/
 /* Get the time at which either the process or user timeout will
    expire.  Returns 1 if the user timeout is first, and 0 otherwise.  */
 int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
@@ -2694,3 +2788,230 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp)
     ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
     }
 }
+
+/*--------------------------------------------------------------------------*/
+/* Global set of executing processes for use by the Ctrl handler.
+   This global instance will be zero-initialized by the compiler.
+
+   Note that the console Ctrl handler runs on a background thread and so
+   everything it does must be thread safe.  Here, we track the hProcess
+   HANDLEs directly instead of kwsysProcess instances, so that we don't have
+   to make kwsysProcess thread safe.  */
+typedef struct kwsysProcessInstance_s
+{
+  HANDLE hProcess;
+  DWORD dwProcessId;
+  int NewProcessGroup; /* Whether the process was created in a new group.  */
+} kwsysProcessInstance;
+
+typedef struct kwsysProcessInstances_s
+{
+  /* Whether we have initialized key fields below, like critical sections.  */
+  int Initialized;
+
+  /* Ctrl handler runs on a different thread, so we must sync access.  */
+  CRITICAL_SECTION Lock;
+
+  int Exiting;
+  size_t Count;
+  size_t Size;
+  kwsysProcessInstance* Processes;
+} kwsysProcessInstances;
+static kwsysProcessInstances kwsysProcesses;
+
+/*--------------------------------------------------------------------------*/
+/* Initialize critial section and set up console Ctrl handler.  You MUST call
+   this before using any other kwsysProcesses* functions below.  */
+static int kwsysProcessesInitialize(void)
+{
+  /* Initialize everything if not done already.  */
+  if(!kwsysProcesses.Initialized)
+    {
+    InitializeCriticalSection(&kwsysProcesses.Lock);
+
+    /* Set up console ctrl handler.  */
+    if(!SetConsoleCtrlHandler(kwsysCtrlHandler, TRUE))
+      {
+      return 0;
+      }
+
+    kwsysProcesses.Initialized = 1;
+    }
+  return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* The Ctrl handler waits on the global list of processes.  To prevent an
+   orphaned process, do not create a new process if the Ctrl handler is
+   already running.  Do so by using this function to check if it is ok to
+   create a process.  */
+static int kwsysTryEnterCreateProcessSection(void)
+{
+  /* Enter main critical section; this means creating a process and the Ctrl
+     handler are mutually exclusive.  */
+  EnterCriticalSection(&kwsysProcesses.Lock);
+  /* Indicate to the caller if they can create a process.  */
+  if(kwsysProcesses.Exiting)
+    {
+    LeaveCriticalSection(&kwsysProcesses.Lock);
+    return 0;
+    }
+  else
+    {
+    return 1;
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Matching function on successful kwsysTryEnterCreateProcessSection return.
+   Make sure you called kwsysProcessesAdd if applicable before calling this.*/
+static void kwsysLeaveCreateProcessSection(void)
+{
+  LeaveCriticalSection(&kwsysProcesses.Lock);
+}
+
+/*--------------------------------------------------------------------------*/
+/* Add new process to global process list.  The Ctrl handler will wait for
+   the process to exit before it returns.  Do not close the process handle
+   until after calling kwsysProcessesRemove.  The newProcessGroup parameter
+   must be set if the process was created with CREATE_NEW_PROCESS_GROUP.  */
+static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessid,
+                             int newProcessGroup)
+{
+  if(!kwsysProcessesInitialize() || !hProcess ||
+      hProcess == INVALID_HANDLE_VALUE)
+    {
+    return 0;
+    }
+
+  /* Enter the critical section. */
+  EnterCriticalSection(&kwsysProcesses.Lock);
+
+  /* Make sure there is enough space for the new process handle.  */
+  if(kwsysProcesses.Count == kwsysProcesses.Size)
+    {
+    size_t newSize;
+    kwsysProcessInstance *newArray;
+    /* Start with enough space for a small number of process handles
+       and double the size each time more is needed.  */
+    newSize = kwsysProcesses.Size? kwsysProcesses.Size*2 : 4;
+
+    /* Try allocating the new block of memory.  */
+    if(newArray = (kwsysProcessInstance*)malloc(
+       newSize*sizeof(kwsysProcessInstance)))
+      {
+      /* Copy the old process handles to the new memory.  */
+      if(kwsysProcesses.Count > 0)
+        {
+        memcpy(newArray, kwsysProcesses.Processes,
+               kwsysProcesses.Count * sizeof(kwsysProcessInstance));
+        }
+      }
+    else
+      {
+      /* Failed to allocate memory for the new process handle set.  */
+      LeaveCriticalSection(&kwsysProcesses.Lock);
+      return 0;
+      }
+
+    /* Free original array. */
+    free(kwsysProcesses.Processes);
+
+    /* Update original structure with new allocation. */
+    kwsysProcesses.Size = newSize;
+    kwsysProcesses.Processes = newArray;
+    }
+
+  /* Append the new process information to the set.  */
+  kwsysProcesses.Processes[kwsysProcesses.Count].hProcess = hProcess;
+  kwsysProcesses.Processes[kwsysProcesses.Count].dwProcessId = dwProcessid;
+  kwsysProcesses.Processes[kwsysProcesses.Count++].NewProcessGroup =
+    newProcessGroup;
+
+  /* Leave critical section and return success. */
+  LeaveCriticalSection(&kwsysProcesses.Lock);
+
+  return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Removes process to global process list.  */
+static void kwsysProcessesRemove(HANDLE hProcess)
+{
+  size_t i;
+
+  if (!hProcess || hProcess == INVALID_HANDLE_VALUE)
+    {
+    return;
+    }
+
+  EnterCriticalSection(&kwsysProcesses.Lock);
+
+  /* Find the given process in the set.  */
+  for(i=0; i < kwsysProcesses.Count; ++i)
+    {
+    if(kwsysProcesses.Processes[i].hProcess == hProcess)
+      {
+      break;
+      }
+    }
+  if(i < kwsysProcesses.Count)
+    {
+    /* Found it!  Remove the process from the set.  */
+    --kwsysProcesses.Count;
+    for(; i < kwsysProcesses.Count; ++i)
+      {
+      kwsysProcesses.Processes[i] = kwsysProcesses.Processes[i+1];
+      }
+
+    /* If this was the last process, free the array.  */
+    if(kwsysProcesses.Count == 0)
+      {
+      kwsysProcesses.Size = 0;
+      free(kwsysProcesses.Processes);
+      kwsysProcesses.Processes = 0;
+      }
+    }
+
+  LeaveCriticalSection(&kwsysProcesses.Lock);
+}
+
+/*--------------------------------------------------------------------------*/
+static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType)
+{
+  size_t i;
+  (void)dwCtrlType;
+  /* Enter critical section.  */
+  EnterCriticalSection(&kwsysProcesses.Lock);
+
+  /* Set flag indicating that we are exiting.  */
+  kwsysProcesses.Exiting = 1;
+
+  /* If some of our processes were created in a new process group, we must
+     manually interrupt them.  They won't otherwise receive a Ctrl+C/Break. */
+  for(i=0; i < kwsysProcesses.Count; ++i)
+    {
+    if(kwsysProcesses.Processes[i].NewProcessGroup)
+      {
+      DWORD groupId = kwsysProcesses.Processes[i].dwProcessId;
+      if(groupId)
+        {
+        GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, groupId);
+        }
+      }
+    }
+
+  /* Wait for each child process to exit.  This is the key step that prevents
+     us from leaving several orphaned children processes running in the
+     background when the user presses Ctrl+C.  */
+  for(i=0; i < kwsysProcesses.Count; ++i)
+    {
+    WaitForSingleObject(kwsysProcesses.Processes[i].hProcess, INFINITE);
+    }
+
+  /* Leave critical section.  */
+  LeaveCriticalSection(&kwsysProcesses.Lock);
+
+  /* Continue on to default Ctrl handler (which calls ExitProcess).  */
+  return FALSE;
+}
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index 502fbe2..d0235d8 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -33,12 +33,7 @@
 #include <@KWSYS_NAMESPACE@/Configure.h>
 #include <@KWSYS_NAMESPACE@/Configure.hxx>
 
-#include <@KWSYS_NAMESPACE@/stl/string>
-
-/* Define this macro temporarily to keep the code readable.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE at _stl
-#endif
+#include <string>
 
 /* Disable useless Borland warnings.  KWSys tries not to force things
    on its includers, but there is no choice here.  */
@@ -207,7 +202,7 @@ public:
   /**
    * Instantiate RegularExpression with compiled string.
    */
-  inline RegularExpression (kwsys_stl::string const&);
+  inline RegularExpression (std::string const&);
 
   /**
    * Destructor.
@@ -224,7 +219,7 @@ public:
    * Compile a regular expression into internal code
    * for later pattern matching.
    */
-  inline bool compile (kwsys_stl::string const&);
+  inline bool compile (std::string const&);
 
   /**
    * Matches the regular expression to the given string.
@@ -236,17 +231,17 @@ public:
    * Matches the regular expression to the given std string.
    * Returns true if found, and sets start and end indexes accordingly.
    */
-  inline bool find (kwsys_stl::string const&);
+  inline bool find (std::string const&);
 
   /**
    * Index to start of first find.
    */
-  inline kwsys_stl::string::size_type start() const;
+  inline std::string::size_type start() const;
 
   /**
    * Index to end of first find.
    */
-  inline kwsys_stl::string::size_type end() const;
+  inline std::string::size_type end() const;
 
   /**
    * Copy the given regular expression.
@@ -285,9 +280,9 @@ public:
    * Destructor.
    */
   // awf added
-  kwsys_stl::string::size_type start(int n) const;
-  kwsys_stl::string::size_type end(int n) const;
-  kwsys_stl::string match(int n) const;
+  std::string::size_type start(int n) const;
+  std::string::size_type end(int n) const;
+  std::string match(int n) const;
   
   enum { NSUBEXP = 10 };
 private: 
@@ -296,7 +291,7 @@ private:
   char  regstart;                       // Internal use only
   char  reganch;                        // Internal use only
   const char* regmust;                  // Internal use only
-  kwsys_stl::string::size_type regmlen;                // Internal use only
+  std::string::size_type regmlen;                // Internal use only
   char* program;   
   int   progsize;
   const char* searchstring;
@@ -327,7 +322,7 @@ inline RegularExpression::RegularExpression (const char* s)
  * Creates a regular expression from string s, and
  * compiles s.
  */
-inline RegularExpression::RegularExpression (const kwsys_stl::string& s)
+inline RegularExpression::RegularExpression (const std::string& s)
 {
   this->program = 0;
   this->compile(s);
@@ -347,7 +342,7 @@ inline RegularExpression::~RegularExpression ()
  * Compile a regular expression into internal code
  * for later pattern matching.
  */
-inline bool RegularExpression::compile (kwsys_stl::string const& s)
+inline bool RegularExpression::compile (std::string const& s)
 {
   return this->compile(s.c_str());
 }
@@ -356,7 +351,7 @@ inline bool RegularExpression::compile (kwsys_stl::string const& s)
  * Matches the regular expression to the given std string.
  * Returns true if found, and sets start and end indexes accordingly.
  */
-inline bool RegularExpression::find (kwsys_stl::string const& s)
+inline bool RegularExpression::find (std::string const& s)
 {
   return this->find(s.c_str());
 }
@@ -364,9 +359,9 @@ inline bool RegularExpression::find (kwsys_stl::string const& s)
 /**
  * Set the start position for the regular expression.
  */
-inline kwsys_stl::string::size_type RegularExpression::start () const 
+inline std::string::size_type RegularExpression::start () const
 {
-  return static_cast<kwsys_stl::string::size_type>(
+  return static_cast<std::string::size_type>(
     this->startp[0] - searchstring);
 }
 
@@ -374,9 +369,9 @@ inline kwsys_stl::string::size_type RegularExpression::start () const
 /**
  * Returns the start/end index of the last item found.
  */
-inline kwsys_stl::string::size_type RegularExpression::end () const 
+inline std::string::size_type RegularExpression::end () const
 {
-  return static_cast<kwsys_stl::string::size_type>(
+  return static_cast<std::string::size_type>(
     this->endp[0] - searchstring);
 }
 
@@ -410,9 +405,9 @@ inline void RegularExpression::set_invalid ()
 /**
  * Return start index of nth submatch. start(0) is the start of the full match.
  */
-inline kwsys_stl::string::size_type RegularExpression::start(int n) const
+inline std::string::size_type RegularExpression::start(int n) const
 {
-  return static_cast<kwsys_stl::string::size_type>(
+  return static_cast<std::string::size_type>(
     this->startp[n] - searchstring);
 }
 
@@ -420,34 +415,29 @@ inline kwsys_stl::string::size_type RegularExpression::start(int n) const
 /**
  * Return end index of nth submatch. end(0) is the end of the full match.
  */
-inline kwsys_stl::string::size_type RegularExpression::end(int n) const
+inline std::string::size_type RegularExpression::end(int n) const
 {
-  return static_cast<kwsys_stl::string::size_type>(
+  return static_cast<std::string::size_type>(
     this->endp[n] - searchstring);
 }
 
 /**
  * Return nth submatch as a string.
  */
-inline kwsys_stl::string RegularExpression::match(int n) const
+inline std::string RegularExpression::match(int n) const
 {
   if (this->startp[n]==0)
     {
-    return kwsys_stl::string("");
+    return std::string("");
     }
   else
     {
-    return kwsys_stl::string(this->startp[n],
-                             static_cast<kwsys_stl::string::size_type>(
+    return std::string(this->startp[n],
+                             static_cast<std::string::size_type>(
                                this->endp[n] - this->startp[n]));
     }
 }
 
 } // namespace @KWSYS_NAMESPACE@
 
-/* Undefine temporary macro.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
 #endif
diff --git a/Source/kwsys/String.hxx.in b/Source/kwsys/String.hxx.in
index 4386c9e..2e9aedb 100644
--- a/Source/kwsys/String.hxx.in
+++ b/Source/kwsys/String.hxx.in
@@ -12,7 +12,7 @@
 #ifndef @KWSYS_NAMESPACE at _String_hxx
 #define @KWSYS_NAMESPACE at _String_hxx
 
-#include <@KWSYS_NAMESPACE@/stl/string>
+#include <string>
 
 namespace @KWSYS_NAMESPACE@
 {
@@ -25,10 +25,10 @@ namespace @KWSYS_NAMESPACE@
  * simply a subclass of this type with the same interface so that the
  * name is shorter in debugging symbols and error messages.
  */
-class String: public @KWSYS_NAMESPACE at _stl::string
+class String: public std::string
 {
   /** The original string type.  */
-  typedef @KWSYS_NAMESPACE at _stl::string stl_string;
+  typedef std::string stl_string;
 
 public:
 
@@ -55,8 +55,8 @@ public:
 #if defined(__WATCOMC__)
 inline bool operator<(String const& l, String const& r)
   {
-  return (static_cast<@KWSYS_NAMESPACE at _stl::string const&>(l) <
-          static_cast<@KWSYS_NAMESPACE at _stl::string const&>(r));
+  return (static_cast<std::string const&>(l) <
+          static_cast<std::string const&>(r));
   }
 #endif
 
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c
index 1ee26fa..ccc7e81 100644
--- a/Source/kwsys/System.c
+++ b/Source/kwsys/System.c
@@ -20,8 +20,8 @@
 
 #include <stddef.h> /* ptrdiff_t */
 #include <stdlib.h> /* malloc, free */
-#include <string.h> /* strlen */
-#include <ctype.h>  /* isalpha */
+#include <string.h> /* memcpy */
+#include <ctype.h>  /* isspace */
 
 #include <stdio.h>
 
@@ -31,587 +31,6 @@ typedef ptrdiff_t kwsysSystem_ptrdiff_t;
 typedef int kwsysSystem_ptrdiff_t;
 #endif
 
-/*
-
-Notes:
-
-Make variable replacements open a can of worms.  Sometimes they should
-be quoted and sometimes not.  Sometimes their replacement values are
-already quoted.
-
-VS variables cause problems.  In order to pass the referenced value
-with spaces the reference must be quoted.  If the variable value ends
-in a backslash then it will escape the ending quote!  In order to make
-the ending backslash appear we need this:
-
-  "$(InputDir)\"
-
-However if there is not a trailing backslash then this will put a
-quote in the value so we need:
-
-  "$(InputDir)"
-
-Make variable references are platform specific so we should probably
-just NOT quote them and let the listfile author deal with it.
-
-*/
-
-/*
-TODO: For windows echo:
-
-To display a pipe (|) or redirection character (< or >) when using the
-echo command, use a caret character immediately before the pipe or
-redirection character (for example, ^>, ^<, or ^| ). If you need to
-use the caret character itself (^), use two in a row (^^).
-*/
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharIsWhitespace(char c)
-{
-  return ((c == ' ') || (c == '\t'));
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharNeedsQuotesOnUnix(char c)
-{
-  return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
-          (c == '&') || (c == '$') || (c == '(') || (c == ')') ||
-          (c == '~') || (c == '<') || (c == '>') || (c == '|') ||
-          (c == '*') || (c == '^') || (c == '\\'));
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharNeedsQuotesOnWindows(char c)
-{
-  return ((c == '\'') || (c == '#') || (c == '&') ||
-          (c == '<') || (c == '>') || (c == '|') || (c == '^'));
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharNeedsQuotes(char c, int isUnix, int flags)
-{
-  /* On Windows the built-in command shell echo never needs quotes.  */
-  if(!isUnix && (flags & kwsysSystem_Shell_Flag_EchoWindows))
-    {
-    return 0;
-    }
-
-  /* On all platforms quotes are needed to preserve whitespace.  */
-  if(kwsysSystem_Shell__CharIsWhitespace(c))
-    {
-    return 1;
-    }
-
-  if(isUnix)
-    {
-    /* On UNIX several special characters need quotes to preserve them.  */
-    if(kwsysSystem_Shell__CharNeedsQuotesOnUnix(c))
-      {
-      return 1;
-      }
-    }
-  else
-    {
-    /* On Windows several special characters need quotes to preserve them.  */
-    if(kwsysSystem_Shell__CharNeedsQuotesOnWindows(c))
-      {
-      return 1;
-      }
-    }
-  return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharIsMakeVariableName(char c)
-{
-  return c && (c == '_' || isalpha(((int)c)));
-}
-
-/*--------------------------------------------------------------------------*/
-static const char* kwsysSystem_Shell__SkipMakeVariables(const char* c)
-{
-  while(*c == '$' && *(c+1) == '(')
-    {
-    const char* skip = c+2;
-    while(kwsysSystem_Shell__CharIsMakeVariableName(*skip))
-      {
-      ++skip;
-      }
-    if(*skip == ')')
-      {
-      c = skip+1;
-      }
-    else
-      {
-      break;
-      }
-    }
-  return c;
-}
-
-/*
-Allowing make variable replacements opens a can of worms.  Sometimes
-they should be quoted and sometimes not.  Sometimes their replacement
-values are already quoted or contain escapes.
-
-Some Visual Studio variables cause problems.  In order to pass the
-referenced value with spaces the reference must be quoted.  If the
-variable value ends in a backslash then it will escape the ending
-quote!  In order to make the ending backslash appear we need this:
-
-  "$(InputDir)\"
-
-However if there is not a trailing backslash then this will put a
-quote in the value so we need:
-
-  "$(InputDir)"
-
-This macro decides whether we quote an argument just because it
-contains a make variable reference.  This should be replaced with a
-flag later when we understand applications of this better.
-*/
-#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__ArgumentNeedsQuotes(const char* in, int isUnix,
-                                                  int flags)
-{
-  /* The empty string needs quotes.  */
-  if(!*in)
-    {
-    return 1;
-    }
-
-  /* Scan the string for characters that require quoting.  */
-  {
-  const char* c;
-  for(c=in; *c; ++c)
-    {
-    /* Look for $(MAKEVAR) syntax if requested.  */
-    if(flags & kwsysSystem_Shell_Flag_AllowMakeVariables)
-      {
-#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
-      const char* skip = kwsysSystem_Shell__SkipMakeVariables(c);
-      if(skip != c)
-        {
-        /* We need to quote make variable references to preserve the
-           string with contents substituted in its place.  */
-        return 1;
-        }
-#else
-      /* Skip over the make variable references if any are present.  */
-      c = kwsysSystem_Shell__SkipMakeVariables(c);
-
-      /* Stop if we have reached the end of the string.  */
-      if(!*c)
-        {
-        break;
-        }
-#endif
-      }
-
-    /* Check whether this character needs quotes.  */
-    if(kwsysSystem_Shell__CharNeedsQuotes(*c, isUnix, flags))
-      {
-      return 1;
-      }
-    }
-  }
-
-  /* On Windows some single character arguments need quotes.  */
-  if(!isUnix && *in && !*(in+1))
-    {
-    char c = *in;
-    if((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#'))
-      {
-      return 1;
-      }
-    }
-
-  return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__GetArgumentSize(const char* in,
-                                              int isUnix, int flags)
-{
-  /* Start with the length of the original argument, plus one for
-     either a terminating null or a separating space.  */
-  int size = (int)strlen(in) + 1;
-
-  /* String iterator.  */
-  const char* c;
-
-  /* Keep track of how many backslashes have been encountered in a row.  */
-  int windows_backslashes = 0;
-
-  /* Scan the string for characters that require escaping or quoting.  */
-  for(c=in; *c; ++c)
-    {
-    /* Look for $(MAKEVAR) syntax if requested.  */
-    if(flags & kwsysSystem_Shell_Flag_AllowMakeVariables)
-      {
-      /* Skip over the make variable references if any are present.  */
-      c = kwsysSystem_Shell__SkipMakeVariables(c);
-
-      /* Stop if we have reached the end of the string.  */
-      if(!*c)
-        {
-        break;
-        }
-      }
-
-    /* Check whether this character needs escaping for the shell.  */
-    if(isUnix)
-      {
-      /* On Unix a few special characters need escaping even inside a
-         quoted argument.  */
-      if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
-        {
-        /* This character needs a backslash to escape it.  */
-        ++size;
-        }
-      }
-    else if(flags & kwsysSystem_Shell_Flag_EchoWindows)
-      {
-      /* On Windows the built-in command shell echo never needs escaping.  */
-      }
-    else
-      {
-      /* On Windows only backslashes and double-quotes need escaping.  */
-      if(*c == '\\')
-        {
-        /* Found a backslash.  It may need to be escaped later.  */
-        ++windows_backslashes;
-        }
-      else if(*c == '"')
-        {
-        /* Found a double-quote.  We need to escape it and all
-           immediately preceding backslashes.  */
-        size += windows_backslashes + 1;
-        windows_backslashes = 0;
-        }
-      else
-        {
-        /* Found another character.  This eliminates the possibility
-           that any immediately preceding backslashes will be
-           escaped.  */
-        windows_backslashes = 0;
-        }
-      }
-
-    /* Check whether this character needs escaping for a make tool.  */
-    if(*c == '$')
-      {
-      if(flags & kwsysSystem_Shell_Flag_Make)
-        {
-        /* In Makefiles a dollar is written $$ so we need one extra
-           character.  */
-        ++size;
-        }
-      else if(flags & kwsysSystem_Shell_Flag_VSIDE)
-        {
-        /* In a VS IDE a dollar is written "$" so we need two extra
-           characters.  */
-        size += 2;
-        }
-      }
-    else if(*c == '#')
-      {
-      if((flags & kwsysSystem_Shell_Flag_Make) &&
-         (flags & kwsysSystem_Shell_Flag_WatcomWMake))
-        {
-        /* In Watcom WMake makefiles a pound is written $# so we need
-           one extra character.  */
-        ++size;
-        }
-      }
-    else if(*c == '%')
-      {
-      if((flags & kwsysSystem_Shell_Flag_VSIDE) ||
-         ((flags & kwsysSystem_Shell_Flag_Make) &&
-          ((flags & kwsysSystem_Shell_Flag_MinGWMake) ||
-           (flags & kwsysSystem_Shell_Flag_NMake))))
-        {
-        /* In the VS IDE, NMake, or MinGW make a percent is written %%
-           so we need one extra characters.  */
-        size += 1;
-        }
-      }
-    else if(*c == ';')
-      {
-      if(flags & kwsysSystem_Shell_Flag_VSIDE)
-        {
-        /* In a VS IDE a semicolon is written ";" so we need two extra
-           characters.  */
-        size += 2;
-        }
-      }
-    }
-
-  /* Check whether the argument needs surrounding quotes.  */
-  if(kwsysSystem_Shell__ArgumentNeedsQuotes(in, isUnix, flags))
-    {
-    /* Surrounding quotes are needed.  Allocate space for them.  */
-    if((flags & kwsysSystem_Shell_Flag_WatcomQuote) && (isUnix))
-      {
-        size += 2;
-      }
-    size += 2;
-
-    /* We must escape all ending backslashes when quoting on windows.  */
-    size += windows_backslashes;
-    }
-
-  return size;
-}
-
-/*--------------------------------------------------------------------------*/
-static char* kwsysSystem_Shell__GetArgument(const char* in, char* out,
-                                            int isUnix, int flags)
-{
-  /* String iterator.  */
-  const char* c;
-
-  /* Keep track of how many backslashes have been encountered in a row.  */
-  int windows_backslashes = 0;
-
-  /* Whether the argument must be quoted.  */
-  int needQuotes = kwsysSystem_Shell__ArgumentNeedsQuotes(in, isUnix, flags);
-  if(needQuotes)
-    {
-    /* Add the opening quote for this argument.  */
-    if(flags & kwsysSystem_Shell_Flag_WatcomQuote)
-      {
-      if(isUnix)
-        {
-        *out++ = '"';
-        }
-      *out++ = '\'';
-      }
-    else
-      {
-      *out++ = '"';
-      }
-    }
-
-  /* Scan the string for characters that require escaping or quoting.  */
-  for(c=in; *c; ++c)
-    {
-    /* Look for $(MAKEVAR) syntax if requested.  */
-    if(flags & kwsysSystem_Shell_Flag_AllowMakeVariables)
-      {
-      const char* skip = kwsysSystem_Shell__SkipMakeVariables(c);
-      if(skip != c)
-        {
-        /* Copy to the end of the make variable references.  */
-        while(c != skip)
-          {
-          *out++ = *c++;
-          }
-
-        /* The make variable reference eliminates any escaping needed
-           for preceding backslashes.  */
-        windows_backslashes = 0;
-
-        /* Stop if we have reached the end of the string.  */
-        if(!*c)
-          {
-          break;
-          }
-        }
-      }
-
-    /* Check whether this character needs escaping for the shell.  */
-    if(isUnix)
-      {
-      /* On Unix a few special characters need escaping even inside a
-         quoted argument.  */
-      if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
-        {
-        /* This character needs a backslash to escape it.  */
-        *out++ = '\\';
-        }
-      }
-    else if(flags & kwsysSystem_Shell_Flag_EchoWindows)
-      {
-      /* On Windows the built-in command shell echo never needs escaping.  */
-      }
-    else
-      {
-      /* On Windows only backslashes and double-quotes need escaping.  */
-      if(*c == '\\')
-        {
-        /* Found a backslash.  It may need to be escaped later.  */
-        ++windows_backslashes;
-        }
-      else if(*c == '"')
-        {
-        /* Found a double-quote.  Escape all immediately preceding
-           backslashes.  */
-        while(windows_backslashes > 0)
-          {
-          --windows_backslashes;
-          *out++ = '\\';
-          }
-
-        /* Add the backslash to escape the double-quote.  */
-        *out++ = '\\';
-        }
-      else
-        {
-        /* We encountered a normal character.  This eliminates any
-           escaping needed for preceding backslashes.  */
-        windows_backslashes = 0;
-        }
-      }
-
-    /* Check whether this character needs escaping for a make tool.  */
-    if(*c == '$')
-      {
-      if(flags & kwsysSystem_Shell_Flag_Make)
-        {
-        /* In Makefiles a dollar is written $$.  The make tool will
-           replace it with just $ before passing it to the shell.  */
-        *out++ = '$';
-        *out++ = '$';
-        }
-      else if(flags & kwsysSystem_Shell_Flag_VSIDE)
-        {
-        /* In a VS IDE a dollar is written "$".  If this is written in
-           an un-quoted argument it starts a quoted segment, inserts
-           the $ and ends the segment.  If it is written in a quoted
-           argument it ends quoting, inserts the $ and restarts
-           quoting.  Either way the $ is isolated from surrounding
-           text to avoid looking like a variable reference.  */
-        *out++ = '"';
-        *out++ = '$';
-        *out++ = '"';
-        }
-      else
-        {
-        /* Otherwise a dollar is written just $. */
-        *out++ = '$';
-        }
-      }
-    else if(*c == '#')
-      {
-      if((flags & kwsysSystem_Shell_Flag_Make) &&
-         (flags & kwsysSystem_Shell_Flag_WatcomWMake))
-        {
-        /* In Watcom WMake makefiles a pound is written $#.  The make
-           tool will replace it with just # before passing it to the
-           shell.  */
-        *out++ = '$';
-        *out++ = '#';
-        }
-      else
-        {
-        /* Otherwise a pound is written just #. */
-        *out++ = '#';
-        }
-      }
-    else if(*c == '%')
-      {
-      if((flags & kwsysSystem_Shell_Flag_VSIDE) ||
-         ((flags & kwsysSystem_Shell_Flag_Make) &&
-          ((flags & kwsysSystem_Shell_Flag_MinGWMake) ||
-           (flags & kwsysSystem_Shell_Flag_NMake))))
-        {
-        /* In the VS IDE, NMake, or MinGW make a percent is written %%.  */
-        *out++ = '%';
-        *out++ = '%';
-        }
-      else
-        {
-        /* Otherwise a percent is written just %. */
-        *out++ = '%';
-        }
-      }
-    else if(*c == ';')
-      {
-      if(flags & kwsysSystem_Shell_Flag_VSIDE)
-        {
-        /* In a VS IDE a semicolon is written ";".  If this is written
-           in an un-quoted argument it starts a quoted segment,
-           inserts the ; and ends the segment.  If it is written in a
-           quoted argument it ends quoting, inserts the ; and restarts
-           quoting.  Either way the ; is isolated.  */
-        *out++ = '"';
-        *out++ = ';';
-        *out++ = '"';
-        }
-      else
-        {
-        /* Otherwise a semicolon is written just ;. */
-        *out++ = ';';
-        }
-      }
-    else
-      {
-      /* Store this character.  */
-      *out++ = *c;
-      }
-    }
-
-  if(needQuotes)
-    {
-    /* Add enough backslashes to escape any trailing ones.  */
-    while(windows_backslashes > 0)
-      {
-      --windows_backslashes;
-      *out++ = '\\';
-      }
-
-    /* Add the closing quote for this argument.  */
-    if(flags & kwsysSystem_Shell_Flag_WatcomQuote)
-      {
-      *out++ = '\'';
-      if(isUnix)
-        {
-        *out++ = '"';
-        }
-      }
-    else
-      {
-      *out++ = '"';
-      }
-    }
-
-  /* Store a terminating null without incrementing.  */
-  *out = 0;
-
-  return out;
-}
-
-/*--------------------------------------------------------------------------*/
-char* kwsysSystem_Shell_GetArgumentForWindows(const char* in,
-                                              char* out,
-                                              int flags)
-{
-  return kwsysSystem_Shell__GetArgument(in, out, 0, flags);
-}
-
-/*--------------------------------------------------------------------------*/
-char* kwsysSystem_Shell_GetArgumentForUnix(const char* in,
-                                           char* out,
-                                           int flags)
-{
-  return kwsysSystem_Shell__GetArgument(in, out, 1, flags);
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysSystem_Shell_GetArgumentSizeForWindows(const char* in, int flags)
-{
-  return kwsysSystem_Shell__GetArgumentSize(in, 0, flags);
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysSystem_Shell_GetArgumentSizeForUnix(const char* in, int flags)
-{
-  return kwsysSystem_Shell__GetArgumentSize(in, 1, flags);
-}
-
 /*--------------------------------------------------------------------------*/
 static int kwsysSystem__AppendByte(char* local,
                                    char** begin, char** end,
diff --git a/Source/kwsys/System.h.in b/Source/kwsys/System.h.in
index f21bf0d..3f3d3f4 100644
--- a/Source/kwsys/System.h.in
+++ b/Source/kwsys/System.h.in
@@ -24,28 +24,6 @@
 #endif
 #if !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
 # define kwsysSystem_Parse_CommandForUnix             kwsys_ns(System_Parse_CommandForUnix)
-# define kwsysSystem_Shell_GetArgumentForWindows      kwsys_ns(System_Shell_GetArgumentForWindows)
-# define kwsysSystem_Shell_GetArgumentForUnix         kwsys_ns(System_Shell_GetArgumentForUnix)
-# define kwsysSystem_Shell_GetArgumentSizeForWindows  kwsys_ns(System_Shell_GetArgumentSizeForWindows)
-# define kwsysSystem_Shell_GetArgumentSizeForUnix     kwsys_ns(System_Shell_GetArgumentSizeForUnix)
-# define kwsysSystem_Shell_Flag_e                     kwsys_ns(System_Shell_Flag_e)
-# define kwsysSystem_Shell_Flag_Make                  kwsys_ns(System_Shell_Flag_Make)
-# define kwsysSystem_Shell_Flag_VSIDE                 kwsys_ns(System_Shell_Flag_VSIDE)
-# define kwsysSystem_Shell_Flag_EchoWindows           kwsys_ns(System_Shell_Flag_EchoWindows)
-# define kwsysSystem_Shell_Flag_WatcomWMake           kwsys_ns(System_Shell_Flag_WatcomWMake)
-# define kwsysSystem_Shell_Flag_MinGWMake             kwsys_ns(System_Shell_Flag_MinGWMake)
-# define kwsysSystem_Shell_Flag_NMake                 kwsys_ns(System_Shell_Flag_NMake)
-# define kwsysSystem_Shell_Flag_AllowMakeVariables    kwsys_ns(System_Shell_Flag_AllowMakeVariables)
-# define kwsysSystem_Shell_Flag_WatcomQuote           kwsys_ns(System_Shell_Flag_WatcomQuote)
-#endif
-
-#ifdef __VMS
-#define @KWSYS_NAMESPACE at System_Shell_GetArgumentForUnix \
-   @KWSYS_NAMESPACE at System_Shell_UnixGA
-#define @KWSYS_NAMESPACE at System_Shell_GetArgumentSizeForUnix \
-   @KWSYS_NAMESPACE at System_Shell_UnixGAS
-#define @KWSYS_NAMESPACE at System_Shell_GetArgumentForWindows \
-   @KWSYS_NAMESPACE at System_Shell_WindowsGA
 #endif
 
 #if defined(__cplusplus)
@@ -54,69 +32,6 @@ extern "C"
 #endif
 
 /**
- * Transform the given command line argument for use in a Windows or
- * Unix shell.  Returns a pointer to the end of the command line
- * argument in the provided output buffer.  Flags may be passed to
- * modify the generated quoting and escape sequences to work under
- * alternative environments.
- */
-kwsysEXPORT char* kwsysSystem_Shell_GetArgumentForWindows(const char* in,
-                                                          char* out,
-                                                          int flags);
-kwsysEXPORT char* kwsysSystem_Shell_GetArgumentForUnix(const char* in,
-                                                       char* out,
-                                                       int flags);
-
-/**
- * Compute the size of the buffer required to store the output from
- * kwsysSystem_Shell_GetArgumentForWindows or
- * kwsysSystem_Shell_GetArgumentForUnix.  The flags passed must be
- * identical between the two calls.
- */
-kwsysEXPORT int kwsysSystem_Shell_GetArgumentSizeForWindows(const char* in,
-                                                            int flags);
-kwsysEXPORT int kwsysSystem_Shell_GetArgumentSizeForUnix(const char* in,
-                                                         int flags);
-
-/**
- * Flags to pass to kwsysSystem_Shell_GetArgumentForWindows or
- * kwsysSystem_Shell_GetArgumentForUnix.  These modify the generated
- * quoting and escape sequences to work under alternative
- * environments.
- */
-enum kwsysSystem_Shell_Flag_e
-{
-  /** The target shell is in a makefile.  */
-  kwsysSystem_Shell_Flag_Make               = (1<<0),
-
-  /** The target shell is in a VS project file.  Do not use with
-      Shell_Flag_Make.  */
-  kwsysSystem_Shell_Flag_VSIDE              = (1<<1),
-
-  /** In a windows shell the argument is being passed to "echo".  */
-  kwsysSystem_Shell_Flag_EchoWindows        = (1<<2),
-
-  /** The target shell is in a Watcom WMake makefile.  */
-  kwsysSystem_Shell_Flag_WatcomWMake        = (1<<3),
-
-  /** The target shell is in a MinGW Make makefile.  */
-  kwsysSystem_Shell_Flag_MinGWMake          = (1<<4),
-
-  /** The target shell is in a NMake makefile.  */
-  kwsysSystem_Shell_Flag_NMake              = (1<<5),
-
-  /** Make variable reference syntax $(MAKEVAR) should not be escaped
-      to allow a build tool to replace it.  Replacement values
-      containing spaces, quotes, backslashes, or other
-      non-alphanumeric characters that have significance to some makes
-      or shells produce undefined behavior.  */
-  kwsysSystem_Shell_Flag_AllowMakeVariables = (1<<6),
-
-  /** The target shell quoting uses extra single Quotes for Watcom tools.  */
-  kwsysSystem_Shell_Flag_WatcomQuote        = (1<<7)
-};
-
-/**
  * Parse a unix-style command line string into separate arguments.
  *
  * On success, returns a pointer to an array of pointers to individual
@@ -148,19 +63,6 @@ kwsysEXPORT char** kwsysSystem_Parse_CommandForUnix(const char* command,
 # undef kwsysEXPORT
 # if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
 #  undef kwsysSystem_Parse_CommandForUnix
-#  undef kwsysSystem_Shell_GetArgumentForWindows
-#  undef kwsysSystem_Shell_GetArgumentForUnix
-#  undef kwsysSystem_Shell_GetArgumentSizeForWindows
-#  undef kwsysSystem_Shell_GetArgumentSizeForUnix
-#  undef kwsysSystem_Shell_Flag_e
-#  undef kwsysSystem_Shell_Flag_Make
-#  undef kwsysSystem_Shell_Flag_VSIDE
-#  undef kwsysSystem_Shell_Flag_EchoWindows
-#  undef kwsysSystem_Shell_Flag_WatcomWMake
-#  undef kwsysSystem_Shell_Flag_MinGWMake
-#  undef kwsysSystem_Shell_Flag_NMake
-#  undef kwsysSystem_Shell_Flag_AllowMakeVariables
-#  undef kwsysSystem_Shell_Flag_WatcomQuote
 # endif
 #endif
 
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index b0434f4..cddcc8d 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -35,14 +35,8 @@
 // http://msdn.microsoft.com/en-us/library/ms683219(VS.85).aspx
 
 #include "kwsysPrivate.h"
-#include KWSYS_HEADER(stl/string)
-#include KWSYS_HEADER(stl/vector)
-#include KWSYS_HEADER(ios/iosfwd)
 #include KWSYS_HEADER(SystemInformation.hxx)
 #include KWSYS_HEADER(Process.h)
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(ios/sstream)
-#include KWSYS_HEADER(ios/fstream)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
@@ -50,14 +44,14 @@
 # include "SystemInformation.hxx.in"
 # include "Process.h.in"
 # include "Configure.hxx.in"
-# include "kwsys_stl.hxx.in"
-# include "kwsys_stl_vector.in"
-# include "kwsys_stl_iosfwd.in"
-# include "kwsys_ios_sstream.h.in"
-# include "kwsys_ios_iostream.h.in"
-# include "kwsys_ios_fstream.h.in"
 #endif
 
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <string>
+#include <vector>
+
 #if defined(_WIN32)
 # include <windows.h>
 # if defined(_MSC_VER) && _MSC_VER >= 1800
@@ -81,6 +75,11 @@ typedef int siginfo_t;
 # include <errno.h> // extern int errno;
 #endif
 
+#if defined (__CYGWIN__) && !defined(_WIN32)
+# include <windows.h>
+# undef _WIN32
+#endif
+
 #ifdef __FreeBSD__
 # include <sys/sysctl.h>
 # include <fenv.h>
@@ -320,11 +319,11 @@ public:
 
   const char * GetVendorString();
   const char * GetVendorID();
-  kwsys_stl::string GetTypeID();
-  kwsys_stl::string GetFamilyID();
-  kwsys_stl::string GetModelID();
-  kwsys_stl::string GetModelName();
-  kwsys_stl::string GetSteppingCode();
+  std::string GetTypeID();
+  std::string GetFamilyID();
+  std::string GetModelID();
+  std::string GetModelName();
+  std::string GetSteppingCode();
   const char * GetExtendedProcessorName();
   const char * GetProcessorSerialNumber();
   int GetProcessorCacheSize();
@@ -336,7 +335,7 @@ public:
 
   const char * GetOSName();
   const char * GetHostname();
-  int GetFullyQualifiedDomainName(kwsys_stl::string &fqdn);
+  int GetFullyQualifiedDomainName(std::string &fqdn);
   const char * GetOSRelease();
   const char * GetOSVersion();
   const char * GetOSPlatform();
@@ -366,13 +365,15 @@ public:
         const char *procLimitEnvVarName);
   LongLong GetProcMemoryUsed();
 
+  double GetLoadAverage();
+
   // enable/disable stack trace signal handler.
   static
   void SetStackTraceOnError(int enable);
 
   // get current stack
   static
-  kwsys_stl::string GetProgramStack(int firstFrame, int wholePath);
+  std::string GetProgramStack(int firstFrame, int wholePath);
 
   /** Run the different checks */
   void RunCPUCheck();
@@ -388,10 +389,10 @@ public:
     int Revision;
     int ExtendedFamily;
     int ExtendedModel;
-    kwsys_stl::string ProcessorName;
-    kwsys_stl::string Vendor;
-    kwsys_stl::string SerialNumber;
-    kwsys_stl::string ModelName;
+    std::string ProcessorName;
+    std::string Vendor;
+    std::string SerialNumber;
+    std::string ModelName;
     } ID;
 
   typedef struct tagCPUPowerManagement
@@ -473,7 +474,7 @@ protected:
 
   // For Linux and Cygwin, /proc/cpuinfo formats are slightly different
   bool RetreiveInformationFromCpuInfoFile();
-  kwsys_stl::string ExtractValueFromCpuInfoFile(kwsys_stl::string buffer,
+  std::string ExtractValueFromCpuInfoFile(std::string buffer,
                                           const char* word, size_t init=0);
 
   bool QueryLinuxMemory();
@@ -482,20 +483,20 @@ protected:
   static void Delay (unsigned int);
   static void DelayOverhead (unsigned int);
 
-  void FindManufacturer(const kwsys_stl::string &family = "");
+  void FindManufacturer(const std::string &family = "");
 
   // For Mac
   bool ParseSysCtl();
-  int CallSwVers(const char *arg, kwsys_stl::string &ver);
-  void TrimNewline(kwsys_stl::string&);
-  kwsys_stl::string ExtractValueFromSysCtl(const char* word);
-  kwsys_stl::string SysCtlBuffer;
+  int CallSwVers(const char *arg, std::string &ver);
+  void TrimNewline(std::string&);
+  std::string ExtractValueFromSysCtl(const char* word);
+  std::string SysCtlBuffer;
 
   // For Solaris
   bool QuerySolarisMemory();
   bool QuerySolarisProcessor();
-  kwsys_stl::string ParseValueFromKStat(const char* arguments);
-  kwsys_stl::string RunProcess(kwsys_stl::vector<const char*> args);
+  std::string ParseValueFromKStat(const char* arguments);
+  std::string RunProcess(std::vector<const char*> args);
 
   //For Haiku OS
   bool QueryHaikuInfo();
@@ -533,11 +534,11 @@ protected:
 
   // Operating System information
   bool QueryOSInformation();
-  kwsys_stl::string OSName;
-  kwsys_stl::string Hostname;
-  kwsys_stl::string OSRelease;
-  kwsys_stl::string OSVersion;
-  kwsys_stl::string OSPlatform;
+  std::string OSName;
+  std::string Hostname;
+  std::string OSRelease;
+  std::string OSVersion;
+  std::string OSPlatform;
 };
 
 
@@ -561,27 +562,27 @@ const char * SystemInformation::GetVendorID()
   return this->Implementation->GetVendorID();
 }
 
-kwsys_stl::string SystemInformation::GetTypeID()
+std::string SystemInformation::GetTypeID()
 {
   return this->Implementation->GetTypeID();
 }
 
-kwsys_stl::string SystemInformation::GetFamilyID()
+std::string SystemInformation::GetFamilyID()
 {
   return this->Implementation->GetFamilyID();
 }
 
-kwsys_stl::string SystemInformation::GetModelID()
+std::string SystemInformation::GetModelID()
 {
   return this->Implementation->GetModelID();
 }
 
-kwsys_stl::string SystemInformation::GetModelName()
+std::string SystemInformation::GetModelName()
 {
   return this->Implementation->GetModelName();
 }
 
-kwsys_stl::string SystemInformation::GetSteppingCode()
+std::string SystemInformation::GetSteppingCode()
 {
   return this->Implementation->GetSteppingCode();
 }
@@ -626,9 +627,9 @@ bool SystemInformation::DoesCPUSupportFeature(long int i)
   return this->Implementation->DoesCPUSupportFeature(i);
 }
 
-kwsys_stl::string SystemInformation::GetCPUDescription()
+std::string SystemInformation::GetCPUDescription()
 {
-  kwsys_ios::ostringstream oss;
+  std::ostringstream oss;
   oss
     << this->GetNumberOfPhysicalCPU()
     << " core ";
@@ -647,9 +648,9 @@ kwsys_stl::string SystemInformation::GetCPUDescription()
     }
 
   // remove extra spaces
-  kwsys_stl::string tmp=oss.str();
+  std::string tmp=oss.str();
   size_t pos;
-  while( (pos=tmp.find("  "))!=kwsys_stl::string::npos)
+  while( (pos=tmp.find("  "))!=std::string::npos)
     {
     tmp.replace(pos,2," ");
     }
@@ -667,9 +668,9 @@ const char * SystemInformation::GetHostname()
   return this->Implementation->GetHostname();
 }
 
-kwsys_stl::string SystemInformation::GetFullyQualifiedDomainName()
+std::string SystemInformation::GetFullyQualifiedDomainName()
 {
-  kwsys_stl::string fqdn;
+  std::string fqdn;
   this->Implementation->GetFullyQualifiedDomainName(fqdn);
   return fqdn;
 }
@@ -716,9 +717,9 @@ int SystemInformation::GetOSIsApple()
 #endif
 }
 
-kwsys_stl::string SystemInformation::GetOSDescription()
+std::string SystemInformation::GetOSDescription()
 {
-  kwsys_ios::ostringstream oss;
+  std::ostringstream oss;
   oss
     << this->GetOSName()
     << " "
@@ -770,11 +771,11 @@ size_t SystemInformation::GetAvailablePhysicalMemory()
   return this->Implementation->GetAvailablePhysicalMemory();
 }
 
-kwsys_stl::string SystemInformation::GetMemoryDescription(
+std::string SystemInformation::GetMemoryDescription(
       const char *hostLimitEnvVarName,
       const char *procLimitEnvVarName)
 {
-  kwsys_ios::ostringstream oss;
+  std::ostringstream oss;
   oss
     << "Host Total: "
     << iostreamLongLong(this->GetHostMemoryTotal())
@@ -820,6 +821,11 @@ SystemInformation::LongLong SystemInformation::GetProcMemoryUsed()
   return this->Implementation->GetProcMemoryUsed();
 }
 
+double SystemInformation::GetLoadAverage()
+{
+  return this->Implementation->GetLoadAverage();
+}
+
 SystemInformation::LongLong SystemInformation::GetProcessId()
 {
   return this->Implementation->GetProcessId();
@@ -830,7 +836,7 @@ void SystemInformation::SetStackTraceOnError(int enable)
   SystemInformationImplementation::SetStackTraceOnError(enable);
 }
 
-kwsys_stl::string SystemInformation::GetProgramStack(int firstFrame, int wholePath)
+std::string SystemInformation::GetProgramStack(int firstFrame, int wholePath)
 {
   return SystemInformationImplementation::GetProgramStack(firstFrame, wholePath);
 }
@@ -914,7 +920,7 @@ namespace {
 #if defined(__linux) || defined(__APPLE__)
 int LoadLines(
       FILE *file,
-      kwsys_stl::vector<kwsys_stl::string> &lines)
+      std::vector<std::string> &lines)
 {
   // Load each line in the given file into a the vector.
   int nRead=0;
@@ -951,7 +957,7 @@ int LoadLines(
 // *****************************************************************************
 int LoadLines(
       const char *fileName,
-      kwsys_stl::vector<kwsys_stl::string> &lines)
+      std::vector<std::string> &lines)
 {
   FILE *file=fopen(fileName,"r");
   if (file==0)
@@ -967,18 +973,18 @@ int LoadLines(
 // ****************************************************************************
 template<typename T>
 int NameValue(
-      kwsys_stl::vector<kwsys_stl::string> &lines,
-      kwsys_stl::string name, T &value)
+      std::vector<std::string> &lines,
+      std::string name, T &value)
 {
   size_t nLines=lines.size();
   for (size_t i=0; i<nLines; ++i)
     {
     size_t at=lines[i].find(name);
-    if (at==kwsys_stl::string::npos)
+    if (at==std::string::npos)
       {
       continue;
       }
-    kwsys_ios::istringstream is(lines[i].substr(at+name.size()));
+    std::istringstream is(lines[i].substr(at+name.size()));
     is >> value;
     return 0;
     }
@@ -994,7 +1000,7 @@ int GetFieldsFromFile(
       const char **fieldNames,
       T *values)
 {
-  kwsys_stl::vector<kwsys_stl::string> fields;
+  std::vector<std::string> fields;
   if (!LoadLines(fileName,fields))
     {
     return -1;
@@ -1044,7 +1050,7 @@ int GetFieldsFromCommand(
     {
     return -1;
     }
-  kwsys_stl::vector<kwsys_stl::string> fields;
+  std::vector<std::string> fields;
   int nl=LoadLines(file,fields);
   pclose(file);
   if (nl==0)
@@ -1073,10 +1079,10 @@ void StacktraceSignalHandler(
       void * /*sigContext*/)
 {
 #if defined(__linux) || defined(__APPLE__)
-  kwsys_ios::ostringstream oss;
+  std::ostringstream oss;
   oss
-     << kwsys_ios::endl
-     << "=========================================================" << kwsys_ios::endl
+     << std::endl
+     << "=========================================================" << std::endl
      << "Process id " << getpid() << " ";
   switch (sigNo)
     {
@@ -1269,11 +1275,11 @@ void StacktraceSignalHandler(
       break;
     }
   oss
-    << kwsys_ios::endl
-    << "Program Stack:" << kwsys_ios::endl
+    << std::endl
+    << "Program Stack:" << std::endl
     << SystemInformationImplementation::GetProgramStack(2,0)
-    << "=========================================================" << kwsys_ios::endl;
-  kwsys_ios::cerr << oss.str() << kwsys_ios::endl;
+    << "=========================================================" << std::endl;
+  std::cerr << oss.str() << std::endl;
 
   // restore the previously registered handlers
   // and abort
@@ -1318,7 +1324,7 @@ public:
   void SetBinary(const char *binary)
     { this->Binary=safes(binary); }
 
-  kwsys_stl::string GetBinary() const;
+  std::string GetBinary() const;
 
   // Description:
   // Set the name of the function that the symbol is found in.
@@ -1326,7 +1332,7 @@ public:
   void SetFunction(const char *function)
     { this->Function=this->Demangle(function); }
 
-  kwsys_stl::string GetFunction() const
+  std::string GetFunction() const
     { return this->Function; }
 
   // Description:
@@ -1335,7 +1341,7 @@ public:
   void SetSourceFile(const char *sourcefile)
     { this->SourceFile=safes(sourcefile); }
 
-  kwsys_stl::string GetSourceFile() const
+  std::string GetSourceFile() const
     { return this->GetFileName(this->SourceFile); }
 
   // Description:
@@ -1353,31 +1359,31 @@ private:
   void *GetRealAddress() const
     { return (void*)((char*)this->Address-(char*)this->BinaryBaseAddress); }
 
-  kwsys_stl::string GetFileName(const kwsys_stl::string &path) const;
-  kwsys_stl::string Demangle(const char *symbol) const;
+  std::string GetFileName(const std::string &path) const;
+  std::string Demangle(const char *symbol) const;
 
 private:
-  kwsys_stl::string Binary;
+  std::string Binary;
   void *BinaryBaseAddress;
   void *Address;
-  kwsys_stl::string SourceFile;
-  kwsys_stl::string Function;
+  std::string SourceFile;
+  std::string Function;
   long LineNumber;
   int ReportPath;
 };
 
 // --------------------------------------------------------------------------
-kwsys_ios::ostream &operator<<(
-      kwsys_ios::ostream &os,
+std::ostream &operator<<(
+      std::ostream &os,
       const SymbolProperties &sp)
 {
 #if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
   os
-    << kwsys_ios::hex << sp.GetAddress() << " : "
+    << std::hex << sp.GetAddress() << " : "
     << sp.GetFunction()
     << " [(" << sp.GetBinary() << ") "
     << sp.GetSourceFile() << ":"
-    << kwsys_ios::dec << sp.GetLineNumber() << "]";
+    << std::dec << sp.GetLineNumber() << "]";
 #elif defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
   void *addr = sp.GetAddress();
   char **syminfo = backtrace_symbols(&addr,1);
@@ -1410,28 +1416,28 @@ SymbolProperties::SymbolProperties()
 }
 
 // --------------------------------------------------------------------------
-kwsys_stl::string SymbolProperties::GetFileName(const kwsys_stl::string &path) const
+std::string SymbolProperties::GetFileName(const std::string &path) const
 {
-  kwsys_stl::string file(path);
+  std::string file(path);
   if (!this->ReportPath)
     {
     size_t at = file.rfind("/");
-    if (at!=kwsys_stl::string::npos)
+    if (at!=std::string::npos)
       {
-      file = file.substr(at+1,kwsys_stl::string::npos);
+      file = file.substr(at+1,std::string::npos);
       }
     }
   return file;
 }
 
 // --------------------------------------------------------------------------
-kwsys_stl::string SymbolProperties::GetBinary() const
+std::string SymbolProperties::GetBinary() const
 {
 // only linux has proc fs
 #if defined(__linux__)
   if (this->Binary=="/proc/self/exe")
     {
-    kwsys_stl::string binary;
+    std::string binary;
     char buf[1024]={'\0'};
     ssize_t ll=0;
     if ((ll=readlink("/proc/self/exe",buf,1024))>0)
@@ -1450,9 +1456,9 @@ kwsys_stl::string SymbolProperties::GetBinary() const
 }
 
 // --------------------------------------------------------------------------
-kwsys_stl::string SymbolProperties::Demangle(const char *symbol) const
+std::string SymbolProperties::Demangle(const char *symbol) const
 {
-  kwsys_stl::string result = safes(symbol);
+  std::string result = safes(symbol);
 #if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
   int status = 0;
   size_t bufferLen = 1024;
@@ -1490,6 +1496,60 @@ void SymbolProperties::Initialize(void *address)
 }
 #endif // don't define this class if we're not using it
 
+// --------------------------------------------------------------------------
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes
+#endif
+#if defined(_MSC_VER) && _MSC_VER < 1310
+# undef KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes
+#endif
+#if defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes)
+double calculateCPULoad(unsigned __int64 idleTicks,
+                        unsigned __int64 totalTicks)
+{
+  static double previousLoad = -0.0;
+  static unsigned __int64 previousIdleTicks = 0;
+  static unsigned __int64 previousTotalTicks = 0;
+
+  unsigned __int64 const idleTicksSinceLastTime =
+    idleTicks - previousIdleTicks;
+  unsigned __int64 const totalTicksSinceLastTime =
+    totalTicks - previousTotalTicks;
+
+  double load;
+  if (previousTotalTicks == 0 || totalTicksSinceLastTime == 0)
+    {
+    // No new information.  Use previous result.
+    load = previousLoad;
+    }
+  else
+    {
+    // Calculate load since last time.
+    load = 1.0 - double(idleTicksSinceLastTime) / totalTicksSinceLastTime;
+
+    // Smooth if possible.
+    if (previousLoad > 0)
+      {
+      load = 0.25 * load + 0.75 * previousLoad;
+      }
+    }
+
+  previousLoad = load;
+  previousIdleTicks = idleTicks;
+  previousTotalTicks = totalTicks;
+
+  return load;
+}
+
+unsigned __int64 fileTimeToUInt64(FILETIME const& ft)
+{
+  LARGE_INTEGER out;
+  out.HighPart = ft.dwHighDateTime;
+  out.LowPart = ft.dwLowDateTime;
+  return out.QuadPart;
+}
+#endif
+
 } // anonymous namespace
 
 
@@ -1663,7 +1723,7 @@ const char* SystemInformationImplementation::GetHostname()
 
 /** Get the FQDN */
 int SystemInformationImplementation::GetFullyQualifiedDomainName(
-      kwsys_stl::string &fqdn)
+      std::string &fqdn)
 {
   // in the event of absolute failure return localhost.
   fqdn="localhost";
@@ -1754,8 +1814,8 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName(
         continue;
         }
 
-      kwsys_stl::string candidate=host;
-      if ((candidate.find(base)!=kwsys_stl::string::npos) && baseSize<candidate.size())
+      std::string candidate=host;
+      if ((candidate.find(base)!=std::string::npos) && baseSize<candidate.size())
         {
         // success, stop now.
         ierr=0;
@@ -1831,39 +1891,39 @@ const char * SystemInformationImplementation::GetVendorID()
 }
 
 /** Return the type ID of the CPU */
-kwsys_stl::string SystemInformationImplementation::GetTypeID()
+std::string SystemInformationImplementation::GetTypeID()
 {
-  kwsys_ios::ostringstream str;
+  std::ostringstream str;
   str << this->ChipID.Type;
   return str.str();
 }
 
 /** Return the family of the CPU present */
-kwsys_stl::string SystemInformationImplementation::GetFamilyID()
+std::string SystemInformationImplementation::GetFamilyID()
 {
-  kwsys_ios::ostringstream str;
+  std::ostringstream str;
   str << this->ChipID.Family;
   return str.str();
 }
 
 // Return the model of CPU present */
-kwsys_stl::string SystemInformationImplementation::GetModelID()
+std::string SystemInformationImplementation::GetModelID()
 {
-  kwsys_ios::ostringstream str;
+  std::ostringstream str;
   str << this->ChipID.Model;
   return str.str();
 }
 
 // Return the model name of CPU present */
-kwsys_stl::string SystemInformationImplementation::GetModelName()
+std::string SystemInformationImplementation::GetModelName()
 {
   return this->ChipID.ModelName;
 }
 
 /** Return the stepping code of the CPU present. */
-kwsys_stl::string SystemInformationImplementation::GetSteppingCode()
+std::string SystemInformationImplementation::GetSteppingCode()
 {
-  kwsys_ios::ostringstream str;
+  std::ostringstream str;
   str << this->ChipID.Revision;
   return str.str();
 }
@@ -2114,7 +2174,7 @@ bool SystemInformationImplementation::RetrieveCPUFeatures()
 
 
 /** Find the manufacturer given the vendor id */
-void SystemInformationImplementation::FindManufacturer(const kwsys_stl::string& family)
+void SystemInformationImplementation::FindManufacturer(const std::string& family)
 {
   if (this->ChipID.Vendor == "GenuineIntel")       this->ChipManufacturer = Intel;        // Intel Corp.
   else if (this->ChipID.Vendor == "UMC UMC UMC ")  this->ChipManufacturer = UMC;          // United Microelectronics Corp.
@@ -2733,11 +2793,11 @@ bool SystemInformationImplementation::RetrieveCPUPowerManagement()
 
 #if USE_CPUID
 // Used only in USE_CPUID implementation below.
-static void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
+static void SystemInformationStripLeadingSpace(std::string& str)
 {
   // Because some manufacturers have leading white space - we have to post-process the name.
-  kwsys_stl::string::size_type pos = str.find_first_not_of(" ");
-  if(pos != kwsys_stl::string::npos)
+  std::string::size_type pos = str.find_first_not_of(" ");
+  if(pos != std::string::npos)
     {
     str = str.substr(pos);
     }
@@ -3082,7 +3142,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
 
 
 /** Extract a value from the CPUInfo file */
-kwsys_stl::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(kwsys_stl::string buffer,const char* word,size_t init)
+std::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(std::string buffer,const char* word,size_t init)
 {
   size_t pos = buffer.find(word,init);
   if(pos != buffer.npos)
@@ -3114,12 +3174,12 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
 {
   this->NumberOfLogicalCPU = 0;
   this->NumberOfPhysicalCPU = 0;
-  kwsys_stl::string buffer;
+  std::string buffer;
 
   FILE *fd = fopen("/proc/cpuinfo", "r" );
   if ( !fd )
     {
-    kwsys_ios::cout << "Problem opening /proc/cpuinfo" << kwsys_ios::endl;
+    std::cout << "Problem opening /proc/cpuinfo" << std::endl;
     return false;
     }
 
@@ -3143,7 +3203,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
 #ifdef __linux
   // Find the largest physical id.
   int maxId = -1;
-  kwsys_stl::string idc =
+  std::string idc =
                        this->ExtractValueFromCpuInfoFile(buffer,"physical id");
   while(this->CurrentPositionInFile != buffer.npos)
     {
@@ -3158,7 +3218,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
   // Physical ids returned by Linux don't distinguish cores.
   // We want to record the total number of cores in this->NumberOfPhysicalCPU
   // (checking only the first proc)
-  kwsys_stl::string cores =
+  std::string cores =
                         this->ExtractValueFromCpuInfoFile(buffer,"cpu cores");
   int numberOfCoresPerCPU=atoi(cores.c_str());
   if (maxId > 0)
@@ -3176,7 +3236,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
 #else // __CYGWIN__
   // does not have "physical id" entries, neither "cpu cores"
   // this has to be fixed for hyper-threading.
-  kwsys_stl::string cpucount =
+  std::string cpucount =
     this->ExtractValueFromCpuInfoFile(buffer,"cpu count");
   this->NumberOfPhysicalCPU=
     this->NumberOfLogicalCPU = atoi(cpucount.c_str());
@@ -3192,7 +3252,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
       this->NumberOfLogicalCPU/this->NumberOfPhysicalCPU;
 
   // CPU speed (checking only the first processor)
-  kwsys_stl::string CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer,"cpu MHz");
+  std::string CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer,"cpu MHz");
   if(!CPUSpeed.empty())
     {
     this->CPUSpeedInMHz = static_cast<float>(atof(CPUSpeed.c_str()));
@@ -3208,7 +3268,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
 #endif
 
   // Chip family
-  kwsys_stl::string familyStr =
+  std::string familyStr =
     this->ExtractValueFromCpuInfoFile(buffer,"cpu family");
   if(familyStr.empty())
     {
@@ -3238,7 +3298,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
     {
     // Some platforms (e.g. PA-RISC) tell us their CPU name here.
     // Note: x86 does not.
-    kwsys_stl::string cpuname = this->ExtractValueFromCpuInfoFile(buffer,"cpu");
+    std::string cpuname = this->ExtractValueFromCpuInfoFile(buffer,"cpu");
     if(!cpuname.empty())
       {
       this->ChipID.ProcessorName = cpuname;
@@ -3246,7 +3306,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
     }
 
   // Chip revision
-  kwsys_stl::string cpurev = this->ExtractValueFromCpuInfoFile(buffer,"stepping");
+  std::string cpurev = this->ExtractValueFromCpuInfoFile(buffer,"stepping");
   if(cpurev.empty())
     {
     cpurev = this->ExtractValueFromCpuInfoFile(buffer,"CPU revision");
@@ -3259,7 +3319,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
   // L1 Cache size
   // Different architectures may show different names for the caches.
   // Sum up everything we find.
-  kwsys_stl::vector<const char*> cachename;
+  std::vector<const char*> cachename;
   cachename.clear();
 
   cachename.push_back("cache size"); // e.g. x86
@@ -3269,7 +3329,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
   this->Features.L1CacheSize = 0;
   for (size_t index = 0; index < cachename.size(); index ++)
     {
-    kwsys_stl::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer,cachename[index]);
+    std::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer,cachename[index]);
     if (!cacheSize.empty())
       {
       pos = cacheSize.find(" KB");
@@ -3282,48 +3342,48 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
     }
 
   // processor feature flags (probably x86 specific)
-  kwsys_stl::string cpuflags = this->ExtractValueFromCpuInfoFile(buffer,"flags");
+  std::string cpuflags = this->ExtractValueFromCpuInfoFile(buffer,"flags");
   if(!cpurev.empty())
     {
     // now we can match every flags as space + flag + space
     cpuflags = " " + cpuflags + " ";
-    if ((cpuflags.find(" fpu ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" fpu ")!=std::string::npos))
       {
       this->Features.HasFPU = true;
       }
-    if ((cpuflags.find(" tsc ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" tsc ")!=std::string::npos))
       {
       this->Features.HasTSC = true;
       }
-    if ((cpuflags.find(" mmx ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" mmx ")!=std::string::npos))
       {
       this->Features.HasMMX = true;
       }
-    if ((cpuflags.find(" sse ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" sse ")!=std::string::npos))
       {
       this->Features.HasSSE = true;
       }
-    if ((cpuflags.find(" sse2 ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" sse2 ")!=std::string::npos))
       {
       this->Features.HasSSE2 = true;
       }
-    if ((cpuflags.find(" apic ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" apic ")!=std::string::npos))
       {
       this->Features.HasAPIC = true;
       }
-    if ((cpuflags.find(" cmov ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" cmov ")!=std::string::npos))
       {
       this->Features.HasCMOV = true;
       }
-    if ((cpuflags.find(" mtrr ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" mtrr ")!=std::string::npos))
       {
       this->Features.HasMTRR = true;
       }
-    if ((cpuflags.find(" acpi ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" acpi ")!=std::string::npos))
       {
       this->Features.HasACPI = true;
       }
-    if ((cpuflags.find(" 3dnow ")!=kwsys_stl::string::npos))
+    if ((cpuflags.find(" 3dnow ")!=std::string::npos))
       {
       this->Features.ExtendedFeatures.Has3DNow = true;
       }
@@ -3579,7 +3639,7 @@ SystemInformationImplementation::GetProcMemoryUsed()
 #elif defined(__APPLE__)
   SystemInformation::LongLong memUsed=0;
   pid_t pid=getpid();
-  kwsys_ios::ostringstream oss;
+  std::ostringstream oss;
   oss << "ps -o rss= -p " << pid;
   FILE *file=popen(oss.str().c_str(),"r");
   if (file==0)
@@ -3604,7 +3664,7 @@ SystemInformationImplementation::GetProcMemoryUsed()
     {
     return -2;
     }
-  kwsys_ios::istringstream iss(oss.str());
+  std::istringstream iss(oss.str());
   iss >> memUsed;
   return memUsed;
 #else
@@ -3612,6 +3672,38 @@ SystemInformationImplementation::GetProcMemoryUsed()
 #endif
 }
 
+double SystemInformationImplementation::GetLoadAverage()
+{
+#if defined(KWSYS_CXX_HAS_GETLOADAVG)
+  double loadavg[3] = { 0.0, 0.0, 0.0 };
+  if (getloadavg(loadavg, 3) > 0)
+    {
+    return loadavg[0];
+    }
+  return -0.0;
+#elif defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes)
+  // Old windows.h headers do not provide GetSystemTimes.
+  typedef BOOL (WINAPI *GetSystemTimesType)(LPFILETIME, LPFILETIME,
+                                            LPFILETIME);
+  static GetSystemTimesType pGetSystemTimes =
+    (GetSystemTimesType)GetProcAddress(GetModuleHandleW(L"kernel32"),
+                                       "GetSystemTimes");
+  FILETIME idleTime, kernelTime, userTime;
+  if (pGetSystemTimes && pGetSystemTimes(&idleTime, &kernelTime, &userTime))
+    {
+    unsigned __int64 const idleTicks =
+      fileTimeToUInt64(idleTime);
+    unsigned __int64 const totalTicks =
+      fileTimeToUInt64(kernelTime) + fileTimeToUInt64(userTime);
+    return calculateCPULoad(idleTicks, totalTicks) * GetNumberOfPhysicalCPU();
+    }
+  return -0.0;
+#else
+  // Not implemented on this platform.
+  return -0.0;
+#endif
+}
+
 /**
 Get the process id of the running process.
 */
@@ -3631,11 +3723,11 @@ SystemInformationImplementation::GetProcessId()
 return current program stack in a string
 demangle cxx symbols if possible.
 */
-kwsys_stl::string SystemInformationImplementation::GetProgramStack(
+std::string SystemInformationImplementation::GetProgramStack(
       int firstFrame,
       int wholePath)
 {
-  kwsys_stl::string programStack = ""
+  std::string programStack = ""
 #if !defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
     "WARNING: The stack could not be examined "
     "because backtrace is not supported.\n"
@@ -3654,7 +3746,7 @@ kwsys_stl::string SystemInformationImplementation::GetProgramStack(
 #endif
     ;
 
-  kwsys_ios::ostringstream oss;
+  std::ostringstream oss;
 #if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
   void *stackSymbols[256];
   int nFrames=backtrace(stackSymbols,256);
@@ -3663,7 +3755,7 @@ kwsys_stl::string SystemInformationImplementation::GetProgramStack(
     SymbolProperties symProps;
     symProps.SetReportPath(wholePath);
     symProps.Initialize(stackSymbols[i]);
-    oss << symProps << kwsys_ios::endl;
+    oss << symProps << std::endl;
     }
 #else
   (void)firstFrame;
@@ -3794,7 +3886,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
   int errorFlag = uname(&unameInfo);
   if( errorFlag!=0 )
     {
-    kwsys_ios::cout << "Problem calling uname(): " << strerror(errno) << kwsys_ios::endl;
+    std::cout << "Problem calling uname(): " << strerror(errno) << std::endl;
     return false;
     }
 
@@ -3818,7 +3910,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
   FILE *fd = fopen("/proc/meminfo", "r" );
   if ( !fd )
     {
-    kwsys_ios::cout << "Problem opening /proc/meminfo" << kwsys_ios::endl;
+    std::cout << "Problem opening /proc/meminfo" << std::endl;
     return false;
     }
 
@@ -3856,7 +3948,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
       }
     else
       {
-      kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl;
+      std::cout << "Problem parsing /proc/meminfo" << std::endl;
       fclose(fd);
       return false;
       }
@@ -3889,7 +3981,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
       }
     else
       {
-      kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl;
+      std::cout << "Problem parsing /proc/meminfo" << std::endl;
       fclose(fd);
       return false;
       }
@@ -4366,8 +4458,8 @@ bool SystemInformationImplementation::ParseSysCtl()
     ::memset(retBuf, 0, 128);
     len = 32;
     err = sysctlbyname("hw.machine", &retBuf, &len, NULL, 0);
-    kwsys_stl::string machineBuf(retBuf);
-    if (machineBuf.find_first_of("Power") != kwsys_stl::string::npos)
+    std::string machineBuf(retBuf);
+    if (machineBuf.find_first_of("Power") != std::string::npos)
       {
       this->ChipID.Vendor = "IBM";
       len = sizeof(this->ChipID.Family);
@@ -4429,41 +4521,41 @@ bool SystemInformationImplementation::ParseSysCtl()
       {
       // now we can match every flags as space + flag + space
       buf[len + 1] = ' ';
-      kwsys_stl::string cpuflags(buf, len + 2);
+      std::string cpuflags(buf, len + 2);
 
-      if ((cpuflags.find(" FPU ")!=kwsys_stl::string::npos))
+      if ((cpuflags.find(" FPU ")!=std::string::npos))
         {
         this->Features.HasFPU = true;
         }
-      if ((cpuflags.find(" TSC ")!=kwsys_stl::string::npos))
+      if ((cpuflags.find(" TSC ")!=std::string::npos))
         {
         this->Features.HasTSC = true;
         }
-      if ((cpuflags.find(" MMX ")!=kwsys_stl::string::npos))
+      if ((cpuflags.find(" MMX ")!=std::string::npos))
         {
         this->Features.HasMMX = true;
         }
-      if ((cpuflags.find(" SSE ")!=kwsys_stl::string::npos))
+      if ((cpuflags.find(" SSE ")!=std::string::npos))
         {
         this->Features.HasSSE = true;
         }
-      if ((cpuflags.find(" SSE2 ")!=kwsys_stl::string::npos))
+      if ((cpuflags.find(" SSE2 ")!=std::string::npos))
         {
         this->Features.HasSSE2 = true;
         }
-      if ((cpuflags.find(" APIC ")!=kwsys_stl::string::npos))
+      if ((cpuflags.find(" APIC ")!=std::string::npos))
         {
         this->Features.HasAPIC = true;
         }
-      if ((cpuflags.find(" CMOV ")!=kwsys_stl::string::npos))
+      if ((cpuflags.find(" CMOV ")!=std::string::npos))
         {
         this->Features.HasCMOV = true;
         }
-      if ((cpuflags.find(" MTRR ")!=kwsys_stl::string::npos))
+      if ((cpuflags.find(" MTRR ")!=std::string::npos))
         {
         this->Features.HasMTRR = true;
         }
-      if ((cpuflags.find(" ACPI ")!=kwsys_stl::string::npos))
+      if ((cpuflags.find(" ACPI ")!=std::string::npos))
         {
         this->Features.HasACPI = true;
         }
@@ -4497,7 +4589,7 @@ bool SystemInformationImplementation::ParseSysCtl()
 
 
 /** Extract a value from sysctl command */
-kwsys_stl::string SystemInformationImplementation::ExtractValueFromSysCtl(const char* word)
+std::string SystemInformationImplementation::ExtractValueFromSysCtl(const char* word)
 {
   size_t pos = this->SysCtlBuffer.find(word);
   if(pos != this->SysCtlBuffer.npos)
@@ -4514,9 +4606,9 @@ kwsys_stl::string SystemInformationImplementation::ExtractValueFromSysCtl(const
 
 
 /** Run a given process */
-kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<const char*> args)
+std::string SystemInformationImplementation::RunProcess(std::vector<const char*> args)
 {
-  kwsys_stl::string buffer = "";
+  std::string buffer = "";
 
   // Run the application
   kwsysProcess* gp = kwsysProcess_New();
@@ -4546,12 +4638,12 @@ kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<
       } break;
     case kwsysProcess_State_Error:
       {
-      kwsys_ios::cerr << "Error: Could not run " << args[0] << ":\n";
-      kwsys_ios::cerr << kwsysProcess_GetErrorString(gp) << "\n";
+      std::cerr << "Error: Could not run " << args[0] << ":\n";
+      std::cerr << kwsysProcess_GetErrorString(gp) << "\n";
       } break;
     case kwsysProcess_State_Exception:
       {
-      kwsys_ios::cerr << "Error: " << args[0]
+      std::cerr << "Error: " << args[0]
                 << " terminated with an exception: "
                 << kwsysProcess_GetExceptionString(gp) << "\n";
       } break;
@@ -4561,27 +4653,27 @@ kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<
     case kwsysProcess_State_Killed:
       {
       // Should not get here.
-      kwsys_ios::cerr << "Unexpected ending state after running " << args[0]
-                << kwsys_ios::endl;
+      std::cerr << "Unexpected ending state after running " << args[0]
+                << std::endl;
       } break;
     }
   kwsysProcess_Delete(gp);
   if(result)
     {
-    kwsys_ios::cerr << "Error " << args[0] << " returned :" << result << "\n";
+    std::cerr << "Error " << args[0] << " returned :" << result << "\n";
     }
   return buffer;
 }
 
 
-kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const char* arguments)
+std::string SystemInformationImplementation::ParseValueFromKStat(const char* arguments)
 {
-  kwsys_stl::vector<const char*> args;
+  std::vector<const char*> args;
   args.clear();
   args.push_back("kstat");
   args.push_back("-p");
 
-  kwsys_stl::string command = arguments;
+  std::string command = arguments;
   size_t start = command.npos;
   size_t pos = command.find(' ',0);
   while(pos!=command.npos)
@@ -4603,7 +4695,7 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
 
     if(!inQuotes)
       {
-      kwsys_stl::string arg = command.substr(start+1,pos-start-1);
+      std::string arg = command.substr(start+1,pos-start-1);
 
       // Remove the quotes if any
       size_t quotes = arg.find('"');
@@ -4617,14 +4709,14 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
       }
     pos = command.find(' ',pos+1);
     }
-  kwsys_stl::string lastArg = command.substr(start+1,command.size()-start-1);
+  std::string lastArg = command.substr(start+1,command.size()-start-1);
   args.push_back(lastArg.c_str());
 
   args.push_back(0);
 
-  kwsys_stl::string buffer = this->RunProcess(args);
+  std::string buffer = this->RunProcess(args);
 
-  kwsys_stl::string value = "";
+  std::string value = "";
   for(size_t i=buffer.size()-1;i>0;i--)
     {
     if(buffer[i] == ' ' || buffer[i] == '\t')
@@ -4633,7 +4725,7 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
       }
     if(buffer[i] != '\n' && buffer[i] != '\r')
       {
-      kwsys_stl::string val = value;
+      std::string val = value;
       value = buffer[i];
       value += val;
       }
@@ -4787,8 +4879,8 @@ bool SystemInformationImplementation::QueryHaikuInfo()
 bool SystemInformationImplementation::QueryQNXMemory()
 {
 #if defined(__QNX__)
-  kwsys_stl::string buffer;
-  kwsys_stl::vector<const char*> args;
+  std::string buffer;
+  std::vector<const char*> args;
   args.clear();
 
   args.push_back("showmem");
@@ -4845,8 +4937,8 @@ bool SystemInformationImplementation::QueryQNXProcessor()
 #if defined(__QNX__)
   // the output on my QNX 6.4.1 looks like this:
   // Processor1: 686 Pentium II Stepping 3 2175MHz FPU
-  kwsys_stl::string buffer;
-  kwsys_stl::vector<const char*> args;
+  std::string buffer;
+  std::vector<const char*> args;
   args.clear();
 
   args.push_back("pidin");
@@ -5342,10 +5434,10 @@ bool SystemInformationImplementation::QueryOSInformation()
 
 int SystemInformationImplementation::CallSwVers(
       const char *arg,
-      kwsys_stl::string &ver)
+      std::string &ver)
 {
 #ifdef __APPLE__
-  kwsys_stl::vector<const char*> args;
+  std::vector<const char*> args;
   args.push_back("sw_vers");
   args.push_back(arg);
   args.push_back(0);
@@ -5359,18 +5451,18 @@ int SystemInformationImplementation::CallSwVers(
   return 0;
 }
 
-void SystemInformationImplementation::TrimNewline(kwsys_stl::string& output)
+void SystemInformationImplementation::TrimNewline(std::string& output)
 {
   // remove \r
-  kwsys_stl::string::size_type pos=0;
-  while((pos = output.find("\r", pos)) != kwsys_stl::string::npos)
+  std::string::size_type pos=0;
+  while((pos = output.find("\r", pos)) != std::string::npos)
     {
     output.erase(pos);
     }
 
   // remove \n
   pos = 0;
-  while((pos = output.find("\n", pos)) != kwsys_stl::string::npos)
+  while((pos = output.find("\n", pos)) != std::string::npos)
     {
     output.erase(pos);
     }
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index a9fd05d..7c45388 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -12,14 +12,9 @@
 #ifndef @KWSYS_NAMESPACE at _SystemInformation_h
 #define @KWSYS_NAMESPACE at _SystemInformation_h
 
-
-/* Define these macros temporarily to keep the code readable.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE at _stl
-# define kwsys_ios @KWSYS_NAMESPACE at _ios
-#endif
-#include <@KWSYS_NAMESPACE@/stl/string>
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
 #include <stddef.h> /* size_t */
+#include <string>
 
 namespace @KWSYS_NAMESPACE@
 {
@@ -45,11 +40,11 @@ public:
 
   const char * GetVendorString();
   const char * GetVendorID();
-  kwsys_stl::string GetTypeID();
-  kwsys_stl::string GetFamilyID();
-  kwsys_stl::string GetModelID();
-  kwsys_stl::string GetModelName();
-  kwsys_stl::string GetSteppingCode();
+  std::string GetTypeID();
+  std::string GetFamilyID();
+  std::string GetModelID();
+  std::string GetModelName();
+  std::string GetSteppingCode();
   const char * GetExtendedProcessorName();
   const char * GetProcessorSerialNumber();
   int GetProcessorCacheSize();
@@ -61,10 +56,10 @@ public:
 
   // returns an informative general description of the cpu
   // on this system.
-  kwsys_stl::string GetCPUDescription();
+  std::string GetCPUDescription();
 
   const char * GetHostname();
-  kwsys_stl::string GetFullyQualifiedDomainName();
+  std::string GetFullyQualifiedDomainName();
 
   const char * GetOSName();
   const char * GetOSRelease();
@@ -77,7 +72,7 @@ public:
 
   // returns an informative general description of the os
   // on this system.
-  kwsys_stl::string GetOSDescription();
+  std::string GetOSDescription();
 
   bool Is64Bits();
 
@@ -98,7 +93,7 @@ public:
   // returns an informative general description if the installed and
   // available ram on this system. See the  GetHostMmeoryTotal, and
   // Get{Host,Proc}MemoryAvailable methods for more information.
-  kwsys_stl::string GetMemoryDescription(
+  std::string GetMemoryDescription(
         const char *hostLimitEnvVarName=NULL,
         const char *procLimitEnvVarName=NULL);
 
@@ -130,6 +125,10 @@ public:
   // Get system RAM used by this process id in units of KiB.
   LongLong GetProcMemoryUsed();
 
+  // Return the load average of the machine or -0.0 if it cannot
+  // be determined.
+  double GetLoadAverage();
+
   // enable/disable stack trace signal handler. In order to
   // produce an informative stack trace the application should
   // be dynamically linked and compiled with debug symbols.
@@ -140,7 +139,7 @@ public:
   // order to produce an informative stack trace the application
   // should be dynamically linked and compiled with debug symbols.
   static
-  kwsys_stl::string GetProgramStack(int firstFrame, int wholePath);
+  std::string GetProgramStack(int firstFrame, int wholePath);
 
   /** Run the different checks */
   void RunCPUCheck();
@@ -150,10 +149,4 @@ public:
 
 } // namespace @KWSYS_NAMESPACE@
 
-/* Undefine temporary macros.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# undef kwsys_stl
-# undef kwsys_ios
-#endif
-
 #endif
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index c834e34..262af27 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -31,11 +31,10 @@
 #include KWSYS_HEADER(FStream.hxx)
 #include KWSYS_HEADER(Encoding.hxx)
 
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(ios/fstream)
-#include KWSYS_HEADER(ios/sstream)
-
-#include KWSYS_HEADER(stl/set)
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <set>
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
@@ -44,9 +43,6 @@
 # include "Directory.hxx.in"
 # include "FStream.hxx.in"
 # include "Encoding.hxx.in"
-# include "kwsys_ios_iostream.h.in"
-# include "kwsys_ios_fstream.h.in"
-# include "kwsys_ios_sstream.h.in"
 #endif
 
 #ifdef _MSC_VER
@@ -68,6 +64,10 @@
 #include <sys/stat.h>
 #include <time.h>
 
+#ifdef _MSC_VER
+# define umask _umask // Note this is still umask on Borland
+#endif
+
 // support for realpath call
 #ifndef _WIN32
 #include <sys/time.h>
@@ -216,12 +216,12 @@ static time_t windows_filetime_to_posix_time(const FILETIME& ft)
 #ifdef KWSYS_WINDOWS_DIRS
 #include <wctype.h>
 
-inline int Mkdir(const kwsys_stl::string& dir)
+inline int Mkdir(const std::string& dir)
 {
   return _wmkdir(
     KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
 }
-inline int Rmdir(const kwsys_stl::string& dir)
+inline int Rmdir(const std::string& dir)
 {
   return _wrmdir(
     KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
@@ -242,7 +242,7 @@ inline const char* Getcwd(char* buf, unsigned int len)
     }
   return 0;
 }
-inline int Chdir(const kwsys_stl::string& dir)
+inline int Chdir(const std::string& dir)
 {
   #if defined(__BORLANDC__)
   return chdir(dir.c_str());
@@ -250,11 +250,11 @@ inline int Chdir(const kwsys_stl::string& dir)
   return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
   #endif
 }
-inline void Realpath(const kwsys_stl::string& path,
-                     kwsys_stl::string& resolved_path,
-                     kwsys_stl::string* errorMessage = 0)
+inline void Realpath(const std::string& path,
+                     std::string& resolved_path,
+                     std::string* errorMessage = 0)
 {
-  kwsys_stl::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path);
+  std::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path);
   wchar_t *ptemp;
   wchar_t fullpath[MAX_PATH];
   DWORD bufferLen = GetFullPathNameW(tmp.c_str(),
@@ -299,11 +299,11 @@ inline void Realpath(const kwsys_stl::string& path,
 #include <sys/types.h>
 #include <fcntl.h>
 #include <unistd.h>
-inline int Mkdir(const kwsys_stl::string& dir)
+inline int Mkdir(const std::string& dir)
 {
   return mkdir(dir.c_str(), 00777);
 }
-inline int Rmdir(const kwsys_stl::string& dir)
+inline int Rmdir(const std::string& dir)
 {
   return rmdir(dir.c_str());
 }
@@ -312,13 +312,13 @@ inline const char* Getcwd(char* buf, unsigned int len)
   return getcwd(buf, len);
 }
 
-inline int Chdir(const kwsys_stl::string& dir)
+inline int Chdir(const std::string& dir)
 {
   return chdir(dir.c_str());
 }
-inline void Realpath(const kwsys_stl::string& path,
-                     kwsys_stl::string& resolved_path,
-                     kwsys_stl::string* errorMessage = 0)
+inline void Realpath(const std::string& path,
+                     std::string& resolved_path,
+                     std::string* errorMessage = 0)
 {
   char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH];
 
@@ -381,13 +381,34 @@ double SystemTools::GetTime(void)
 }
 
 class SystemToolsTranslationMap :
-    public kwsys_stl::map<kwsys_stl::string,kwsys_stl::string>
+    public std::map<std::string,std::string>
+{
+};
+
+#ifdef _WIN32
+struct SystemToolsPathCaseCmp
 {
+  bool operator()(std::string const& l, std::string const& r) const
+    {
+# ifdef _MSC_VER
+    return _stricmp(l.c_str(), r.c_str()) < 0;
+# elif defined(__GNUC__)
+    return strcasecmp(l.c_str(), r.c_str()) < 0;
+# else
+    return SystemTools::Strucmp(l.c_str(), r.c_str()) < 0;
+# endif
+    }
 };
 
+class SystemToolsPathCaseMap:
+  public std::map<std::string, std::string,
+                        SystemToolsPathCaseCmp> {};
+#endif
+
 // adds the elements of the env variable path to the arg passed in
-void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char* env)
+void SystemTools::GetPath(std::vector<std::string>& path, const char* env)
 {
+  size_t const old_size = path.size();
 #if defined(_WIN32) && !defined(__CYGWIN__)
   const char pathSep = ';';
 #else
@@ -403,19 +424,19 @@ void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char
     return;
     }
 
-  kwsys_stl::string pathEnv = cpathEnv;
+  std::string pathEnv = cpathEnv;
 
   // A hack to make the below algorithm work.
   if(!pathEnv.empty() && *pathEnv.rbegin() != pathSep)
     {
     pathEnv += pathSep;
     }
-  kwsys_stl::string::size_type start =0;
+  std::string::size_type start =0;
   bool done = false;
   while(!done)
     {
-    kwsys_stl::string::size_type endpos = pathEnv.find(pathSep, start);
-    if(endpos != kwsys_stl::string::npos)
+    std::string::size_type endpos = pathEnv.find(pathSep, start);
+    if(endpos != std::string::npos)
       {
       path.push_back(pathEnv.substr(start, endpos-start));
       start = endpos+1;
@@ -425,7 +446,7 @@ void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char
       done = true;
       }
     }
-  for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+  for(std::vector<std::string>::iterator i = path.begin() + old_size;
       i != path.end(); ++i)
     {
     SystemTools::ConvertToUnixSlashes(*i);
@@ -437,12 +458,12 @@ const char* SystemTools::GetEnv(const char* key)
   return getenv(key);
 }
 
-const char* SystemTools::GetEnv(const kwsys_stl::string& key)
+const char* SystemTools::GetEnv(const std::string& key)
 {
   return SystemTools::GetEnv(key.c_str());
 }
 
-bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result)
+bool SystemTools::GetEnv(const char* key, std::string& result)
 {
   const char* v = getenv(key);
   if(v)
@@ -456,7 +477,7 @@ bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result)
     }
 }
 
-bool SystemTools::GetEnv(const kwsys_stl::string& key, kwsys_stl::string& result)
+bool SystemTools::GetEnv(const std::string& key, std::string& result)
 {
   return SystemTools::GetEnv(key.c_str(), result);
 }
@@ -472,7 +493,7 @@ bool SystemTools::GetEnv(const kwsys_stl::string& key, kwsys_stl::string& result
 #if KWSYS_CXX_HAS_UNSETENV
 /* unsetenv("A") removes A from the environment.
    On older platforms it returns void instead of int.  */
-static int kwsysUnPutEnv(const kwsys_stl::string& env)
+static int kwsysUnPutEnv(const std::string& env)
 {
   size_t pos = env.find('=');
   if(pos != env.npos)
@@ -489,7 +510,7 @@ static int kwsysUnPutEnv(const kwsys_stl::string& env)
 
 #elif defined(KWSYS_PUTENV_EMPTY) || defined(KWSYS_PUTENV_NAME)
 /* putenv("A=") or putenv("A") removes A from the environment.  */
-static int kwsysUnPutEnv(const kwsys_stl::string& env)
+static int kwsysUnPutEnv(const std::string& env)
 {
   int err = 0;
   size_t pos = env.find('=');
@@ -534,7 +555,7 @@ static int kwsysUnPutEnv(const kwsys_stl::string& env)
 
 #else
 /* Manipulate the "environ" global directly.  */
-static int kwsysUnPutEnv(const kwsys_stl::string& env)
+static int kwsysUnPutEnv(const std::string& env)
 {
   size_t pos = env.find('=');
   size_t const len = pos == env.npos ? env.size() : pos;
@@ -567,7 +588,7 @@ static int kwsysUnPutEnv(const kwsys_stl::string& env)
 
 /* setenv("A", "B", 1) will set A=B in the environment and makes its
    own copies of the strings.  */
-bool SystemTools::PutEnv(const kwsys_stl::string& env)
+bool SystemTools::PutEnv(const std::string& env)
 {
   size_t pos = env.find('=');
   if(pos != env.npos)
@@ -581,7 +602,7 @@ bool SystemTools::PutEnv(const kwsys_stl::string& env)
     }
 }
 
-bool SystemTools::UnPutEnv(const kwsys_stl::string& env)
+bool SystemTools::UnPutEnv(const std::string& env)
 {
   return kwsysUnPutEnv(env) == 0;
 }
@@ -619,7 +640,7 @@ struct kwsysEnvCompare
     }
 };
 
-class kwsysEnv: public kwsys_stl::set<const char*, kwsysEnvCompare>
+class kwsysEnv: public std::set<const char*, kwsysEnvCompare>
 {
   class Free
   {
@@ -629,7 +650,7 @@ class kwsysEnv: public kwsys_stl::set<const char*, kwsysEnvCompare>
     ~Free() { free(const_cast<char*>(this->Env)); }
   };
 public:
-  typedef kwsys_stl::set<const char*, kwsysEnvCompare> derived;
+  typedef std::set<const char*, kwsysEnvCompare> derived;
   ~kwsysEnv()
     {
     for(derived::iterator i = this->begin(); i != this->end(); ++i)
@@ -667,12 +688,12 @@ public:
 
 static kwsysEnv kwsysEnvInstance;
 
-bool SystemTools::PutEnv(const kwsys_stl::string& env)
+bool SystemTools::PutEnv(const std::string& env)
 {
   return kwsysEnvInstance.Put(env.c_str());
 }
 
-bool SystemTools::UnPutEnv(const kwsys_stl::string& env)
+bool SystemTools::UnPutEnv(const std::string& env)
 {
   return kwsysEnvInstance.UnPut(env.c_str());
 }
@@ -690,7 +711,7 @@ const char* SystemTools::GetExecutableExtension()
 #endif
 }
 
-FILE* SystemTools::Fopen(const kwsys_stl::string& file, const char* mode)
+FILE* SystemTools::Fopen(const std::string& file, const char* mode)
 {
 #ifdef _WIN32
   return _wfopen(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
@@ -706,10 +727,10 @@ bool SystemTools::MakeDirectory(const char* path)
     {
     return false;
     }
-  return SystemTools::MakeDirectory(kwsys_stl::string(path));
+  return SystemTools::MakeDirectory(std::string(path));
 }
 
-bool SystemTools::MakeDirectory(const kwsys_stl::string& path)
+bool SystemTools::MakeDirectory(const std::string& path)
 {
   if(SystemTools::FileExists(path))
     {
@@ -719,12 +740,12 @@ bool SystemTools::MakeDirectory(const kwsys_stl::string& path)
     {
     return false;
     }
-  kwsys_stl::string dir = path;
+  std::string dir = path;
   SystemTools::ConvertToUnixSlashes(dir);
 
-  kwsys_stl::string::size_type pos = 0;
-  kwsys_stl::string topdir;
-  while((pos = dir.find('/', pos)) != kwsys_stl::string::npos)
+  std::string::size_type pos = 0;
+  std::string topdir;
+  while((pos = dir.find('/', pos)) != std::string::npos)
     {
     topdir = dir.substr(0, pos);
     Mkdir(topdir);
@@ -752,9 +773,9 @@ bool SystemTools::MakeDirectory(const kwsys_stl::string& path)
 
 // replace replace with with as many times as it shows up in source.
 // write the result into source.
-void SystemTools::ReplaceString(kwsys_stl::string& source,
-                                const kwsys_stl::string& replace,
-                                const kwsys_stl::string& with)
+void SystemTools::ReplaceString(std::string& source,
+                                const std::string& replace,
+                                const std::string& with)
 {
   // do while hangs if replaceSize is 0
   if (replace.empty())
@@ -765,7 +786,7 @@ void SystemTools::ReplaceString(kwsys_stl::string& source,
   SystemTools::ReplaceString(source, replace.c_str(), replace.size(), with);
 }
 
-void SystemTools::ReplaceString(kwsys_stl::string& source,
+void SystemTools::ReplaceString(std::string& source,
                                 const char* replace,
                                 const char* with)
 {
@@ -778,10 +799,10 @@ void SystemTools::ReplaceString(kwsys_stl::string& source,
   SystemTools::ReplaceString(source, replace, strlen(replace), with ? with : "");
 }
 
-void SystemTools::ReplaceString(kwsys_stl::string& source,
+void SystemTools::ReplaceString(std::string& source,
                                 const char* replace,
                                 size_t replaceSize,
-                                const kwsys_stl::string& with)
+                                const std::string& with)
 {
   const char *src = source.c_str();
   char *searchPos = const_cast<char *>(strstr(src,replace));
@@ -824,21 +845,21 @@ void SystemTools::ReplaceString(kwsys_stl::string& source,
 #endif
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-static bool SystemToolsParseRegistryKey(const kwsys_stl::string& key,
+static bool SystemToolsParseRegistryKey(const std::string& key,
                                         HKEY& primaryKey,
-                                        kwsys_stl::string& second,
-                                        kwsys_stl::string& valuename)
+                                        std::string& second,
+                                        std::string& valuename)
 {
-  kwsys_stl::string primary = key;
+  std::string primary = key;
 
   size_t start = primary.find('\\');
-  if (start == kwsys_stl::string::npos)
+  if (start == std::string::npos)
     {
     return false;
     }
 
   size_t valuenamepos = primary.find(';');
-  if (valuenamepos != kwsys_stl::string::npos)
+  if (valuenamepos != std::string::npos)
     {
     valuename = primary.substr(valuenamepos+1);
     }
@@ -895,13 +916,13 @@ static DWORD SystemToolsMakeRegistryMode(DWORD mode,
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
 bool
-SystemTools::GetRegistrySubKeys(const kwsys_stl::string& key,
-                                kwsys_stl::vector<kwsys_stl::string>& subkeys,
+SystemTools::GetRegistrySubKeys(const std::string& key,
+                                std::vector<std::string>& subkeys,
                                 KeyWOW64 view)
 {
   HKEY primaryKey = HKEY_CURRENT_USER;
-  kwsys_stl::string second;
-  kwsys_stl::string valuename;
+  std::string second;
+  std::string valuename;
   if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename))
     {
     return false;
@@ -934,8 +955,8 @@ SystemTools::GetRegistrySubKeys(const kwsys_stl::string& key,
   return true;
 }
 #else
-bool SystemTools::GetRegistrySubKeys(const kwsys_stl::string&,
-                                     kwsys_stl::vector<kwsys_stl::string>&,
+bool SystemTools::GetRegistrySubKeys(const std::string&,
+                                     std::vector<std::string>&,
                                      KeyWOW64)
 {
   return false;
@@ -950,13 +971,13 @@ bool SystemTools::GetRegistrySubKeys(const kwsys_stl::string&,
 //      =>  will return the data of the "Root" value of the key
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::ReadRegistryValue(const kwsys_stl::string& key, kwsys_stl::string &value,
+bool SystemTools::ReadRegistryValue(const std::string& key, std::string &value,
                                     KeyWOW64 view)
 {
   bool valueset = false;
   HKEY primaryKey = HKEY_CURRENT_USER;
-  kwsys_stl::string second;
-  kwsys_stl::string valuename;
+  std::string second;
+  std::string valuename;
   if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename))
     {
     return false;
@@ -1007,7 +1028,7 @@ bool SystemTools::ReadRegistryValue(const kwsys_stl::string& key, kwsys_stl::str
   return valueset;
 }
 #else
-bool SystemTools::ReadRegistryValue(const kwsys_stl::string&, kwsys_stl::string &,
+bool SystemTools::ReadRegistryValue(const std::string&, std::string &,
                                     KeyWOW64)
 {
   return false;
@@ -1023,13 +1044,13 @@ bool SystemTools::ReadRegistryValue(const kwsys_stl::string&, kwsys_stl::string
 //      =>  will set the data of the "Root" value of the key
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::WriteRegistryValue(const kwsys_stl::string& key,
-                                     const kwsys_stl::string& value,
+bool SystemTools::WriteRegistryValue(const std::string& key,
+                                     const std::string& value,
                                      KeyWOW64 view)
 {
   HKEY primaryKey = HKEY_CURRENT_USER;
-  kwsys_stl::string second;
-  kwsys_stl::string valuename;
+  std::string second;
+  std::string valuename;
   if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename))
     {
     return false;
@@ -1064,7 +1085,7 @@ bool SystemTools::WriteRegistryValue(const kwsys_stl::string& key,
   return false;
 }
 #else
-bool SystemTools::WriteRegistryValue(const kwsys_stl::string&, const kwsys_stl::string&, KeyWOW64)
+bool SystemTools::WriteRegistryValue(const std::string&, const std::string&, KeyWOW64)
 {
   return false;
 }
@@ -1078,11 +1099,11 @@ bool SystemTools::WriteRegistryValue(const kwsys_stl::string&, const kwsys_stl::
 //      =>  will delete  the data of the "Root" value of the key
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::DeleteRegistryValue(const kwsys_stl::string& key, KeyWOW64 view)
+bool SystemTools::DeleteRegistryValue(const std::string& key, KeyWOW64 view)
 {
   HKEY primaryKey = HKEY_CURRENT_USER;
-  kwsys_stl::string second;
-  kwsys_stl::string valuename;
+  std::string second;
+  std::string valuename;
   if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename))
     {
     return false;
@@ -1109,13 +1130,13 @@ bool SystemTools::DeleteRegistryValue(const kwsys_stl::string& key, KeyWOW64 vie
   return false;
 }
 #else
-bool SystemTools::DeleteRegistryValue(const kwsys_stl::string&, KeyWOW64)
+bool SystemTools::DeleteRegistryValue(const std::string&, KeyWOW64)
 {
   return false;
 }
 #endif
 
-bool SystemTools::SameFile(const kwsys_stl::string& file1, const kwsys_stl::string& file2)
+bool SystemTools::SameFile(const std::string& file1, const std::string& file2)
 {
 #ifdef _WIN32
   HANDLE hFile1, hFile2;
@@ -1183,11 +1204,11 @@ bool SystemTools::FileExists(const char* filename)
     {
     return false;
     }
-  return SystemTools::FileExists(kwsys_stl::string(filename));
+  return SystemTools::FileExists(std::string(filename));
 }
 
 //----------------------------------------------------------------------------
-bool SystemTools::FileExists(const kwsys_stl::string& filename)
+bool SystemTools::FileExists(const std::string& filename)
 {
   if(filename.empty())
     {
@@ -1213,17 +1234,15 @@ bool SystemTools::FileExists(const kwsys_stl::string& filename)
 //----------------------------------------------------------------------------
 bool SystemTools::FileExists(const char* filename, bool isFile)
 {
-  if(SystemTools::FileExists(filename))
+  if(!filename)
     {
-    // If isFile is set return not FileIsDirectory,
-    // so this will only be true if it is a file
-    return !isFile || !SystemTools::FileIsDirectory(filename);
+    return false;
     }
-  return false;
+  return SystemTools::FileExists(std::string(filename), isFile);
 }
 
 //----------------------------------------------------------------------------
-bool SystemTools::FileExists(const kwsys_stl::string& filename, bool isFile)
+bool SystemTools::FileExists(const std::string& filename, bool isFile)
 {
   if(SystemTools::FileExists(filename))
     {
@@ -1235,6 +1254,43 @@ bool SystemTools::FileExists(const kwsys_stl::string& filename, bool isFile)
 }
 
 //----------------------------------------------------------------------------
+bool SystemTools::TestFileAccess(const char* filename,
+                                 TestFilePermissions permissions)
+{
+  if(!filename)
+    {
+    return false;
+    }
+  return SystemTools::TestFileAccess(std::string(filename),
+                                     permissions);
+}
+
+//----------------------------------------------------------------------------
+bool SystemTools::TestFileAccess(const std::string& filename,
+                                 TestFilePermissions permissions)
+{
+  if(filename.empty())
+    {
+    return false;
+    }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  // If execute set, change to read permission (all files on Windows
+  // are executable if they are readable).  The CRT will always fail
+  // if you pass an execute bit.
+  if(permissions & TEST_FILE_EXECUTE)
+    {
+    permissions &= ~TEST_FILE_EXECUTE;
+    permissions |= TEST_FILE_READ;
+    }
+  return _waccess(
+    SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+    permissions) == 0;
+#else
+  return access(filename.c_str(), permissions) == 0;
+#endif
+}
+
+//----------------------------------------------------------------------------
 #ifdef __CYGWIN__
 bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
 {
@@ -1258,7 +1314,7 @@ bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
 }
 #endif
 
-bool SystemTools::Touch(const kwsys_stl::string& filename, bool create)
+bool SystemTools::Touch(const std::string& filename, bool create)
 {
   if (!SystemTools::FileExists(filename))
     {
@@ -1334,8 +1390,8 @@ bool SystemTools::Touch(const kwsys_stl::string& filename, bool create)
   return true;
 }
 
-bool SystemTools::FileTimeCompare(const kwsys_stl::string& f1,
-                                  const kwsys_stl::string& f2,
+bool SystemTools::FileTimeCompare(const std::string& f1,
+                                  const std::string& f2,
                                   int* result)
 {
   // Default to same time.
@@ -1407,26 +1463,26 @@ bool SystemTools::FileTimeCompare(const kwsys_stl::string& f1,
 
 // Return a capitalized string (i.e the first letter is uppercased, all other
 // are lowercased)
-kwsys_stl::string SystemTools::Capitalized(const kwsys_stl::string& s)
+std::string SystemTools::Capitalized(const std::string& s)
 {
-  kwsys_stl::string n;
+  std::string n;
   if(s.empty())
     {
     return n;
     }
   n.resize(s.size());
-  n[0] = static_cast<kwsys_stl::string::value_type>(toupper(s[0]));
+  n[0] = static_cast<std::string::value_type>(toupper(s[0]));
   for (size_t i = 1; i < s.size(); i++)
     {
-    n[i] = static_cast<kwsys_stl::string::value_type>(tolower(s[i]));
+    n[i] = static_cast<std::string::value_type>(tolower(s[i]));
     }
   return n;
 }
 
 // Return capitalized words
-kwsys_stl::string SystemTools::CapitalizedWords(const kwsys_stl::string& s)
+std::string SystemTools::CapitalizedWords(const std::string& s)
 {
-  kwsys_stl::string n(s);
+  std::string n(s);
   for (size_t i = 0; i < s.size(); i++)
     {
 #if defined(_MSC_VER) && defined (_MT) && defined (_DEBUG)
@@ -1438,16 +1494,16 @@ kwsys_stl::string SystemTools::CapitalizedWords(const kwsys_stl::string& s)
     if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1])))
 #endif
       {
-      n[i] = static_cast<kwsys_stl::string::value_type>(toupper(s[i]));
+      n[i] = static_cast<std::string::value_type>(toupper(s[i]));
       }
     }
   return n;
 }
 
 // Return uncapitalized words
-kwsys_stl::string SystemTools::UnCapitalizedWords(const kwsys_stl::string& s)
+std::string SystemTools::UnCapitalizedWords(const std::string& s)
 {
-  kwsys_stl::string n(s);
+  std::string n(s);
   for (size_t i = 0; i < s.size(); i++)
     {
 #if defined(_MSC_VER) && defined (_MT) && defined (_DEBUG)
@@ -1459,17 +1515,17 @@ kwsys_stl::string SystemTools::UnCapitalizedWords(const kwsys_stl::string& s)
     if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1])))
 #endif
       {
-      n[i] = static_cast<kwsys_stl::string::value_type>(tolower(s[i]));
+      n[i] = static_cast<std::string::value_type>(tolower(s[i]));
       }
     }
   return n;
 }
 
 // only works for words with at least two letters
-kwsys_stl::string SystemTools::AddSpaceBetweenCapitalizedWords(
-  const kwsys_stl::string& s)
+std::string SystemTools::AddSpaceBetweenCapitalizedWords(
+  const std::string& s)
 {
-  kwsys_stl::string n;
+  std::string n;
   if (!s.empty())
     {
     n.reserve(s.size());
@@ -1536,25 +1592,25 @@ char* SystemTools::AppendStrings(
 }
 
 // Return a lower case string
-kwsys_stl::string SystemTools::LowerCase(const kwsys_stl::string& s)
+std::string SystemTools::LowerCase(const std::string& s)
 {
-  kwsys_stl::string n;
+  std::string n;
   n.resize(s.size());
   for (size_t i = 0; i < s.size(); i++)
     {
-    n[i] = static_cast<kwsys_stl::string::value_type>(tolower(s[i]));
+    n[i] = static_cast<std::string::value_type>(tolower(s[i]));
     }
   return n;
 }
 
 // Return a lower case string
-kwsys_stl::string SystemTools::UpperCase(const kwsys_stl::string& s)
+std::string SystemTools::UpperCase(const std::string& s)
 {
-  kwsys_stl::string n;
+  std::string n;
   n.resize(s.size());
   for (size_t i = 0; i < s.size(); i++)
     {
-    n[i] = static_cast<kwsys_stl::string::value_type>(toupper(s[i]));
+    n[i] = static_cast<std::string::value_type>(toupper(s[i]));
     }
   return n;
 }
@@ -1660,7 +1716,7 @@ bool SystemTools::StringStartsWith(const char* str1, const char* str2)
 }
 
 // Returns if string starts with another string
-bool SystemTools::StringStartsWith(const kwsys_stl::string& str1, const char* str2)
+bool SystemTools::StringStartsWith(const std::string& str1, const char* str2)
 {
   if (!str2)
     {
@@ -1682,7 +1738,7 @@ bool SystemTools::StringEndsWith(const char* str1, const char* str2)
 }
 
 // Returns if string ends with another string
-bool SystemTools::StringEndsWith(const kwsys_stl::string& str1, const char* str2)
+bool SystemTools::StringEndsWith(const std::string& str1, const char* str2)
 {
   if (!str2)
     {
@@ -1728,7 +1784,7 @@ char* SystemTools::DuplicateString(const char* str)
 }
 
 // Return a cropped string
-kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
+std::string SystemTools::CropString(const std::string& s,
                                           size_t max_len)
 {
   if (!s.size() || max_len == 0 || max_len >= s.size())
@@ -1736,13 +1792,13 @@ kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
     return s;
     }
 
-  kwsys_stl::string n;
+  std::string n;
   n.reserve(max_len);
 
   size_t middle = max_len / 2;
 
   n += s.substr(0, middle);
-  n += s.substr(s.size() - (max_len - middle), kwsys_stl::string::npos);
+  n += s.substr(s.size() - (max_len - middle), std::string::npos);
 
   if (max_len > 2)
     {
@@ -1761,10 +1817,10 @@ kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
 }
 
 //----------------------------------------------------------------------------
-kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const kwsys_stl::string& p, char sep, bool isPath)
+std::vector<kwsys::String> SystemTools::SplitString(const std::string& p, char sep, bool isPath)
 {
-  kwsys_stl::string path = p;
-  kwsys_stl::vector<kwsys::String> paths;
+  std::string path = p;
+  std::vector<kwsys::String> paths;
   if(path.empty())
     {
     return paths;
@@ -1774,9 +1830,9 @@ kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const kwsys_stl::strin
     path.erase(path.begin());
     paths.push_back("/");
     }
-  kwsys_stl::string::size_type pos1 = 0;
-  kwsys_stl::string::size_type pos2 = path.find(sep, pos1+1);
-  while(pos2 != kwsys_stl::string::npos)
+  std::string::size_type pos1 = 0;
+  std::string::size_type pos2 = path.find(sep, pos1+1);
+  while(pos2 != std::string::npos)
     {
     paths.push_back(path.substr(pos1, pos2-pos1));
     pos1 = pos2+1;
@@ -1856,12 +1912,12 @@ int SystemTools::EstimateFormatLength(const char *format, va_list ap)
   return static_cast<int>(length);
 }
 
-kwsys_stl::string SystemTools::EscapeChars(
+std::string SystemTools::EscapeChars(
   const char *str,
   const char *chars_to_escape,
   char escape_char)
 {
-  kwsys_stl::string n;
+  std::string n;
   if (str)
     {
     if (!chars_to_escape || !*chars_to_escape)
@@ -1892,17 +1948,17 @@ kwsys_stl::string SystemTools::EscapeChars(
 }
 
 #ifdef __VMS
-static void ConvertVMSToUnix(kwsys_stl::string& path)
+static void ConvertVMSToUnix(std::string& path)
 {
-  kwsys_stl::string::size_type rootEnd = path.find(":[");
-  kwsys_stl::string::size_type pathEnd = path.find("]");
+  std::string::size_type rootEnd = path.find(":[");
+  std::string::size_type pathEnd = path.find("]");
   if(rootEnd != path.npos)
     {
-    kwsys_stl::string root = path.substr(0, rootEnd);
-    kwsys_stl::string pathPart = path.substr(rootEnd+2, pathEnd - rootEnd-2);
+    std::string root = path.substr(0, rootEnd);
+    std::string pathPart = path.substr(rootEnd+2, pathEnd - rootEnd-2);
     const char* pathCString = pathPart.c_str();
     const char* pos0 = pathCString;
-    for (kwsys_stl::string::size_type pos = 0; *pos0; ++ pos )
+    for (std::string::size_type pos = 0; *pos0; ++ pos )
       {
       if ( *pos0 == '.' )
         {
@@ -1916,7 +1972,7 @@ static void ConvertVMSToUnix(kwsys_stl::string& path)
 #endif
 
 // convert windows slashes to unix slashes
-void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
+void SystemTools::ConvertToUnixSlashes(std::string& path)
 {
   const char* pathCString = path.c_str();
   bool hasDoubleSlash = false;
@@ -1925,7 +1981,7 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
 #else
   const char* pos0 = pathCString;
   const char* pos1 = pathCString+1;
-  for (kwsys_stl::string::size_type pos = 0; *pos0; ++ pos )
+  for (std::string::size_type pos = 0; *pos0; ++ pos )
     {
     // make sure we don't convert an escaped space to a unix slash
     if ( *pos0 == '\\' && *pos1 != ' ' )
@@ -1973,8 +2029,8 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
 #ifdef HAVE_GETPWNAM
     else if(pathCString[0] == '~')
       {
-      kwsys_stl::string::size_type idx = path.find_first_of("/\0");
-      kwsys_stl::string user = path.substr(1, idx-1);
+      std::string::size_type idx = path.find_first_of("/\0");
+      std::string user = path.substr(1, idx-1);
       passwd* pw = getpwnam(user.c_str());
       if(pw)
         {
@@ -1999,10 +2055,10 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
 
 #ifdef _WIN32
 // Convert local paths to UNC style paths
-kwsys_stl::wstring
-SystemTools::ConvertToWindowsExtendedPath(const kwsys_stl::string &source)
+std::wstring
+SystemTools::ConvertToWindowsExtendedPath(const std::string &source)
 {
-  kwsys_stl::wstring wsource = Encoding::ToWide(source);
+  std::wstring wsource = Encoding::ToWide(source);
 
   // Resolve any relative paths
   DWORD wfull_len;
@@ -2010,7 +2066,7 @@ SystemTools::ConvertToWindowsExtendedPath(const kwsys_stl::string &source)
   /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
    * won't return a large enough buffer size if the input is too small */
   wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
-  kwsys_stl::vector<wchar_t> wfull(wfull_len);
+  std::vector<wchar_t> wfull(wfull_len);
   GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
 
   /* This should get the correct size without any extra padding from the
@@ -2019,7 +2075,7 @@ SystemTools::ConvertToWindowsExtendedPath(const kwsys_stl::string &source)
 
   if(wfull_len >= 2 && isalpha(wfull[0]) && wfull[1] == L':')
     { /* C:\Foo\bar\FooBar.txt */
-    return L"\\\\?\\" + kwsys_stl::wstring(&wfull[0]);
+    return L"\\\\?\\" + std::wstring(&wfull[0]);
     }
   else if(wfull_len >= 2 && wfull[0] == L'\\' && wfull[1] == L'\\')
     { /* Starts with \\ */
@@ -2028,31 +2084,31 @@ SystemTools::ConvertToWindowsExtendedPath(const kwsys_stl::string &source)
       if(wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' &&
                            wfull[6] == L'C' && wfull[7] == L'\\')
         { /* \\?\UNC\Foo\bar\FooBar.txt */
-        return kwsys_stl::wstring(&wfull[0]);
+        return std::wstring(&wfull[0]);
         }
       else if(wfull_len >= 6 && isalpha(wfull[4]) && wfull[5] == L':')
         { /* \\?\C:\Foo\bar\FooBar.txt */
-        return kwsys_stl::wstring(&wfull[0]);
+        return std::wstring(&wfull[0]);
         }
       else if(wfull_len >= 5)
         { /* \\?\Foo\bar\FooBar.txt */
-        return L"\\\\?\\UNC\\" + kwsys_stl::wstring(&wfull[4]);
+        return L"\\\\?\\UNC\\" + std::wstring(&wfull[4]);
         }
       }
     else if(wfull_len >= 4 && wfull[2] == L'.' && wfull[3] == L'\\')
       { /* Starts with \\.\ a device name */
       if(wfull_len >= 6 && isalpha(wfull[4]) && wfull[5] == L':')
         { /* \\.\C:\Foo\bar\FooBar.txt */
-        return L"\\\\?\\" + kwsys_stl::wstring(&wfull[4]);
+        return L"\\\\?\\" + std::wstring(&wfull[4]);
         }
       else if(wfull_len >= 5)
         { /* \\.\Foo\bar\ Device name is left unchanged */
-        return kwsys_stl::wstring(&wfull[0]);
+        return std::wstring(&wfull[0]);
         }
       }
     else if(wfull_len >= 3)
       { /* \\Foo\bar\FooBar.txt */
-      return L"\\\\?\\UNC\\" + kwsys_stl::wstring(&wfull[2]);
+      return L"\\\\?\\UNC\\" + std::wstring(&wfull[2]);
       }
     }
 
@@ -2063,20 +2119,20 @@ SystemTools::ConvertToWindowsExtendedPath(const kwsys_stl::string &source)
 #endif
 
 // change // to /, and escape any spaces in the path
-kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const kwsys_stl::string& path)
+std::string SystemTools::ConvertToUnixOutputPath(const std::string& path)
 {
-  kwsys_stl::string ret = path;
+  std::string ret = path;
 
   // remove // except at the beginning might be a cygwin drive
-  kwsys_stl::string::size_type pos=1;
-  while((pos = ret.find("//", pos)) != kwsys_stl::string::npos)
+  std::string::size_type pos=1;
+  while((pos = ret.find("//", pos)) != std::string::npos)
     {
     ret.erase(pos, 1);
     }
   // escape spaces and () in the path
-  if(ret.find_first_of(" ") != kwsys_stl::string::npos)
+  if(ret.find_first_of(" ") != std::string::npos)
     {
-    kwsys_stl::string result = "";
+    std::string result = "";
     char lastch = 1;
     for(const char* ch = ret.c_str(); *ch != '\0'; ++ch)
       {
@@ -2093,7 +2149,7 @@ kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const kwsys_stl::string&
   return ret;
 }
 
-kwsys_stl::string SystemTools::ConvertToOutputPath(const kwsys_stl::string& path)
+std::string SystemTools::ConvertToOutputPath(const std::string& path)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   return SystemTools::ConvertToWindowsOutputPath(path);
@@ -2103,16 +2159,16 @@ kwsys_stl::string SystemTools::ConvertToOutputPath(const kwsys_stl::string& path
 }
 
 // remove double slashes not at the start
-kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const kwsys_stl::string& path)
+std::string SystemTools::ConvertToWindowsOutputPath(const std::string& path)
 {
-  kwsys_stl::string ret;
+  std::string ret;
   // make it big enough for all of path and double quotes
   ret.reserve(path.size()+3);
   // put path into the string
   ret = path;
-  kwsys_stl::string::size_type pos = 0;
+  std::string::size_type pos = 0;
   // first convert all of the slashes
-  while((pos = ret.find('/', pos)) != kwsys_stl::string::npos)
+  while((pos = ret.find('/', pos)) != std::string::npos)
     {
     ret[pos] = '\\';
     pos++;
@@ -2134,33 +2190,33 @@ kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const kwsys_stl::strin
       return ret;
       }
     }
-  while((pos = ret.find("\\\\", pos)) != kwsys_stl::string::npos)
+  while((pos = ret.find("\\\\", pos)) != std::string::npos)
     {
     ret.erase(pos, 1);
     }
   // now double quote the path if it has spaces in it
   // and is not already double quoted
-  if(ret.find(' ') != kwsys_stl::string::npos
+  if(ret.find(' ') != std::string::npos
      && ret[0] != '\"')
     {
-    ret.insert(static_cast<kwsys_stl::string::size_type>(0),
-               static_cast<kwsys_stl::string::size_type>(1), '\"');
+    ret.insert(static_cast<std::string::size_type>(0),
+               static_cast<std::string::size_type>(1), '\"');
     ret.append(1, '\"');
     }
   return ret;
 }
 
-bool SystemTools::CopyFileIfDifferent(const kwsys_stl::string& source,
-                                      const kwsys_stl::string& destination)
+bool SystemTools::CopyFileIfDifferent(const std::string& source,
+                                      const std::string& destination)
 {
   // special check for a destination that is a directory
   // FilesDiffer does not handle file to directory compare
   if(SystemTools::FileIsDirectory(destination))
     {
-    kwsys_stl::string new_destination = destination;
+    std::string new_destination = destination;
     SystemTools::ConvertToUnixSlashes(new_destination);
     new_destination += '/';
-    kwsys_stl::string source_name = source;
+    std::string source_name = source;
     new_destination += SystemTools::GetFilenameName(source_name);
     if(SystemTools::FilesDiffer(source, new_destination))
       {
@@ -2185,8 +2241,8 @@ bool SystemTools::CopyFileIfDifferent(const kwsys_stl::string& source,
 
 #define KWSYS_ST_BUFFER 4096
 
-bool SystemTools::FilesDiffer(const kwsys_stl::string& source,
-                              const kwsys_stl::string& destination)
+bool SystemTools::FilesDiffer(const std::string& source,
+                              const std::string& destination)
 {
 
 #if defined(_WIN32)
@@ -2249,11 +2305,11 @@ bool SystemTools::FilesDiffer(const kwsys_stl::string& source,
 
 #if defined(_WIN32)
   kwsys::ifstream finSource(source.c_str(),
-                            (kwsys_ios::ios::binary |
-                             kwsys_ios::ios::in));
+                            (std::ios::binary |
+                             std::ios::in));
   kwsys::ifstream finDestination(destination.c_str(),
-                                 (kwsys_ios::ios::binary |
-                                  kwsys_ios::ios::in));
+                                 (std::ios::binary |
+                                  std::ios::in));
 #else
   kwsys::ifstream finSource(source.c_str());
   kwsys::ifstream finDestination(destination.c_str());
@@ -2269,13 +2325,13 @@ bool SystemTools::FilesDiffer(const kwsys_stl::string& source,
   while(nleft > 0)
     {
     // Read a block from each file.
-    kwsys_ios::streamsize nnext = (nleft > KWSYS_ST_BUFFER)? KWSYS_ST_BUFFER : static_cast<kwsys_ios::streamsize>(nleft);
+    std::streamsize nnext = (nleft > KWSYS_ST_BUFFER)? KWSYS_ST_BUFFER : static_cast<std::streamsize>(nleft);
     finSource.read(source_buf, nnext);
     finDestination.read(dest_buf, nnext);
 
     // If either failed to read assume they are different.
-    if(static_cast<kwsys_ios::streamsize>(finSource.gcount()) != nnext ||
-       static_cast<kwsys_ios::streamsize>(finDestination.gcount()) != nnext)
+    if(static_cast<std::streamsize>(finSource.gcount()) != nnext ||
+       static_cast<std::streamsize>(finDestination.gcount()) != nnext)
       {
       return true;
       }
@@ -2301,7 +2357,7 @@ bool SystemTools::FilesDiffer(const kwsys_stl::string& source,
 /**
  * Copy a file named by "source" to the file named by "destination".
  */
-bool SystemTools::CopyFileAlways(const kwsys_stl::string& source, const kwsys_stl::string& destination)
+bool SystemTools::CopyFileAlways(const std::string& source, const std::string& destination)
 {
   // If files are the same do not copy
   if ( SystemTools::SameFile(source, destination) )
@@ -2310,95 +2366,102 @@ bool SystemTools::CopyFileAlways(const kwsys_stl::string& source, const kwsys_st
     }
   mode_t perm = 0;
   bool perms = SystemTools::GetPermissions(source, perm);
+  std::string real_destination = destination;
 
-  const int bufferSize = 4096;
-  char buffer[bufferSize];
-
-  // If destination is a directory, try to create a file with the same
-  // name as the source in that directory.
-
-  kwsys_stl::string real_destination = destination;
-  kwsys_stl::string destination_dir;
-  if(SystemTools::FileExists(destination) &&
-     SystemTools::FileIsDirectory(destination))
+  if(SystemTools::FileIsDirectory(source))
     {
-    destination_dir = real_destination;
-    SystemTools::ConvertToUnixSlashes(real_destination);
-    real_destination += '/';
-    kwsys_stl::string source_name = source;
-    real_destination += SystemTools::GetFilenameName(source_name);
+    SystemTools::MakeDirectory(destination);
     }
   else
     {
-    destination_dir = SystemTools::GetFilenamePath(destination);
-    }
+    const int bufferSize = 4096;
+    char buffer[bufferSize];
+
+    // If destination is a directory, try to create a file with the same
+    // name as the source in that directory.
+
+    std::string destination_dir;
+    if(SystemTools::FileExists(destination) &&
+       SystemTools::FileIsDirectory(destination))
+      {
+      destination_dir = real_destination;
+      SystemTools::ConvertToUnixSlashes(real_destination);
+      real_destination += '/';
+      std::string source_name = source;
+      real_destination += SystemTools::GetFilenameName(source_name);
+      }
+    else
+      {
+      destination_dir = SystemTools::GetFilenamePath(destination);
+      }
 
-  // Create destination directory
+    // Create destination directory
 
-  SystemTools::MakeDirectory(destination_dir);
+    SystemTools::MakeDirectory(destination_dir);
 
-  // Open files
+    // Open files
 #if defined(_WIN32)
-  kwsys::ifstream fin(Encoding::ToNarrow(
-    SystemTools::ConvertToWindowsExtendedPath(source)).c_str(),
-                kwsys_ios::ios::in | kwsys_ios_binary);
+    kwsys::ifstream fin(Encoding::ToNarrow(
+      SystemTools::ConvertToWindowsExtendedPath(source)).c_str(),
+                  std::ios::in | std::ios::binary);
 #else
-  kwsys::ifstream fin(source.c_str(),
-                kwsys_ios::ios::in | kwsys_ios_binary);
+    kwsys::ifstream fin(source.c_str(),
+                  std::ios::in | std::ios::binary);
 #endif
-  if(!fin)
-    {
-    return false;
-    }
+    if(!fin)
+      {
+      return false;
+      }
 
-  // try and remove the destination file so that read only destination files
-  // can be written to.
-  // If the remove fails continue so that files in read only directories
-  // that do not allow file removal can be modified.
-  SystemTools::RemoveFile(real_destination);
+    // try and remove the destination file so that read only destination files
+    // can be written to.
+    // If the remove fails continue so that files in read only directories
+    // that do not allow file removal can be modified.
+    SystemTools::RemoveFile(real_destination);
 
 #if defined(_WIN32)
-  kwsys::ofstream fout(Encoding::ToNarrow(
-    SystemTools::ConvertToWindowsExtendedPath(real_destination)).c_str(),
-                     kwsys_ios::ios::out | kwsys_ios::ios::trunc | kwsys_ios_binary);
+    kwsys::ofstream fout(Encoding::ToNarrow(
+      SystemTools::ConvertToWindowsExtendedPath(real_destination)).c_str(),
+                     std::ios::out | std::ios::trunc | std::ios::binary);
 #else
-  kwsys::ofstream fout(real_destination.c_str(),
-                     kwsys_ios::ios::out | kwsys_ios::ios::trunc | kwsys_ios_binary);
+    kwsys::ofstream fout(real_destination.c_str(),
+                     std::ios::out | std::ios::trunc | std::ios::binary);
 #endif
-  if(!fout)
-    {
-    return false;
-    }
-
-  // This copy loop is very sensitive on certain platforms with
-  // slightly broken stream libraries (like HPUX).  Normally, it is
-  // incorrect to not check the error condition on the fin.read()
-  // before using the data, but the fin.gcount() will be zero if an
-  // error occurred.  Therefore, the loop should be safe everywhere.
-  while(fin)
-    {
-    fin.read(buffer, bufferSize);
-    if(fin.gcount())
+    if(!fout)
       {
-      fout.write(buffer, fin.gcount());
+      return false;
       }
-    else
+
+    // This copy loop is very sensitive on certain platforms with
+    // slightly broken stream libraries (like HPUX).  Normally, it is
+    // incorrect to not check the error condition on the fin.read()
+    // before using the data, but the fin.gcount() will be zero if an
+    // error occurred.  Therefore, the loop should be safe everywhere.
+    while(fin)
       {
-      break;
+      fin.read(buffer, bufferSize);
+      if(fin.gcount())
+        {
+        fout.write(buffer, fin.gcount());
+        }
+      else
+        {
+        break;
+        }
       }
-    }
 
-  // Make sure the operating system has finished writing the file
-  // before closing it.  This will ensure the file is finished before
-  // the check below.
-  fout.flush();
+    // Make sure the operating system has finished writing the file
+    // before closing it.  This will ensure the file is finished before
+    // the check below.
+    fout.flush();
 
-  fin.close();
-  fout.close();
+    fin.close();
+    fout.close();
 
-  if(!fout)
-    {
-    return false;
+    if(!fout)
+      {
+      return false;
+      }
     }
   if ( perms )
     {
@@ -2411,7 +2474,7 @@ bool SystemTools::CopyFileAlways(const kwsys_stl::string& source, const kwsys_st
 }
 
 //----------------------------------------------------------------------------
-bool SystemTools::CopyAFile(const kwsys_stl::string& source, const kwsys_stl::string& destination,
+bool SystemTools::CopyAFile(const std::string& source, const std::string& destination,
                             bool always)
 {
   if(always)
@@ -2428,7 +2491,7 @@ bool SystemTools::CopyAFile(const kwsys_stl::string& source, const kwsys_stl::st
  * Copy a directory content from "source" directory to the directory named by
  * "destination".
  */
-bool SystemTools::CopyADirectory(const kwsys_stl::string& source, const kwsys_stl::string& destination,
+bool SystemTools::CopyADirectory(const std::string& source, const std::string& destination,
                                  bool always)
 {
   Directory dir;
@@ -2448,12 +2511,12 @@ bool SystemTools::CopyADirectory(const kwsys_stl::string& source, const kwsys_st
     if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
         strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".."))
       {
-      kwsys_stl::string fullPath = source;
+      std::string fullPath = source;
       fullPath += "/";
       fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
       if(SystemTools::FileIsDirectory(fullPath))
         {
-        kwsys_stl::string fullDestPath = destination;
+        std::string fullDestPath = destination;
         fullDestPath += "/";
         fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum));
         if (!SystemTools::CopyADirectory(fullPath,
@@ -2478,7 +2541,7 @@ bool SystemTools::CopyADirectory(const kwsys_stl::string& source, const kwsys_st
 
 
 // return size of file; also returns zero if no file exists
-unsigned long SystemTools::FileLength(const kwsys_stl::string& filename)
+unsigned long SystemTools::FileLength(const std::string& filename)
 {
   unsigned long length = 0;
 #ifdef _WIN32
@@ -2518,7 +2581,7 @@ int SystemTools::Strucmp(const char *s1, const char *s2)
 }
 
 // return file's modified time
-long int SystemTools::ModifiedTime(const kwsys_stl::string& filename)
+long int SystemTools::ModifiedTime(const std::string& filename)
 {
   long int mt = 0;
 #ifdef _WIN32
@@ -2541,7 +2604,7 @@ long int SystemTools::ModifiedTime(const kwsys_stl::string& filename)
 }
 
 // return file's creation time
-long int SystemTools::CreationTime(const kwsys_stl::string& filename)
+long int SystemTools::CreationTime(const std::string& filename)
 {
   long int ct = 0;
 #ifdef _WIN32
@@ -2665,16 +2728,16 @@ bool SystemTools::ConvertTimeStampMacroString(const char *str, time_t *tmt)
   return true;
 }
 
-kwsys_stl::string SystemTools::GetLastSystemError()
+std::string SystemTools::GetLastSystemError()
 {
   int e = errno;
   return strerror(e);
 }
 
-bool SystemTools::RemoveFile(const kwsys_stl::string& source)
+bool SystemTools::RemoveFile(const std::string& source)
 {
 #ifdef _WIN32
-  kwsys_stl::wstring const& ws =
+  std::wstring const& ws =
     SystemTools::ConvertToWindowsExtendedPath(source);
   if (DeleteFileW(ws.c_str()))
     {
@@ -2713,7 +2776,7 @@ bool SystemTools::RemoveFile(const kwsys_stl::string& source)
 #endif
 }
 
-bool SystemTools::RemoveADirectory(const kwsys_stl::string& source)
+bool SystemTools::RemoveADirectory(const std::string& source)
 {
   // Add write permission to the directory so we can modify its
   // content to remove files and directories from it.
@@ -2741,7 +2804,7 @@ bool SystemTools::RemoveADirectory(const kwsys_stl::string& source)
     if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
         strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".."))
       {
-      kwsys_stl::string fullPath = source;
+      std::string fullPath = source;
       fullPath += "/";
       fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
       if(SystemTools::FileIsDirectory(fullPath) &&
@@ -2777,13 +2840,13 @@ size_t SystemTools::GetMaximumFilePathLength()
  * the system search path.  Returns the full path to the file if it is
  * found.  Otherwise, the empty string is returned.
  */
-kwsys_stl::string SystemTools
-::FindName(const kwsys_stl::string& name,
-           const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+std::string SystemTools
+::FindName(const std::string& name,
+           const std::vector<std::string>& userPaths,
            bool no_system_path)
 {
   // Add the system search path to our path first
-  kwsys_stl::vector<kwsys_stl::string> path;
+  std::vector<std::string> path;
   if (!no_system_path)
     {
     SystemTools::GetPath(path, "CMAKE_FILE_PATH");
@@ -2791,7 +2854,7 @@ kwsys_stl::string SystemTools
     }
   // now add the additional paths
   {
-  for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = userPaths.begin();
+  for(std::vector<std::string>::const_iterator i = userPaths.begin();
         i != userPaths.end(); ++i)
     {
     path.push_back(*i);
@@ -2799,10 +2862,10 @@ kwsys_stl::string SystemTools
   }
   // Add a trailing slash to all paths to aid the search process.
   {
-  for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+  for(std::vector<std::string>::iterator i = path.begin();
       i != path.end(); ++i)
     {
-    kwsys_stl::string& p = *i;
+    std::string& p = *i;
     if(p.empty() || *p.rbegin() != '/')
       {
       p += "/";
@@ -2810,8 +2873,8 @@ kwsys_stl::string SystemTools
     }
   }
   // now look for the file
-  kwsys_stl::string tryPath;
-  for(kwsys_stl::vector<kwsys_stl::string>::const_iterator p = path.begin();
+  std::string tryPath;
+  for(std::vector<std::string>::const_iterator p = path.begin();
       p != path.end(); ++p)
     {
     tryPath = *p;
@@ -2830,12 +2893,12 @@ kwsys_stl::string SystemTools
  * the system search path.  Returns the full path to the file if it is
  * found.  Otherwise, the empty string is returned.
  */
-kwsys_stl::string SystemTools
-::FindFile(const kwsys_stl::string& name,
-           const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+std::string SystemTools
+::FindFile(const std::string& name,
+           const std::vector<std::string>& userPaths,
            bool no_system_path)
 {
-  kwsys_stl::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
+  std::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
   if(!tryPath.empty() && !SystemTools::FileIsDirectory(tryPath))
     {
     return SystemTools::CollapseFullPath(tryPath);
@@ -2849,12 +2912,12 @@ kwsys_stl::string SystemTools
  * the system search path.  Returns the full path to the directory if it is
  * found.  Otherwise, the empty string is returned.
  */
-kwsys_stl::string SystemTools
-::FindDirectory(const kwsys_stl::string& name,
-                const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+std::string SystemTools
+::FindDirectory(const std::string& name,
+                const std::vector<std::string>& userPaths,
                 bool no_system_path)
 {
-  kwsys_stl::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
+  std::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
   if(!tryPath.empty() && SystemTools::FileIsDirectory(tryPath))
     {
     return SystemTools::CollapseFullPath(tryPath);
@@ -2868,24 +2931,24 @@ kwsys_stl::string SystemTools
  * the system search path.  Returns the full path to the executable if it is
  * found.  Otherwise, the empty string is returned.
  */
-kwsys_stl::string SystemTools::FindProgram(
+std::string SystemTools::FindProgram(
   const char* nameIn,
-  const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+  const std::vector<std::string>& userPaths,
   bool no_system_path)
 {
   if(!nameIn || !*nameIn)
     {
     return "";
     }
-  return SystemTools::FindProgram(kwsys_stl::string(nameIn), userPaths, no_system_path);
+  return SystemTools::FindProgram(std::string(nameIn), userPaths, no_system_path);
 }
 
-kwsys_stl::string SystemTools::FindProgram(
-  const kwsys_stl::string& name,
-  const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+std::string SystemTools::FindProgram(
+  const std::string& name,
+  const std::vector<std::string>& userPaths,
   bool no_system_path)
 {
-  kwsys_stl::vector<kwsys_stl::string> extensions;
+  std::vector<std::string> extensions;
 #if defined (_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
   bool hasExtension = false;
   // check to see if the name already has a .xxx at
@@ -2901,10 +2964,10 @@ kwsys_stl::string SystemTools::FindProgram(
     extensions.push_back(".exe");
     }
 #endif
-  kwsys_stl::string tryPath;
+  std::string tryPath;
 
   // first try with extensions if the os supports them
-  for(kwsys_stl::vector<kwsys_stl::string>::iterator i =
+  for(std::vector<std::string>::iterator i =
         extensions.begin(); i != extensions.end(); ++i)
     {
     tryPath = name;
@@ -2923,7 +2986,7 @@ kwsys_stl::string SystemTools::FindProgram(
     return SystemTools::CollapseFullPath(tryPath);
     }
   // now construct the path
-  kwsys_stl::vector<kwsys_stl::string> path;
+  std::vector<std::string> path;
   // Add the system search path to our path.
   if (!no_system_path)
     {
@@ -2931,7 +2994,7 @@ kwsys_stl::string SystemTools::FindProgram(
     }
   // now add the additional paths
   {
-  for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i =
+  for(std::vector<std::string>::const_iterator i =
         userPaths.begin();  i != userPaths.end(); ++i)
     {
     path.push_back(*i);
@@ -2939,10 +3002,10 @@ kwsys_stl::string SystemTools::FindProgram(
   }
   // Add a trailing slash to all paths to aid the search process.
   {
-  for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+  for(std::vector<std::string>::iterator i = path.begin();
       i != path.end(); ++i)
     {
-    kwsys_stl::string& p = *i;
+    std::string& p = *i;
     if(p.empty() || *p.rbegin() != '/')
       {
       p += "/";
@@ -2950,7 +3013,7 @@ kwsys_stl::string SystemTools::FindProgram(
     }
   }
   // Try each path
-  for(kwsys_stl::vector<kwsys_stl::string>::iterator p = path.begin();
+  for(std::vector<std::string>::iterator p = path.begin();
       p != path.end(); ++p)
     {
 #ifdef _WIN32
@@ -2958,7 +3021,7 @@ kwsys_stl::string SystemTools::FindProgram(
     SystemTools::ReplaceString(*p, "\"", "");
 #endif
     // first try with extensions
-    for(kwsys_stl::vector<kwsys_stl::string>::iterator ext
+    for(std::vector<std::string>::iterator ext
           = extensions.begin(); ext != extensions.end(); ++ext)
       {
       tryPath = *p;
@@ -2983,16 +3046,16 @@ kwsys_stl::string SystemTools::FindProgram(
   return "";
 }
 
-kwsys_stl::string SystemTools::FindProgram(
-  const kwsys_stl::vector<kwsys_stl::string>& names,
-  const kwsys_stl::vector<kwsys_stl::string>& path,
+std::string SystemTools::FindProgram(
+  const std::vector<std::string>& names,
+  const std::vector<std::string>& path,
   bool noSystemPath)
 {
-  for(kwsys_stl::vector<kwsys_stl::string>::const_iterator it = names.begin();
+  for(std::vector<std::string>::const_iterator it = names.begin();
       it != names.end() ; ++it)
     {
     // Try to find the program.
-    kwsys_stl::string result = SystemTools::FindProgram(*it,
+    std::string result = SystemTools::FindProgram(*it,
                                                   path,
                                                   noSystemPath);
     if ( !result.empty() )
@@ -3008,9 +3071,9 @@ kwsys_stl::string SystemTools::FindProgram(
  * the system search path.  Returns the full path to the library if it is
  * found.  Otherwise, the empty string is returned.
  */
-kwsys_stl::string SystemTools
-::FindLibrary(const kwsys_stl::string& name,
-              const kwsys_stl::vector<kwsys_stl::string>& userPaths)
+std::string SystemTools
+::FindLibrary(const std::string& name,
+              const std::vector<std::string>& userPaths)
 {
   // See if the executable exists as written.
   if(SystemTools::FileExists(name) &&
@@ -3020,11 +3083,11 @@ kwsys_stl::string SystemTools
     }
 
   // Add the system search path to our path.
-  kwsys_stl::vector<kwsys_stl::string> path;
+  std::vector<std::string> path;
   SystemTools::GetPath(path);
    // now add the additional paths
   {
-  for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = userPaths.begin();
+  for(std::vector<std::string>::const_iterator i = userPaths.begin();
         i != userPaths.end(); ++i)
     {
     path.push_back(*i);
@@ -3032,18 +3095,18 @@ kwsys_stl::string SystemTools
   }
   // Add a trailing slash to all paths to aid the search process.
   {
-  for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+  for(std::vector<std::string>::iterator i = path.begin();
       i != path.end(); ++i)
     {
-    kwsys_stl::string& p = *i;
+    std::string& p = *i;
     if(p.empty() || *p.rbegin() != '/')
       {
       p += "/";
       }
     }
   }
-  kwsys_stl::string tryPath;
-  for(kwsys_stl::vector<kwsys_stl::string>::const_iterator p = path.begin();
+  std::string tryPath;
+  for(std::vector<std::string>::const_iterator p = path.begin();
       p != path.end(); ++p)
     {
 #if defined(__APPLE__)
@@ -3118,15 +3181,15 @@ kwsys_stl::string SystemTools
   return "";
 }
 
-kwsys_stl::string SystemTools::GetRealPath(const kwsys_stl::string& path,
-                                           kwsys_stl::string* errorMessage)
+std::string SystemTools::GetRealPath(const std::string& path,
+                                           std::string* errorMessage)
 {
-  kwsys_stl::string ret;
+  std::string ret;
   Realpath(path, ret, errorMessage);
   return ret;
 }
 
-bool SystemTools::FileIsDirectory(const kwsys_stl::string& inName)
+bool SystemTools::FileIsDirectory(const std::string& inName)
 {
   if (inName.empty())
     {
@@ -3175,11 +3238,19 @@ bool SystemTools::FileIsDirectory(const kwsys_stl::string& inName)
     }
 }
 
-bool SystemTools::FileIsSymlink(const kwsys_stl::string& name)
+bool SystemTools::FileIsSymlink(const std::string& name)
 {
 #if defined( _WIN32 )
-  (void)name;
-  return false;
+  DWORD attr = GetFileAttributesW(
+    SystemTools::ConvertToWindowsExtendedPath(name).c_str());
+  if (attr != INVALID_FILE_ATTRIBUTES)
+    {
+    return (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
+    }
+  else
+    {
+    return false;
+    }
 #else
   struct stat fs;
   if(lstat(name.c_str(), &fs) == 0)
@@ -3194,25 +3265,25 @@ bool SystemTools::FileIsSymlink(const kwsys_stl::string& name)
 }
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::CreateSymlink(const kwsys_stl::string&, const kwsys_stl::string&)
+bool SystemTools::CreateSymlink(const std::string&, const std::string&)
 {
   return false;
 }
 #else
-bool SystemTools::CreateSymlink(const kwsys_stl::string& origName, const kwsys_stl::string& newName)
+bool SystemTools::CreateSymlink(const std::string& origName, const std::string& newName)
 {
   return symlink(origName.c_str(), newName.c_str()) >= 0;
 }
 #endif
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::ReadSymlink(const kwsys_stl::string&, kwsys_stl::string&)
+bool SystemTools::ReadSymlink(const std::string&, std::string&)
 {
   return false;
 }
 #else
-bool SystemTools::ReadSymlink(const kwsys_stl::string& newName,
-                              kwsys_stl::string& origName)
+bool SystemTools::ReadSymlink(const std::string& newName,
+                              std::string& origName)
 {
   char buf[KWSYS_SYSTEMTOOLS_MAXPATH+1];
   int count =
@@ -3231,16 +3302,16 @@ bool SystemTools::ReadSymlink(const kwsys_stl::string& newName,
 }
 #endif
 
-int SystemTools::ChangeDirectory(const kwsys_stl::string& dir)
+int SystemTools::ChangeDirectory(const std::string& dir)
 {
   return Chdir(dir);
 }
 
-kwsys_stl::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
+std::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
 {
   char buf[2048];
   const char* cwd = Getcwd(buf, 2048);
-  kwsys_stl::string path;
+  std::string path;
   if ( cwd )
     {
     path = cwd;
@@ -3252,16 +3323,16 @@ kwsys_stl::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
   return path;
 }
 
-kwsys_stl::string SystemTools::GetProgramPath(const kwsys_stl::string& in_name)
+std::string SystemTools::GetProgramPath(const std::string& in_name)
 {
-  kwsys_stl::string dir, file;
+  std::string dir, file;
   SystemTools::SplitProgramPath(in_name, dir, file);
   return dir;
 }
 
-bool SystemTools::SplitProgramPath(const kwsys_stl::string& in_name,
-                                   kwsys_stl::string& dir,
-                                   kwsys_stl::string& file,
+bool SystemTools::SplitProgramPath(const std::string& in_name,
+                                   std::string& dir,
+                                   std::string& file,
                                    bool)
 {
   dir = in_name;
@@ -3270,8 +3341,8 @@ bool SystemTools::SplitProgramPath(const kwsys_stl::string& in_name,
 
   if(!SystemTools::FileIsDirectory(dir))
     {
-    kwsys_stl::string::size_type slashPos = dir.rfind("/");
-    if(slashPos != kwsys_stl::string::npos)
+    std::string::size_type slashPos = dir.rfind("/");
+    if(slashPos != std::string::npos)
       {
       file = dir.substr(slashPos+1);
       dir = dir.substr(0, slashPos);
@@ -3284,7 +3355,7 @@ bool SystemTools::SplitProgramPath(const kwsys_stl::string& in_name,
     }
   if(!(dir.empty()) && !SystemTools::FileIsDirectory(dir))
     {
-    kwsys_stl::string oldDir = in_name;
+    std::string oldDir = in_name;
     SystemTools::ConvertToUnixSlashes(oldDir);
     dir = in_name;
     return false;
@@ -3293,14 +3364,14 @@ bool SystemTools::SplitProgramPath(const kwsys_stl::string& in_name,
 }
 
 bool SystemTools::FindProgramPath(const char* argv0,
-                                  kwsys_stl::string& pathOut,
-                                  kwsys_stl::string& errorMsg,
+                                  std::string& pathOut,
+                                  std::string& errorMsg,
                                   const char* exeName,
                                   const char* buildDir,
                                   const char* installPrefix )
 {
-  kwsys_stl::vector<kwsys_stl::string> failures;
-  kwsys_stl::string self = argv0 ? argv0 : "";
+  std::vector<std::string> failures;
+  std::string self = argv0 ? argv0 : "";
   failures.push_back(self);
   SystemTools::ConvertToUnixSlashes(self);
   self = SystemTools::FindProgram(self);
@@ -3308,7 +3379,7 @@ bool SystemTools::FindProgramPath(const char* argv0,
     {
     if(buildDir)
       {
-      kwsys_stl::string intdir = ".";
+      std::string intdir = ".";
 #ifdef  CMAKE_INTDIR
       intdir = CMAKE_INTDIR;
 #endif
@@ -3333,7 +3404,7 @@ bool SystemTools::FindProgramPath(const char* argv0,
   if(!SystemTools::FileExists(self))
     {
     failures.push_back(self);
-    kwsys_ios::ostringstream msg;
+    std::ostringstream msg;
     msg << "Can not find the command line program ";
     if (exeName)
       {
@@ -3345,7 +3416,7 @@ bool SystemTools::FindProgramPath(const char* argv0,
       msg << "  argv[0] = \"" << argv0 << "\"\n";
       }
     msg << "  Attempted paths:\n";
-    kwsys_stl::vector<kwsys_stl::string>::iterator i;
+    std::vector<std::string>::iterator i;
     for(i=failures.begin(); i != failures.end(); ++i)
       {
       msg << "    \"" << *i << "\"\n";
@@ -3358,15 +3429,15 @@ bool SystemTools::FindProgramPath(const char* argv0,
 }
 
 
-kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_relative)
+std::string SystemTools::CollapseFullPath(const std::string& in_relative)
 {
   return SystemTools::CollapseFullPath(in_relative, 0);
 }
 
-void SystemTools::AddTranslationPath(const kwsys_stl::string& a, const kwsys_stl::string& b)
+void SystemTools::AddTranslationPath(const std::string& a, const std::string& b)
 {
-  kwsys_stl::string path_a = a;
-  kwsys_stl::string path_b = b;
+  std::string path_a = a;
+  std::string path_b = b;
   SystemTools::ConvertToUnixSlashes(path_a);
   SystemTools::ConvertToUnixSlashes(path_b);
   // First check this is a directory path, since we don't want the table to
@@ -3377,7 +3448,7 @@ void SystemTools::AddTranslationPath(const kwsys_stl::string& a, const kwsys_stl
     // Ken--the following code is incorrect. .. can be in a valid path
     // for example  /home/martink/MyHubba...Hubba/Src
     if( SystemTools::FileIsFullPath(path_b) && path_b.find("..")
-        == kwsys_stl::string::npos )
+        == std::string::npos )
       {
       // Before inserting make sure path ends with '/'
       if(!path_a.empty() && *path_a.rbegin() != '/')
@@ -3397,14 +3468,14 @@ void SystemTools::AddTranslationPath(const kwsys_stl::string& a, const kwsys_stl
     }
 }
 
-void SystemTools::AddKeepPath(const kwsys_stl::string& dir)
+void SystemTools::AddKeepPath(const std::string& dir)
 {
-  kwsys_stl::string cdir;
+  std::string cdir;
   Realpath(SystemTools::CollapseFullPath(dir).c_str(), cdir);
   SystemTools::AddTranslationPath(cdir, dir);
 }
 
-void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
+void SystemTools::CheckTranslationPath(std::string & path)
 {
   // Do not translate paths that are too short to have meaningful
   // translations.
@@ -3420,7 +3491,7 @@ void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
 
   // In case a file was specified we still have to go through this:
   // Now convert any path found in the table back to the one desired:
-  kwsys_stl::map<kwsys_stl::string,kwsys_stl::string>::const_iterator it;
+  std::map<std::string,std::string>::const_iterator it;
   for(it  = SystemTools::TranslationMap->begin();
       it != SystemTools::TranslationMap->end();
       ++it )
@@ -3438,13 +3509,13 @@ void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
 
 static void
 SystemToolsAppendComponents(
-  kwsys_stl::vector<kwsys_stl::string>& out_components,
-  kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
-  kwsys_stl::vector<kwsys_stl::string>::const_iterator last)
+  std::vector<std::string>& out_components,
+  std::vector<std::string>::const_iterator first,
+  std::vector<std::string>::const_iterator last)
 {
-  static const kwsys_stl::string up = "..";
-  static const kwsys_stl::string cur = ".";
-  for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = first;
+  static const std::string up = "..";
+  static const std::string cur = ".";
+  for(std::vector<std::string>::const_iterator i = first;
       i != last; ++i)
     {
     if(*i == up)
@@ -3461,20 +3532,20 @@ SystemToolsAppendComponents(
     }
 }
 
-kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path,
+std::string SystemTools::CollapseFullPath(const std::string& in_path,
                                                 const char* in_base)
 {
   // Collect the output path components.
-  kwsys_stl::vector<kwsys_stl::string> out_components;
+  std::vector<std::string> out_components;
 
   // Split the input path components.
-  kwsys_stl::vector<kwsys_stl::string> path_components;
+  std::vector<std::string> path_components;
   SystemTools::SplitPath(in_path, path_components);
 
   // If the input path is relative, start with a base path.
   if(path_components[0].length() == 0)
     {
-    kwsys_stl::vector<kwsys_stl::string> base_components;
+    std::vector<std::string> base_components;
     if(in_base)
       {
       // Use the given base path.
@@ -3507,7 +3578,7 @@ kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path
                               path_components.end());
 
   // Transform the path back to a string.
-  kwsys_stl::string newPath = SystemTools::JoinPath(out_components);
+  std::string newPath = SystemTools::JoinPath(out_components);
 
   // Update the translation table with this potentially new path.  I am not
   // sure why this line is here, it seems really questionable, but yet I
@@ -3532,20 +3603,20 @@ kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path
   return newPath;
 }
 
-kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path,
-                                                const kwsys_stl::string& in_base)
+std::string SystemTools::CollapseFullPath(const std::string& in_path,
+                                                const std::string& in_base)
 {
   // Collect the output path components.
-  kwsys_stl::vector<kwsys_stl::string> out_components;
+  std::vector<std::string> out_components;
 
   // Split the input path components.
-  kwsys_stl::vector<kwsys_stl::string> path_components;
+  std::vector<std::string> path_components;
   SystemTools::SplitPath(in_path, path_components);
 
   // If the input path is relative, start with a base path.
   if(path_components[0].length() == 0)
     {
-    kwsys_stl::vector<kwsys_stl::string> base_components;
+    std::vector<std::string> base_components;
     // Use the given base path.
     SystemTools::SplitPath(in_base, base_components);
 
@@ -3562,7 +3633,7 @@ kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path
                               path_components.end());
 
   // Transform the path back to a string.
-  kwsys_stl::string newPath = SystemTools::JoinPath(out_components);
+  std::string newPath = SystemTools::JoinPath(out_components);
 
   // Update the translation table with this potentially new path.  I am not
   // sure why this line is here, it seems really questionable, but yet I
@@ -3588,7 +3659,7 @@ kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path
 }
 
 // compute the relative path from here to there
-kwsys_stl::string SystemTools::RelativePath(const kwsys_stl::string& local, const kwsys_stl::string& remote)
+std::string SystemTools::RelativePath(const std::string& local, const std::string& remote)
 {
   if(!SystemTools::FileIsFullPath(local))
     {
@@ -3599,14 +3670,14 @@ kwsys_stl::string SystemTools::RelativePath(const kwsys_stl::string& local, cons
     return "";
     }
 
-  kwsys_stl::string l = SystemTools::CollapseFullPath(local);
-  kwsys_stl::string r = SystemTools::CollapseFullPath(remote);
+  std::string l = SystemTools::CollapseFullPath(local);
+  std::string r = SystemTools::CollapseFullPath(remote);
 
   // split up both paths into arrays of strings using / as a separator
-  kwsys_stl::vector<kwsys::String> localSplit = SystemTools::SplitString(l, '/', true);
-  kwsys_stl::vector<kwsys::String> remoteSplit = SystemTools::SplitString(r, '/', true);
-  kwsys_stl::vector<kwsys::String> commonPath; // store shared parts of path in this array
-  kwsys_stl::vector<kwsys::String> finalPath;  // store the final relative path here
+  std::vector<kwsys::String> localSplit = SystemTools::SplitString(l, '/', true);
+  std::vector<kwsys::String> remoteSplit = SystemTools::SplitString(r, '/', true);
+  std::vector<kwsys::String> commonPath; // store shared parts of path in this array
+  std::vector<kwsys::String> finalPath;  // store the final relative path here
   // count up how many matching directory names there are from the start
   unsigned int sameCount = 0;
   while(
@@ -3651,7 +3722,7 @@ kwsys_stl::string SystemTools::RelativePath(const kwsys_stl::string& local, cons
     }
   // for each entry that is not common in the remote path add it
   // to the final path.
-  for(kwsys_stl::vector<String>::iterator vit = remoteSplit.begin();
+  for(std::vector<String>::iterator vit = remoteSplit.begin();
       vit != remoteSplit.end(); ++vit)
     {
     if(!vit->empty())
@@ -3659,10 +3730,10 @@ kwsys_stl::string SystemTools::RelativePath(const kwsys_stl::string& local, cons
       finalPath.push_back(*vit);
       }
     }
-  kwsys_stl::string relativePath;     // result string
+  std::string relativePath;     // result string
   // now turn the array of directories into a unix path by puttint /
   // between each entry that does not already have one
-  for(kwsys_stl::vector<String>::iterator vit1 = finalPath.begin();
+  for(std::vector<String>::iterator vit1 = finalPath.begin();
       vit1 != finalPath.end(); ++vit1)
     {
     if(!relativePath.empty() && *relativePath.rbegin() != '/')
@@ -3675,10 +3746,10 @@ kwsys_stl::string SystemTools::RelativePath(const kwsys_stl::string& local, cons
 }
 
 #ifdef _WIN32
-static int GetCasePathName(const kwsys_stl::string & pathIn,
-                            kwsys_stl::string & casePath)
+static int GetCasePathName(const std::string & pathIn,
+                            std::string & casePath)
 {
-  kwsys_stl::vector<kwsys_stl::string> path_components;
+  std::vector<std::string> path_components;
   SystemTools::SplitPath(pathIn, path_components);
   if(path_components[0].empty()) // First component always exists.
     {
@@ -3688,8 +3759,13 @@ static int GetCasePathName(const kwsys_stl::string & pathIn,
     }
 
   // Start with root component.
-  kwsys_stl::vector<kwsys_stl::string>::size_type idx = 0;
+  std::vector<std::string>::size_type idx = 0;
   casePath = path_components[idx++];
+  // make sure drive letter is always upper case
+  if(casePath.size() > 1 && casePath[1] == ':')
+    {
+    casePath[0] = toupper(casePath[0]);
+    }
   const char* sep = "";
 
   // If network path, fill casePath with server/share so FindFirstFile
@@ -3707,14 +3783,14 @@ static int GetCasePathName(const kwsys_stl::string & pathIn,
     {
     casePath += sep;
     sep = "/";
-    kwsys_stl::string test_str = casePath;
+    std::string test_str = casePath;
     test_str += path_components[idx];
 
     // If path component contains wildcards, we skip matching
     // because these filenames are not allowed on windows,
     // and we do not want to match a different file.
-    if(path_components[idx].find('*') != kwsys_stl::string::npos ||
-       path_components[idx].find('?') != kwsys_stl::string::npos)
+    if(path_components[idx].find('*') != std::string::npos ||
+       path_components[idx].find('?') != std::string::npos)
       {
       casePath = "";
       return 0;
@@ -3740,39 +3816,33 @@ static int GetCasePathName(const kwsys_stl::string & pathIn,
 
 
 //----------------------------------------------------------------------------
-kwsys_stl::string SystemTools::GetActualCaseForPath(const kwsys_stl::string& p)
+std::string SystemTools::GetActualCaseForPath(const std::string& p)
 {
 #ifndef _WIN32
   return p;
 #else
-  kwsys_stl::string casePath = p;
-  // make sure drive letter is always upper case
-  if(casePath.size() > 1 && casePath[1] == ':')
-    {
-    casePath[0] = toupper(casePath[0]);
-    }
-
   // Check to see if actual case has already been called
-  // for this path, and the result is stored in the LongPathMap
-  SystemToolsTranslationMap::iterator i =
-    SystemTools::LongPathMap->find(casePath);
-  if(i != SystemTools::LongPathMap->end())
+  // for this path, and the result is stored in the PathCaseMap
+  SystemToolsPathCaseMap::iterator i =
+    SystemTools::PathCaseMap->find(p);
+  if(i != SystemTools::PathCaseMap->end())
     {
     return i->second;
     }
+  std::string casePath;
   int len = GetCasePathName(p, casePath);
   if(len == 0 || len > MAX_PATH+1)
     {
     return p;
     }
-  (*SystemTools::LongPathMap)[p] = casePath;
+  (*SystemTools::PathCaseMap)[p] = casePath;
   return casePath;
 #endif
 }
 
 //----------------------------------------------------------------------------
 const char* SystemTools::SplitPathRootComponent(const std::string& p,
-                                                kwsys_stl::string* root)
+                                                std::string* root)
 {
   // Identify the root component.
   const char* c = p.c_str();
@@ -3858,7 +3928,7 @@ const char* SystemTools::SplitPathRootComponent(const std::string& p,
 
 //----------------------------------------------------------------------------
 void SystemTools::SplitPath(const std::string& p,
-                            kwsys_stl::vector<kwsys_stl::string>& components,
+                            std::vector<std::string>& components,
                             bool expand_home_dir)
 {
   const char* c;
@@ -3866,13 +3936,13 @@ void SystemTools::SplitPath(const std::string& p,
 
   // Identify the root component.
   {
-  kwsys_stl::string root;
+  std::string root;
   c = SystemTools::SplitPathRootComponent(p, &root);
 
   // Expand home directory references if requested.
   if(expand_home_dir && !root.empty() && root[0] == '~')
     {
-    kwsys_stl::string homedir;
+    std::string homedir;
     root = root.substr(0, root.size()-1);
     if(root.size() == 1)
       {
@@ -3918,7 +3988,7 @@ void SystemTools::SplitPath(const std::string& p,
     if(*last == '/' || *last == '\\')
       {
       // End of a component.  Save it.
-      components.push_back(kwsys_stl::string(first, last));
+      components.push_back(std::string(first, last));
       first = last+1;
       }
     }
@@ -3926,27 +3996,27 @@ void SystemTools::SplitPath(const std::string& p,
   // Save the last component unless there were no components.
   if(last != c)
     {
-    components.push_back(kwsys_stl::string(first, last));
+    components.push_back(std::string(first, last));
     }
 }
 
 //----------------------------------------------------------------------------
-kwsys_stl::string
-SystemTools::JoinPath(const kwsys_stl::vector<kwsys_stl::string>& components)
+std::string
+SystemTools::JoinPath(const std::vector<std::string>& components)
 {
   return SystemTools::JoinPath(components.begin(), components.end());
 }
 
 //----------------------------------------------------------------------------
-kwsys_stl::string
+std::string
 SystemTools
-::JoinPath(kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
-           kwsys_stl::vector<kwsys_stl::string>::const_iterator last)
+::JoinPath(std::vector<std::string>::const_iterator first,
+           std::vector<std::string>::const_iterator last)
 {
   // Construct result in a single string.
-  kwsys_stl::string result;
+  std::string result;
   size_t len = 0;
-  kwsys_stl::vector<kwsys_stl::string>::const_iterator i;
+  std::vector<std::string>::const_iterator i;
   for(i = first; i != last; ++i)
     {
     len += 1 + i->size();
@@ -3975,7 +4045,7 @@ SystemTools
 }
 
 //----------------------------------------------------------------------------
-bool SystemTools::ComparePath(const kwsys_stl::string& c1, const kwsys_stl::string& c2)
+bool SystemTools::ComparePath(const std::string& c1, const std::string& c2)
 {
 #if defined(_WIN32) || defined(__APPLE__)
 # ifdef _MSC_VER
@@ -3991,14 +4061,14 @@ bool SystemTools::ComparePath(const kwsys_stl::string& c1, const kwsys_stl::stri
 }
 
 //----------------------------------------------------------------------------
-bool SystemTools::Split(const kwsys_stl::string& str, kwsys_stl::vector<kwsys_stl::string>& lines, char separator)
+bool SystemTools::Split(const std::string& str, std::vector<std::string>& lines, char separator)
 {
-  kwsys_stl::string data(str);
-  kwsys_stl::string::size_type lpos = 0;
+  std::string data(str);
+  std::string::size_type lpos = 0;
   while(lpos < data.length())
     {
-    kwsys_stl::string::size_type rpos = data.find_first_of(separator, lpos);
-    if(rpos == kwsys_stl::string::npos)
+    std::string::size_type rpos = data.find_first_of(separator, lpos);
+    if(rpos == std::string::npos)
       {
       // Line ends at end of string without a newline.
       lines.push_back(data.substr(lpos));
@@ -4015,14 +4085,14 @@ bool SystemTools::Split(const kwsys_stl::string& str, kwsys_stl::vector<kwsys_st
 }
 
 //----------------------------------------------------------------------------
-bool SystemTools::Split(const kwsys_stl::string& str, kwsys_stl::vector<kwsys_stl::string>& lines)
+bool SystemTools::Split(const std::string& str, std::vector<std::string>& lines)
 {
-  kwsys_stl::string data(str);
-  kwsys_stl::string::size_type lpos = 0;
+  std::string data(str);
+  std::string::size_type lpos = 0;
   while(lpos < data.length())
     {
-    kwsys_stl::string::size_type rpos = data.find_first_of("\n", lpos);
-    if(rpos == kwsys_stl::string::npos)
+    std::string::size_type rpos = data.find_first_of("\n", lpos);
+    if(rpos == std::string::npos)
       {
       // Line ends at end of string without a newline.
       lines.push_back(data.substr(lpos));
@@ -4047,15 +4117,15 @@ bool SystemTools::Split(const kwsys_stl::string& str, kwsys_stl::vector<kwsys_st
  * Return path of a full filename (no trailing slashes).
  * Warning: returned path is converted to Unix slashes format.
  */
-kwsys_stl::string SystemTools::GetFilenamePath(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenamePath(const std::string& filename)
 {
-  kwsys_stl::string fn = filename;
+  std::string fn = filename;
   SystemTools::ConvertToUnixSlashes(fn);
 
-  kwsys_stl::string::size_type slash_pos = fn.rfind("/");
-  if(slash_pos != kwsys_stl::string::npos)
+  std::string::size_type slash_pos = fn.rfind("/");
+  if(slash_pos != std::string::npos)
     {
-    kwsys_stl::string  ret = fn.substr(0, slash_pos);
+    std::string  ret = fn.substr(0, slash_pos);
     if(ret.size() == 2 && ret[1] == ':')
       {
       return ret + '/';
@@ -4076,14 +4146,14 @@ kwsys_stl::string SystemTools::GetFilenamePath(const kwsys_stl::string& filename
 /**
  * Return file name of a full filename (i.e. file name without path).
  */
-kwsys_stl::string SystemTools::GetFilenameName(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenameName(const std::string& filename)
 {
 #if defined(_WIN32)
-  kwsys_stl::string::size_type slash_pos = filename.find_last_of("/\\");
+  std::string::size_type slash_pos = filename.find_last_of("/\\");
 #else
-  kwsys_stl::string::size_type slash_pos = filename.rfind('/');
+  std::string::size_type slash_pos = filename.rfind('/');
 #endif
-  if(slash_pos != kwsys_stl::string::npos)
+  if(slash_pos != std::string::npos)
     {
     return filename.substr(slash_pos + 1);
     }
@@ -4098,11 +4168,11 @@ kwsys_stl::string SystemTools::GetFilenameName(const kwsys_stl::string& filename
  * Return file extension of a full filename (dot included).
  * Warning: this is the longest extension (for example: .tar.gz)
  */
-kwsys_stl::string SystemTools::GetFilenameExtension(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenameExtension(const std::string& filename)
 {
-  kwsys_stl::string name = SystemTools::GetFilenameName(filename);
-  kwsys_stl::string::size_type dot_pos = name.find('.');
-  if(dot_pos != kwsys_stl::string::npos)
+  std::string name = SystemTools::GetFilenameName(filename);
+  std::string::size_type dot_pos = name.find('.');
+  if(dot_pos != std::string::npos)
     {
     return name.substr(dot_pos);
     }
@@ -4116,11 +4186,11 @@ kwsys_stl::string SystemTools::GetFilenameExtension(const kwsys_stl::string& fil
  * Return file extension of a full filename (dot included).
  * Warning: this is the shortest extension (for example: .gz of .tar.gz)
  */
-kwsys_stl::string SystemTools::GetFilenameLastExtension(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenameLastExtension(const std::string& filename)
 {
-  kwsys_stl::string name = SystemTools::GetFilenameName(filename);
-  kwsys_stl::string::size_type dot_pos = name.rfind('.');
-  if(dot_pos != kwsys_stl::string::npos)
+  std::string name = SystemTools::GetFilenameName(filename);
+  std::string::size_type dot_pos = name.rfind('.');
+  if(dot_pos != std::string::npos)
     {
     return name.substr(dot_pos);
     }
@@ -4134,11 +4204,11 @@ kwsys_stl::string SystemTools::GetFilenameLastExtension(const kwsys_stl::string&
  * Return file name without extension of a full filename (i.e. without path).
  * Warning: it considers the longest extension (for example: .tar.gz)
  */
-kwsys_stl::string SystemTools::GetFilenameWithoutExtension(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenameWithoutExtension(const std::string& filename)
 {
-  kwsys_stl::string name = SystemTools::GetFilenameName(filename);
-  kwsys_stl::string::size_type dot_pos = name.find('.');
-  if(dot_pos != kwsys_stl::string::npos)
+  std::string name = SystemTools::GetFilenameName(filename);
+  std::string::size_type dot_pos = name.find('.');
+  if(dot_pos != std::string::npos)
     {
     return name.substr(0, dot_pos);
     }
@@ -4154,12 +4224,12 @@ kwsys_stl::string SystemTools::GetFilenameWithoutExtension(const kwsys_stl::stri
  * Warning: it considers the last extension (for example: removes .gz
  * from .tar.gz)
  */
-kwsys_stl::string
-SystemTools::GetFilenameWithoutLastExtension(const kwsys_stl::string& filename)
+std::string
+SystemTools::GetFilenameWithoutLastExtension(const std::string& filename)
 {
-  kwsys_stl::string name = SystemTools::GetFilenameName(filename);
-  kwsys_stl::string::size_type dot_pos = name.rfind('.');
-  if(dot_pos != kwsys_stl::string::npos)
+  std::string name = SystemTools::GetFilenameName(filename);
+  std::string::size_type dot_pos = name.rfind('.');
+  if(dot_pos != std::string::npos)
     {
     return name.substr(0, dot_pos);
     }
@@ -4211,6 +4281,11 @@ SystemTools::DetectFileType(const char *filename,
     return SystemTools::FileTypeUnknown;
     }
 
+  if (SystemTools::FileIsDirectory(filename))
+    {
+    return SystemTools::FileTypeUnknown;
+    }
+
   FILE *fp = Fopen(filename, "rb");
   if (!fp)
     {
@@ -4224,6 +4299,7 @@ SystemTools::DetectFileType(const char *filename,
   fclose(fp);
   if (read_length == 0)
     {
+    delete [] buffer;
     return SystemTools::FileTypeUnknown;
     }
 
@@ -4262,7 +4338,7 @@ SystemTools::DetectFileType(const char *filename,
 
 bool SystemTools::LocateFileInDir(const char *filename,
                                   const char *dir,
-                                  kwsys_stl::string& filename_found,
+                                  std::string& filename_found,
                                   int try_filename_dirs)
 {
   if (!filename || !dir)
@@ -4272,12 +4348,12 @@ bool SystemTools::LocateFileInDir(const char *filename,
 
   // Get the basename of 'filename'
 
-  kwsys_stl::string filename_base = SystemTools::GetFilenameName(filename);
+  std::string filename_base = SystemTools::GetFilenameName(filename);
 
   // Check if 'dir' is really a directory
   // If win32 and matches something like C:, accept it as a dir
 
-  kwsys_stl::string real_dir;
+  std::string real_dir;
   if (!SystemTools::FileIsDirectory(dir))
     {
 #if defined( _WIN32 )
@@ -4301,7 +4377,7 @@ bool SystemTools::LocateFileInDir(const char *filename,
     int need_slash =
       (dir_len && dir[dir_len - 1] != '/' && dir[dir_len - 1] != '\\');
 
-    kwsys_stl::string temp = dir;
+    std::string temp = dir;
     if (need_slash)
       {
       temp += "/";
@@ -4321,9 +4397,9 @@ bool SystemTools::LocateFileInDir(const char *filename,
 
     else if (try_filename_dirs)
       {
-      kwsys_stl::string filename_dir(filename);
-      kwsys_stl::string filename_dir_base;
-      kwsys_stl::string filename_dir_bases;
+      std::string filename_dir(filename);
+      std::string filename_dir_base;
+      std::string filename_dir_bases;
       do
         {
         filename_dir = SystemTools::GetFilenamePath(filename_dir);
@@ -4357,7 +4433,7 @@ bool SystemTools::LocateFileInDir(const char *filename,
   return res;
 }
 
-bool SystemTools::FileIsFullPath(const kwsys_stl::string& in_name)
+bool SystemTools::FileIsFullPath(const std::string& in_name)
 {
   return SystemTools::FileIsFullPath(in_name.c_str(), in_name.size());
 }
@@ -4406,9 +4482,9 @@ bool SystemTools::FileIsFullPath(const char* in_name, size_t len)
   return false;
 }
 
-bool SystemTools::GetShortPath(const kwsys_stl::string& path, kwsys_stl::string& shortPath)
+bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath)
 {
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
   const int size = int(path.size()) +1; // size of return
   char *tempPath = new char[size];  // create a buffer
   DWORD ret;
@@ -4424,8 +4500,8 @@ bool SystemTools::GetShortPath(const kwsys_stl::string& path, kwsys_stl::string&
     strcpy(tempPath,path.c_str());
     }
 
-  kwsys_stl::wstring wtempPath = Encoding::ToWide(tempPath);
-  kwsys_stl::vector<wchar_t> buffer(wtempPath.size()+1);
+  std::wstring wtempPath = Encoding::ToWide(tempPath);
+  std::vector<wchar_t> buffer(wtempPath.size()+1);
   buffer[0] = 0;
   ret = GetShortPathNameW(wtempPath.c_str(),
     &buffer[0], static_cast<DWORD>(wtempPath.size()));
@@ -4447,8 +4523,8 @@ bool SystemTools::GetShortPath(const kwsys_stl::string& path, kwsys_stl::string&
 #endif
 }
 
-void SystemTools::SplitProgramFromArgs(const kwsys_stl::string& path,
-                                       kwsys_stl::string& program, kwsys_stl::string& args)
+void SystemTools::SplitProgramFromArgs(const std::string& path,
+                                       std::string& program, std::string& args)
 {
   // see if this is a full path to a program
   // if so then set program to path and args to nothing
@@ -4460,8 +4536,8 @@ void SystemTools::SplitProgramFromArgs(const kwsys_stl::string& path,
     }
   // Try to find the program in the path, note the program
   // may have spaces in its name so we have to look for it
-  kwsys_stl::vector<kwsys_stl::string> e;
-  kwsys_stl::string findProg = SystemTools::FindProgram(path, e);
+  std::vector<std::string> e;
+  std::string findProg = SystemTools::FindProgram(path, e);
   if(!findProg.empty())
     {
     program = findProg;
@@ -4471,17 +4547,17 @@ void SystemTools::SplitProgramFromArgs(const kwsys_stl::string& path,
 
   // Now try and peel off space separated chunks from the end of the string
   // so the largest path possible is found allowing for spaces in the path
-  kwsys_stl::string dir = path;
-  kwsys_stl::string::size_type spacePos = dir.rfind(' ');
-  while(spacePos != kwsys_stl::string::npos)
+  std::string dir = path;
+  std::string::size_type spacePos = dir.rfind(' ');
+  while(spacePos != std::string::npos)
     {
-    kwsys_stl::string tryProg = dir.substr(0, spacePos);
+    std::string tryProg = dir.substr(0, spacePos);
     // See if the file exists
     if(SystemTools::FileExists(tryProg))
       {
       program = tryProg;
       // remove trailing spaces from program
-      kwsys_stl::string::size_type pos = program.size()-1;
+      std::string::size_type pos = program.size()-1;
       while(program[pos] == ' ')
         {
         program.erase(pos);
@@ -4496,7 +4572,7 @@ void SystemTools::SplitProgramFromArgs(const kwsys_stl::string& path,
       {
       program = findProg;
       // remove trailing spaces from program
-      kwsys_stl::string::size_type pos = program.size()-1;
+      std::string::size_type pos = program.size()-1;
       while(program[pos] == ' ')
         {
         program.erase(pos);
@@ -4514,29 +4590,29 @@ void SystemTools::SplitProgramFromArgs(const kwsys_stl::string& path,
   args = "";
 }
 
-kwsys_stl::string SystemTools::GetCurrentDateTime(const char* format)
+std::string SystemTools::GetCurrentDateTime(const char* format)
 {
   char buf[1024];
   time_t t;
   time(&t);
   strftime(buf, sizeof(buf), format, localtime(&t));
-  return kwsys_stl::string(buf);
+  return std::string(buf);
 }
 
-kwsys_stl::string SystemTools::MakeCidentifier(const kwsys_stl::string& s)
+std::string SystemTools::MakeCidentifier(const std::string& s)
 {
-  kwsys_stl::string str(s);
+  std::string str(s);
   if (str.find_first_of("0123456789") == 0)
     {
     str = "_" + str;
     }
 
-  kwsys_stl::string permited_chars("_"
+  std::string permited_chars("_"
                              "abcdefghijklmnopqrstuvwxyz"
                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                              "0123456789");
-  kwsys_stl::string::size_type pos = 0;
-  while ((pos = str.find_first_not_of(permited_chars, pos)) != kwsys_stl::string::npos)
+  std::string::size_type pos = 0;
+  while ((pos = str.find_first_not_of(permited_chars, pos)) != std::string::npos)
     {
     str[pos] = '_';
     }
@@ -4546,8 +4622,8 @@ kwsys_stl::string SystemTools::MakeCidentifier(const kwsys_stl::string& s)
 // Due to a buggy stream library on the HP and another on Mac OS X, we
 // need this very carefully written version of getline.  Returns true
 // if any data were read before the end-of-file was reached.
-bool SystemTools::GetLineFromStream(kwsys_ios::istream& is,
-                                    kwsys_stl::string& line,
+bool SystemTools::GetLineFromStream(std::istream& is,
+                                    std::string& line,
                                     bool* has_newline /* = 0 */,
                                     long sizeLimit /* = -1 */)
 {
@@ -4578,7 +4654,7 @@ bool SystemTools::GetLineFromStream(kwsys_ios::istream& is,
   // been reached.  Clear the fail bit just before reading.
   while(!haveNewline &&
         leftToRead != 0 &&
-        (is.clear(is.rdstate() & ~kwsys_ios::ios::failbit),
+        (is.clear(is.rdstate() & ~std::ios::failbit),
          is.getline(buffer, bufferSize), is.gcount() > 0))
     {
     // We have read at least one byte.
@@ -4663,10 +4739,10 @@ bool SystemTools::GetPermissions(const char* file, mode_t& mode)
     {
     return false;
     }
-  return SystemTools::GetPermissions(kwsys_stl::string(file), mode);
+  return SystemTools::GetPermissions(std::string(file), mode);
 }
 
-bool SystemTools::GetPermissions(const kwsys_stl::string& file, mode_t& mode)
+bool SystemTools::GetPermissions(const std::string& file, mode_t& mode)
 {
 #if defined(_WIN32)
   DWORD attr = GetFileAttributesW(
@@ -4712,21 +4788,35 @@ bool SystemTools::GetPermissions(const kwsys_stl::string& file, mode_t& mode)
   return true;
 }
 
-bool SystemTools::SetPermissions(const char* file, mode_t mode)
+bool SystemTools::SetPermissions(const char* file,
+                                 mode_t mode,
+                                 bool honor_umask)
 {
   if ( !file )
     {
     return false;
     }
-  return SystemTools::SetPermissions(kwsys_stl::string(file), mode);
+  return SystemTools::SetPermissions(
+    std::string(file), mode, honor_umask);
 }
 
-bool SystemTools::SetPermissions(const kwsys_stl::string& file, mode_t mode)
+bool SystemTools::SetPermissions(const std::string& file,
+                                 mode_t mode,
+                                 bool honor_umask)
 {
-  if ( !SystemTools::FileExists(file) )
+  // TEMPORARY / TODO:  After FileExists calls lstat() instead of
+  // access(), change this call to FileExists instead of
+  // TestFileAccess so that we don't follow symlinks.
+  if ( !SystemTools::TestFileAccess(file, TEST_FILE_OK) )
     {
     return false;
     }
+  if (honor_umask)
+    {
+    mode_t currentMask = umask(0);
+    umask(currentMask);
+    mode &= ~currentMask;
+    }
 #ifdef _WIN32
   if ( _wchmod(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
                mode) < 0 )
@@ -4740,19 +4830,19 @@ bool SystemTools::SetPermissions(const kwsys_stl::string& file, mode_t mode)
   return true;
 }
 
-kwsys_stl::string SystemTools::GetParentDirectory(const kwsys_stl::string& fileOrDir)
+std::string SystemTools::GetParentDirectory(const std::string& fileOrDir)
 {
   return SystemTools::GetFilenamePath(fileOrDir);
 }
 
-bool SystemTools::IsSubDirectory(const kwsys_stl::string& cSubdir, const kwsys_stl::string& cDir)
+bool SystemTools::IsSubDirectory(const std::string& cSubdir, const std::string& cDir)
 {
   if(cDir.empty())
     {
     return false;
     }
-  kwsys_stl::string subdir = cSubdir;
-  kwsys_stl::string dir = cDir;
+  std::string subdir = cSubdir;
+  std::string dir = cDir;
   SystemTools::ConvertToUnixSlashes(subdir);
   SystemTools::ConvertToUnixSlashes(dir);
   if(subdir.size() > dir.size() && subdir[dir.size()] == '/')
@@ -4787,9 +4877,9 @@ void SystemTools::Delay(unsigned int msec)
 #endif
 }
 
-kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
+std::string SystemTools::GetOperatingSystemNameAndVersion()
 {
-  kwsys_stl::string res;
+  std::string res;
 
 #ifdef _WIN32
   char buffer[256];
@@ -4797,11 +4887,8 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
   OSVERSIONINFOEXA osvi;
   BOOL bOsVersionInfoEx;
 
-  // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
-  // If that fails, try using the OSVERSIONINFO structure.
-
-  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXA));
-  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
+  ZeroMemory(&osvi, sizeof(osvi));
+  osvi.dwOSVersionInfoSize = sizeof(osvi);
 
 #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
 # pragma warning (push)
@@ -4811,14 +4898,10 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
 #  pragma warning (disable:4996)
 # endif
 #endif
-  bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&osvi);
+  bOsVersionInfoEx = GetVersionExA((OSVERSIONINFOA *)&osvi);
   if (!bOsVersionInfoEx)
     {
-    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-    if (!GetVersionEx((OSVERSIONINFO *)&osvi))
-      {
-      return 0;
-      }
+    return 0;
     }
 #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
 # pragma warning (pop)
@@ -4831,10 +4914,56 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
     case VER_PLATFORM_WIN32_NT:
 
       // Test for the specific product family.
+      if (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0)
+        {
+        if (osvi.wProductType == VER_NT_WORKSTATION)
+          {
+          res += "Microsoft Windows 10";
+          }
+        else
+          {
+          res += "Microsoft Windows Server 2016 family";
+          }
+        }
+
+      if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 3)
+        {
+        if (osvi.wProductType == VER_NT_WORKSTATION)
+          {
+          res += "Microsoft Windows 8.1";
+          }
+        else
+          {
+          res += "Microsoft Windows Server 2012 R2 family";
+          }
+        }
+
+      if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2)
+        {
+        if (osvi.wProductType == VER_NT_WORKSTATION)
+          {
+          res += "Microsoft Windows 8";
+          }
+        else
+          {
+          res += "Microsoft Windows Server 2012 family";
+          }
+        }
+
+      if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1)
+        {
+        if (osvi.wProductType == VER_NT_WORKSTATION)
+          {
+          res += "Microsoft Windows 7";
+          }
+        else
+          {
+          res += "Microsoft Windows Server 2008 R2 family";
+          }
+        }
 
       if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
         {
-#if (_MSC_VER >= 1300)
         if (osvi.wProductType == VER_NT_WORKSTATION)
           {
           res += "Microsoft Windows Vista";
@@ -4843,9 +4972,6 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
           {
           res += "Microsoft Windows Server 2008 family";
           }
-#else
-        res += "Microsoft Windows Vista or Windows Server 2008";
-#endif
         }
 
       if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
@@ -4874,7 +5000,6 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
         {
         // Test for the workstation type.
 
-#if (_MSC_VER >= 1300)
         if (osvi.wProductType == VER_NT_WORKSTATION)
           {
           if (osvi.dwMajorVersion == 4)
@@ -4946,7 +5071,6 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
               }
             }
           }
-#endif // Visual Studio 7 and up
         }
 
       // Test for specific product on Windows NT 4.0 SP5 and earlier
@@ -5084,9 +5208,9 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
 }
 
 // ----------------------------------------------------------------------
-bool SystemTools::ParseURLProtocol( const kwsys_stl::string& URL,
-                                    kwsys_stl::string& protocol,
-                                    kwsys_stl::string& dataglom )
+bool SystemTools::ParseURLProtocol( const std::string& URL,
+                                    std::string& protocol,
+                                    std::string& dataglom )
 {
   // match 0 entire url
   // match 1 protocol
@@ -5102,13 +5226,13 @@ bool SystemTools::ParseURLProtocol( const kwsys_stl::string& URL,
 }
 
 // ----------------------------------------------------------------------
-bool SystemTools::ParseURL( const kwsys_stl::string& URL,
-                            kwsys_stl::string& protocol,
-                            kwsys_stl::string& username,
-                            kwsys_stl::string& password,
-                            kwsys_stl::string& hostname,
-                            kwsys_stl::string& dataport,
-                            kwsys_stl::string& database )
+bool SystemTools::ParseURL( const std::string& URL,
+                            std::string& protocol,
+                            std::string& username,
+                            std::string& password,
+                            std::string& hostname,
+                            std::string& dataport,
+                            std::string& database )
 {
   kwsys::RegularExpression urlRe( VTK_URL_REGEX );
   if ( ! urlRe.find( URL ) ) return false;
@@ -5139,7 +5263,9 @@ bool SystemTools::ParseURL( const kwsys_stl::string& URL,
 // necessary.
 static unsigned int SystemToolsManagerCount;
 SystemToolsTranslationMap *SystemTools::TranslationMap;
-SystemToolsTranslationMap *SystemTools::LongPathMap;
+#ifdef _WIN32
+SystemToolsPathCaseMap *SystemTools::PathCaseMap;
+#endif
 #ifdef __CYGWIN__
 SystemToolsTranslationMap *SystemTools::Cyg2Win32Map;
 #endif
@@ -5187,7 +5313,9 @@ void SystemTools::ClassInitialize()
 #endif
   // Allocate the translation map first.
   SystemTools::TranslationMap = new SystemToolsTranslationMap;
-  SystemTools::LongPathMap = new SystemToolsTranslationMap;
+#ifdef _WIN32
+  SystemTools::PathCaseMap = new SystemToolsPathCaseMap;
+#endif
 #ifdef __CYGWIN__
   SystemTools::Cyg2Win32Map = new SystemToolsTranslationMap;
 #endif
@@ -5209,13 +5337,13 @@ void SystemTools::ClassInitialize()
       // The current working directory may be a logical path.  Find
       // the shortest logical path that still produces the correct
       // physical path.
-      kwsys_stl::string cwd_changed;
-      kwsys_stl::string pwd_changed;
+      std::string cwd_changed;
+      std::string pwd_changed;
 
       // Test progressively shorter logical-to-physical mappings.
-      kwsys_stl::string pwd_str = pwd;
-      kwsys_stl::string cwd_str = cwd;
-      kwsys_stl::string pwd_path;
+      std::string pwd_str = pwd;
+      std::string cwd_str = cwd;
+      std::string pwd_path;
       Realpath(pwd, pwd_path);
       while(cwd_str == pwd_path && cwd_str != pwd_str)
         {
@@ -5244,7 +5372,9 @@ void SystemTools::ClassInitialize()
 void SystemTools::ClassFinalize()
 {
   delete SystemTools::TranslationMap;
-  delete SystemTools::LongPathMap;
+#ifdef _WIN32
+  delete SystemTools::PathCaseMap;
+#endif
 #ifdef __CYGWIN__
   delete SystemTools::Cyg2Win32Map;
 #endif
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 93cde02..d2d1d40 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -12,21 +12,25 @@
 #ifndef @KWSYS_NAMESPACE at _SystemTools_hxx
 #define @KWSYS_NAMESPACE at _SystemTools_hxx
 
-#include <@KWSYS_NAMESPACE@/ios/iosfwd>
-#include <@KWSYS_NAMESPACE@/stl/string>
-#include <@KWSYS_NAMESPACE@/stl/vector>
-#include <@KWSYS_NAMESPACE@/stl/map>
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+#include <map>
 
-#include <@KWSYS_NAMESPACE@/Configure.h>
 #include <@KWSYS_NAMESPACE@/String.hxx>
 
 #include <sys/types.h>
+#if !defined(_WIN32) || defined(__CYGWIN__)
+# include <unistd.h> // For access permissions for use with access()
+#endif
 
 // Required for va_list
 #include <stdarg.h>
 // Required for FILE*
 #include <stdio.h>
-#if @KWSYS_NAMESPACE at _STL_HAVE_STD && !defined(va_list)
+#if !defined(va_list)
 // Some compilers move va_list into the std namespace and there is no way to
 // tell that this has been done. Playing with things being included before or
 // after stdarg.h does not solve things because we do not have control over
@@ -44,16 +48,12 @@ namespace @KWSYS_NAMESPACE@
 }
 #endif // va_list
 
-/* Define these macros temporarily to keep the code readable.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE at _stl
-# define kwsys_ios @KWSYS_NAMESPACE at _ios
-#endif
-
 namespace @KWSYS_NAMESPACE@
 {
 
 class SystemToolsTranslationMap;
+class SystemToolsPathCaseMap;
+
 /** \class SystemToolsManager
  * \brief Use to make sure SystemTools is initialized before it is used
  * and is the last static object destroyed
@@ -66,10 +66,28 @@ public:
 };
 
 // This instance will show up in any translation unit that uses
-// SystemTools. It will make sure SystemTools is initialized 
+// SystemTools. It will make sure SystemTools is initialized
 // before it is used and is the last static object destroyed.
 static SystemToolsManager SystemToolsManagerInstance;
 
+// Flags for use with TestFileAccess.  Use a typedef in case any operating
+// system in the future needs a special type.  These are flags that may be
+// combined using the | operator.
+typedef int TestFilePermissions;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  // On Windows (VC and Borland), no system header defines these constants...
+  static const TestFilePermissions TEST_FILE_OK = 0;
+  static const TestFilePermissions TEST_FILE_READ = 4;
+  static const TestFilePermissions TEST_FILE_WRITE = 2;
+  static const TestFilePermissions TEST_FILE_EXECUTE = 1;
+#else
+  // Standard POSIX constants
+  static const TestFilePermissions TEST_FILE_OK = F_OK;
+  static const TestFilePermissions TEST_FILE_READ = R_OK;
+  static const TestFilePermissions TEST_FILE_WRITE = W_OK;
+  static const TestFilePermissions TEST_FILE_EXECUTE = X_OK;
+#endif
+
 /** \class SystemTools
  * \brief A collection of useful platform-independent system functions.
  */
@@ -89,9 +107,9 @@ public:
    * then an underscore is prepended.  Note that this can produce
    * identifiers that the standard reserves (_[A-Z].* and __.*).
    */
-  static kwsys_stl::string MakeCidentifier(const kwsys_stl::string& s);
+  static std::string MakeCidentifier(const std::string& s);
 
-  static kwsys_stl::string MakeCindentifier(const kwsys_stl::string& s)
+  static std::string MakeCindentifier(const std::string& s)
   {
     return MakeCidentifier(s);
   }
@@ -99,46 +117,46 @@ public:
   /**
    * Replace replace all occurences of the string in the source string.
    */
-  static void ReplaceString(kwsys_stl::string& source,
+  static void ReplaceString(std::string& source,
                             const char* replace,
                             const char* with);
-  static void ReplaceString(kwsys_stl::string& source,
-                            const kwsys_stl::string& replace,
-                            const kwsys_stl::string& with);
+  static void ReplaceString(std::string& source,
+                            const std::string& replace,
+                            const std::string& with);
 
   /**
    * Return a capitalized string (i.e the first letter is uppercased,
    * all other are lowercased).
    */
-  static kwsys_stl::string Capitalized(const kwsys_stl::string&);
-  
+  static std::string Capitalized(const std::string&);
+
   /**
    * Return a 'capitalized words' string (i.e the first letter of each word
    * is uppercased all other are left untouched though).
    */
-  static kwsys_stl::string CapitalizedWords(const kwsys_stl::string&);
-  
+  static std::string CapitalizedWords(const std::string&);
+
   /**
    * Return a 'uncapitalized words' string (i.e the first letter of each word
    * is lowercased all other are left untouched though).
    */
-  static kwsys_stl::string UnCapitalizedWords(const kwsys_stl::string&);
-  
+  static std::string UnCapitalizedWords(const std::string&);
+
   /**
    * Return a lower case string
    */
-  static kwsys_stl::string LowerCase(const kwsys_stl::string&);
-  
+  static std::string LowerCase(const std::string&);
+
   /**
    * Return a lower case string
    */
-  static kwsys_stl::string UpperCase(const kwsys_stl::string&);
-  
+  static std::string UpperCase(const std::string&);
+
   /**
    * Count char in string
    */
   static size_t CountChar(const char* str, char c);
-  
+
   /**
    * Remove some characters from a string.
    * Return a pointer to the new resulting string (allocated with 'new')
@@ -150,52 +168,52 @@ public:
    * Return a pointer to the new resulting string (allocated with 'new')
    */
   static char* RemoveCharsButUpperHex(const char* str);
-  
+
   /**
    * Replace some characters by another character in a string (in-place)
    * Return a pointer to string
    */
   static char* ReplaceChars(char* str, const char *toreplace,char replacement);
-  
+
   /**
    * Returns true if str1 starts (respectively ends) with str2
    */
   static bool StringStartsWith(const char* str1, const char* str2);
-  static bool StringStartsWith(const kwsys_stl::string& str1, const char* str2);
+  static bool StringStartsWith(const std::string& str1, const char* str2);
   static bool StringEndsWith(const char* str1, const char* str2);
-  static bool StringEndsWith(const kwsys_stl::string& str1, const char* str2);
+  static bool StringEndsWith(const std::string& str1, const char* str2);
 
   /**
    * Returns a pointer to the last occurence of str2 in str1
    */
   static const char* FindLastString(const char* str1, const char* str2);
-  
+
   /**
    * Make a duplicate of the string similar to the strdup C function
    * but use new to create the 'new' string, so one can use
    * 'delete' to remove it. Returns 0 if the input is empty.
    */
   static char* DuplicateString(const char* str);
-  
+
   /**
    * Return the string cropped to a given length by removing chars in the
    * center of the string and replacing them with an ellipsis (...)
    */
-  static kwsys_stl::string CropString(const kwsys_stl::string&,size_t max_len);
-  
+  static std::string CropString(const std::string&,size_t max_len);
+
   /** split a path by separator into an array of strings, default is /.
       If isPath is true then the string is treated like a path and if
       s starts with a / then the first element of the returned array will
       be /, so /foo/bar will be [/, foo, bar]
-  */  
-  static kwsys_stl::vector<String> SplitString(const kwsys_stl::string& s, char separator = '/',
+  */
+  static std::vector<String> SplitString(const std::string& s, char separator = '/',
                                                bool isPath = false);
   /**
    * Perform a case-independent string comparison
    */
   static int Strucmp(const char *s1, const char *s2);
 
-  /** 
+  /**
    * Convert a string in __DATE__ or __TIMESTAMP__ format into a time_t.
    * Return false on error, true on success
    */
@@ -206,16 +224,16 @@ public:
    * Split a string on its newlines into multiple lines
    * Return false only if the last line stored had no newline
    */
-  static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l);
-  static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l, char separator);
-  
-  /** 
+  static bool Split(const std::string& s, std::vector<std::string>& l);
+  static bool Split(const std::string& s, std::vector<std::string>& l, char separator);
+
+  /**
    * Return string with space added between capitalized words
    * (i.e. EatMyShorts becomes Eat My Shorts )
-   * (note that IEatShorts becomes IEat Shorts) 
+   * (note that IEatShorts becomes IEat Shorts)
    */
-  static kwsys_stl::string AddSpaceBetweenCapitalizedWords(
-    const kwsys_stl::string&);
+  static std::string AddSpaceBetweenCapitalizedWords(
+    const std::string&);
 
   /**
    * Append two or more strings and produce new one.
@@ -242,7 +260,7 @@ public:
   /**
    * Escape specific characters in 'str'.
    */
-  static kwsys_stl::string EscapeChars(
+  static std::string EscapeChars(
     const char *str, const char *chars_to_escape, char escape_char = '\\');
 
   /** -----------------------------------------------------------------
@@ -253,7 +271,7 @@ public:
   /**
    * Replace Windows file system slashes with Unix-style slashes.
    */
-  static void ConvertToUnixSlashes(kwsys_stl::string& path);
+  static void ConvertToUnixSlashes(std::string& path);
 
 #ifdef _WIN32
   /**
@@ -263,20 +281,20 @@ public:
    * will be prefixed with \\?\UNC\. All output will also be converted to
    * absolute paths with Windows-style backslashes.
    **/
-  static kwsys_stl::wstring ConvertToWindowsExtendedPath(const kwsys_stl::string&);
+  static std::wstring ConvertToWindowsExtendedPath(const std::string&);
 #endif
 
   /**
    * For windows this calls ConvertToWindowsOutputPath and for unix
    * it calls ConvertToUnixOutputPath
    */
-  static kwsys_stl::string ConvertToOutputPath(const kwsys_stl::string&);
+  static std::string ConvertToOutputPath(const std::string&);
 
   /**
    * Convert the path to a string that can be used in a unix makefile.
    * double slashes are removed, and spaces are escaped.
    */
-  static kwsys_stl::string ConvertToUnixOutputPath(const kwsys_stl::string&);
+  static std::string ConvertToUnixOutputPath(const std::string&);
 
   /**
    * Convert the path to string that can be used in a windows project or
@@ -284,18 +302,35 @@ public:
    * the string, the slashes are converted to windows style backslashes, and
    * if there are spaces in the string it is double quoted.
    */
-  static kwsys_stl::string ConvertToWindowsOutputPath(const kwsys_stl::string&);
+  static std::string ConvertToWindowsOutputPath(const std::string&);
 
   /**
    * Return true if a file exists in the current directory.
-   * If isFile = true, then make sure the file is a file and 
+   * If isFile = true, then make sure the file is a file and
    * not a directory.  If isFile = false, then return true
-   * if it is a file or a directory.
+   * if it is a file or a directory.  Note that the file will
+   * also be checked for read access.  (Currently, this check
+   * for read access is only done on POSIX systems.)
    */
   static bool FileExists(const char* filename, bool isFile);
-  static bool FileExists(const kwsys_stl::string& filename, bool isFile);
+  static bool FileExists(const std::string& filename, bool isFile);
   static bool FileExists(const char* filename);
-  static bool FileExists(const kwsys_stl::string& filename);
+  static bool FileExists(const std::string& filename);
+
+  /**
+   * Test if a file exists and can be accessed with the requested
+   * permissions.  Symbolic links are followed.  Returns true if
+   * the access test was successful.
+   *
+   * On POSIX systems (including Cygwin), this maps to the access
+   * function.  On Windows systems, all existing files are
+   * considered readable, and writable files are considered to
+   * have the read-only file attribute cleared.
+   */
+  static bool TestFileAccess(const char* filename,
+                             TestFilePermissions permissions);
+  static bool TestFileAccess(const std::string& filename,
+                             TestFilePermissions permissions);
 
   /**
    * Converts Cygwin path to Win32 path. Uses dictionary container for
@@ -309,21 +344,21 @@ public:
   /**
    * Return file length
    */
-  static unsigned long FileLength(const kwsys_stl::string& filename);
+  static unsigned long FileLength(const std::string& filename);
 
   /**
      Change the modification time or create a file
   */
-  static bool Touch(const kwsys_stl::string& filename, bool create);
-  
+  static bool Touch(const std::string& filename, bool create);
+
   /**
    *  Compare file modification times.
    *  Return true for successful comparison and false for error.
    *  When true is returned, result has -1, 0, +1 for
    *  f1 older, same, or newer than f2.
    */
-  static bool FileTimeCompare(const kwsys_stl::string& f1,
-                              const kwsys_stl::string& f2,
+  static bool FileTimeCompare(const std::string& f1,
+                              const std::string& f2,
                               int* result);
 
   /**
@@ -338,17 +373,17 @@ public:
    *  does not exist path is returned unchanged.  This does nothing
    *  on unix but return path.
    */
-  static kwsys_stl::string GetActualCaseForPath(const kwsys_stl::string& path);
+  static std::string GetActualCaseForPath(const std::string& path);
 
   /**
    * Given the path to a program executable, get the directory part of
    * the path with the file stripped off.  If there is no directory
    * part, the empty string is returned.
    */
-  static kwsys_stl::string GetProgramPath(const kwsys_stl::string&);
-  static bool SplitProgramPath(const kwsys_stl::string& in_name,
-                               kwsys_stl::string& dir,
-                               kwsys_stl::string& file,
+  static std::string GetProgramPath(const std::string&);
+  static bool SplitProgramPath(const std::string& in_name,
+                               std::string& dir,
+                               std::string& file,
                                bool errorReport = true);
 
   /**
@@ -358,14 +393,14 @@ public:
    *  to the running executable.  If argv0 is not a full path,
    *  then this will try to find the full path.  If the path is not
    *  found false is returned, if found true is returned.  An error
-   *  message of the attempted paths is stored in errorMsg.  
+   *  message of the attempted paths is stored in errorMsg.
    *  exeName is the name of the executable.
    *  buildDir is a possibly null path to the build directory.
    *  installPrefix is a possibly null pointer to the install directory.
    */
   static bool FindProgramPath(const char* argv0,
-                              kwsys_stl::string& pathOut,
-                              kwsys_stl::string& errorMsg,
+                              std::string& pathOut,
+                              std::string& errorMsg,
                               const char* exeName = 0,
                               const char* buildDir = 0,
                               const char* installPrefix = 0);
@@ -376,21 +411,21 @@ public:
    * (which defaults to the current working directory).  The full path
    * is returned.
    */
-  static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative);
-  static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative,
+  static std::string CollapseFullPath(const std::string& in_relative);
+  static std::string CollapseFullPath(const std::string& in_relative,
                                             const char* in_base);
-  static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative,
-                                            const kwsys_stl::string& in_base);
+  static std::string CollapseFullPath(const std::string& in_relative,
+                                            const std::string& in_base);
 
-  /** 
+  /**
    * Get the real path for a given path, removing all symlinks.  In
    * the event of an error (non-existent path, permissions issue,
    * etc.) the original path is returned if errorMessage pointer is
    * NULL.  Otherwise empty string is returned and errorMessage
    * contains error description.
    */
-  static kwsys_stl::string GetRealPath(const kwsys_stl::string& path,
-                                       kwsys_stl::string* errorMessage = 0);
+  static std::string GetRealPath(const std::string& path,
+                                       std::string* errorMessage = 0);
 
   /**
    * Split a path name into its root component and the rest of the
@@ -408,7 +443,7 @@ public:
    * given.
    */
   static const char* SplitPathRootComponent(const std::string& p,
-                                            kwsys_stl::string* root=0);
+                                            std::string* root=0);
 
   /**
    * Split a path name into its basic components.  The first component
@@ -421,77 +456,77 @@ public:
    * platform supports them.
    */
   static void SplitPath(const std::string& p,
-                        kwsys_stl::vector<kwsys_stl::string>& components,
+                        std::vector<std::string>& components,
                         bool expand_home_dir = true);
 
   /**
    * Join components of a path name into a single string.  See
    * SplitPath for the format of the components.
    */
-  static kwsys_stl::string JoinPath(
-    const kwsys_stl::vector<kwsys_stl::string>& components);
-  static kwsys_stl::string JoinPath(
-    kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
-    kwsys_stl::vector<kwsys_stl::string>::const_iterator last);
+  static std::string JoinPath(
+    const std::vector<std::string>& components);
+  static std::string JoinPath(
+    std::vector<std::string>::const_iterator first,
+    std::vector<std::string>::const_iterator last);
 
   /**
    * Compare a path or components of a path.
    */
-  static bool ComparePath(const kwsys_stl::string& c1, const kwsys_stl::string& c2);
+  static bool ComparePath(const std::string& c1, const std::string& c2);
 
 
   /**
    * Return path of a full filename (no trailing slashes)
    */
-  static kwsys_stl::string GetFilenamePath(const kwsys_stl::string&);
+  static std::string GetFilenamePath(const std::string&);
 
   /**
    * Return file name of a full filename (i.e. file name without path)
    */
-  static kwsys_stl::string GetFilenameName(const kwsys_stl::string&);
+  static std::string GetFilenameName(const std::string&);
 
   /**
    * Split a program from its arguments and handle spaces in the paths
    */
   static void SplitProgramFromArgs(
-    const kwsys_stl::string& path,
-    kwsys_stl::string& program, kwsys_stl::string& args);
+    const std::string& path,
+    std::string& program, std::string& args);
 
   /**
    * Return longest file extension of a full filename (dot included)
    */
-  static kwsys_stl::string GetFilenameExtension(const kwsys_stl::string&);
+  static std::string GetFilenameExtension(const std::string&);
 
   /**
    * Return shortest file extension of a full filename (dot included)
    */
-  static kwsys_stl::string GetFilenameLastExtension(
-    const kwsys_stl::string& filename);
-  
+  static std::string GetFilenameLastExtension(
+    const std::string& filename);
+
   /**
    * Return file name without extension of a full filename
    */
-  static kwsys_stl::string GetFilenameWithoutExtension(
-    const kwsys_stl::string&);
-  
+  static std::string GetFilenameWithoutExtension(
+    const std::string&);
+
   /**
    * Return file name without its last (shortest) extension
    */
-  static kwsys_stl::string GetFilenameWithoutLastExtension(
-    const kwsys_stl::string&);
-  
+  static std::string GetFilenameWithoutLastExtension(
+    const std::string&);
+
   /**
    * Return whether the path represents a full path (not relative)
    */
-  static bool FileIsFullPath(const kwsys_stl::string&);
+  static bool FileIsFullPath(const std::string&);
   static bool FileIsFullPath(const char*);
-  
+
   /**
    * For windows return the short path for the given path,
    * Unix just a pass through
    */
-  static bool GetShortPath(const kwsys_stl::string& path, kwsys_stl::string& result);
-  
+  static bool GetShortPath(const std::string& path, std::string& result);
+
   /**
    * Read line from file. Make sure to get everything. Due to a buggy stream
    * library on the HP and another on Mac OS X, we need this very carefully
@@ -499,20 +534,20 @@ public:
    * end-of-file was reached. If the has_newline argument is specified, it will
    * be true when the line read had a newline character.
    */
-  static bool GetLineFromStream(kwsys_ios::istream& istr, 
-                                kwsys_stl::string& line,
+  static bool GetLineFromStream(std::istream& istr,
+                                std::string& line,
                                 bool* has_newline=0,
                                 long sizeLimit=-1);
 
   /**
    * Get the parent directory of the directory or file
    */
-  static kwsys_stl::string GetParentDirectory(const kwsys_stl::string& fileOrDir);
+  static std::string GetParentDirectory(const std::string& fileOrDir);
 
   /**
    * Check if the given file or directory is in subdirectory of dir
    */
-  static bool IsSubDirectory(const kwsys_stl::string& fileOrDir, const kwsys_stl::string& dir);
+  static bool IsSubDirectory(const std::string& fileOrDir, const std::string& dir);
 
   /** -----------------------------------------------------------------
    *               File Manipulation Routines
@@ -522,44 +557,44 @@ public:
   /**
    * Open a file considering unicode.
    */
-  static FILE* Fopen(const kwsys_stl::string& file, const char* mode);
+  static FILE* Fopen(const std::string& file, const char* mode);
 
   /**
    * Make a new directory if it is not there.  This function
    * can make a full path even if none of the directories existed
-   * prior to calling this function.  
+   * prior to calling this function.
    */
   static bool MakeDirectory(const char* path);
-  static bool MakeDirectory(const kwsys_stl::string& path);
+  static bool MakeDirectory(const std::string& path);
 
   /**
    * Copy the source file to the destination file only
    * if the two files differ.
    */
-  static bool CopyFileIfDifferent(const kwsys_stl::string& source,
-                                  const kwsys_stl::string& destination);
+  static bool CopyFileIfDifferent(const std::string& source,
+                                  const std::string& destination);
 
   /**
    * Compare the contents of two files.  Return true if different
    */
-  static bool FilesDiffer(const kwsys_stl::string& source, const kwsys_stl::string& destination);
+  static bool FilesDiffer(const std::string& source, const std::string& destination);
 
   /**
    * Return true if the two files are the same file
    */
-  static bool SameFile(const kwsys_stl::string& file1, const kwsys_stl::string& file2);
+  static bool SameFile(const std::string& file1, const std::string& file2);
 
   /**
    * Copy a file.
    */
-  static bool CopyFileAlways(const kwsys_stl::string& source, const kwsys_stl::string& destination);
+  static bool CopyFileAlways(const std::string& source, const std::string& destination);
 
   /**
    * Copy a file.  If the "always" argument is true the file is always
    * copied.  If it is false, the file is copied only if it is new or
    * has changed.
    */
-  static bool CopyAFile(const kwsys_stl::string& source, const kwsys_stl::string& destination,
+  static bool CopyAFile(const std::string& source, const std::string& destination,
                         bool always = true);
 
   /**
@@ -568,18 +603,18 @@ public:
    * always copied.  If it is false, only files that have changed or
    * are new are copied.
    */
-  static bool CopyADirectory(const kwsys_stl::string& source, const kwsys_stl::string& destination,
+  static bool CopyADirectory(const std::string& source, const std::string& destination,
                              bool always = true);
-  
+
   /**
    * Remove a file
    */
-  static bool RemoveFile(const kwsys_stl::string& source);
-  
+  static bool RemoveFile(const std::string& source);
+
   /**
    * Remove a directory
    */
-  static bool RemoveADirectory(const kwsys_stl::string& source);
+  static bool RemoveADirectory(const std::string& source);
 
   /**
    * Get the maximum full file path length
@@ -589,57 +624,57 @@ public:
   /**
    * Find a file in the system PATH, with optional extra paths
    */
-  static kwsys_stl::string FindFile(
-    const kwsys_stl::string& name,
-    const kwsys_stl::vector<kwsys_stl::string>& path = 
-    kwsys_stl::vector<kwsys_stl::string>(),
+  static std::string FindFile(
+    const std::string& name,
+    const std::vector<std::string>& path =
+    std::vector<std::string>(),
     bool no_system_path = false);
 
   /**
    * Find a directory in the system PATH, with optional extra paths
    */
-  static kwsys_stl::string FindDirectory(
-    const kwsys_stl::string& name,
-    const kwsys_stl::vector<kwsys_stl::string>& path = 
-    kwsys_stl::vector<kwsys_stl::string>(),
+  static std::string FindDirectory(
+    const std::string& name,
+    const std::vector<std::string>& path =
+    std::vector<std::string>(),
     bool no_system_path = false);
 
   /**
    * Find an executable in the system PATH, with optional extra paths
    */
-  static kwsys_stl::string FindProgram(
+  static std::string FindProgram(
     const char* name,
-    const kwsys_stl::vector<kwsys_stl::string>& path =
-    kwsys_stl::vector<kwsys_stl::string>(),
+    const std::vector<std::string>& path =
+    std::vector<std::string>(),
     bool no_system_path = false);
-  static kwsys_stl::string FindProgram(
-    const kwsys_stl::string& name,
-    const kwsys_stl::vector<kwsys_stl::string>& path =
-    kwsys_stl::vector<kwsys_stl::string>(),
+  static std::string FindProgram(
+    const std::string& name,
+    const std::vector<std::string>& path =
+    std::vector<std::string>(),
     bool no_system_path = false);
-  static kwsys_stl::string FindProgram(
-    const kwsys_stl::vector<kwsys_stl::string>& names,
-    const kwsys_stl::vector<kwsys_stl::string>& path =
-    kwsys_stl::vector<kwsys_stl::string>(),
+  static std::string FindProgram(
+    const std::vector<std::string>& names,
+    const std::vector<std::string>& path =
+    std::vector<std::string>(),
     bool no_system_path = false);
 
   /**
    * Find a library in the system PATH, with optional extra paths
    */
-  static kwsys_stl::string FindLibrary(
-    const kwsys_stl::string& name,
-    const kwsys_stl::vector<kwsys_stl::string>& path);
-  
+  static std::string FindLibrary(
+    const std::string& name,
+    const std::vector<std::string>& path);
+
   /**
    * Return true if the file is a directory
    */
-  static bool FileIsDirectory(const kwsys_stl::string& name);
-  
+  static bool FileIsDirectory(const std::string& name);
+
   /**
    * Return true if the file is a symlink
    */
-  static bool FileIsSymlink(const kwsys_stl::string& name);
-  
+  static bool FileIsSymlink(const std::string& name);
+
   /**
    * Return true if the file has a given signature (first set of bytes)
    */
@@ -655,28 +690,28 @@ public:
    * The algorithm is simplistic, and should probably check for usual file
    * extensions, 'magic' signature, unicode, etc.
    */
-  enum FileTypeEnum 
-  { 
+  enum FileTypeEnum
+  {
     FileTypeUnknown,
     FileTypeBinary,
     FileTypeText
   };
   static SystemTools::FileTypeEnum DetectFileType(
-    const char* filename, 
-    unsigned long length = 256, 
+    const char* filename,
+    unsigned long length = 256,
     double percent_bin = 0.05);
 
   /**
    * Create a symbolic link if the platform supports it.  Returns whether
    * creation succeded.
    */
-  static bool CreateSymlink(const kwsys_stl::string& origName, const kwsys_stl::string& newName);
+  static bool CreateSymlink(const std::string& origName, const std::string& newName);
 
   /**
    * Read the contents of a symbolic link.  Returns whether reading
    * succeded.
    */
-  static bool ReadSymlink(const kwsys_stl::string& newName, kwsys_stl::string& origName);
+  static bool ReadSymlink(const std::string& newName, std::string& origName);
 
   /**
    * Try to locate the file 'filename' in the directory 'dir'.
@@ -688,47 +723,55 @@ public:
    * 'filename_found' is assigned the fully qualified name/path of the file
    * if it is found (not touched otherwise).
    * If 'try_filename_dirs' is true, try to find the file using the
-   * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt, 
+   * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt,
    * first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar
    * etc.
    * Return true if the file was found, false otherwise.
    */
-  static bool LocateFileInDir(const char *filename, 
-                              const char *dir, 
-                              kwsys_stl::string& filename_found,
+  static bool LocateFileInDir(const char *filename,
+                              const char *dir,
+                              std::string& filename_found,
                               int try_filename_dirs = 0);
 
-  /** compute the relative path from local to remote.  local must 
-      be a directory.  remote can be a file or a directory.  
+  /** compute the relative path from local to remote.  local must
+      be a directory.  remote can be a file or a directory.
       Both remote and local must be full paths.  Basically, if
       you are in directory local and you want to access the file in remote
       what is the relative path to do that.  For example:
       /a/b/c/d to /a/b/c1/d1 -> ../../c1/d1
       from /usr/src to /usr/src/test/blah/foo.cpp -> test/blah/foo.cpp
   */
-  static kwsys_stl::string RelativePath(const kwsys_stl::string& local, const kwsys_stl::string& remote);
+  static std::string RelativePath(const std::string& local, const std::string& remote);
 
   /**
    * Return file's modified time
    */
-  static long int ModifiedTime(const kwsys_stl::string& filename);
+  static long int ModifiedTime(const std::string& filename);
 
   /**
    * Return file's creation time (Win32: works only for NTFS, not FAT)
    */
-  static long int CreationTime(const kwsys_stl::string& filename);
+  static long int CreationTime(const std::string& filename);
 
+  /**
+   * Visual C++ does not define mode_t (note that Borland does, however).
+   */
   #if defined( _MSC_VER )
   typedef unsigned short mode_t;
   #endif
 
   /**
-   * Get and set permissions of the file.
+   * Get and set permissions of the file.  If honor_umask is set, the umask
+   * is queried and applied to the given permissions.  Returns false if
+   * failure.
+   *
+   * WARNING:  A non-thread-safe method is currently used to get the umask
+   * if a honor_umask parameter is set to true.
    */
   static bool GetPermissions(const char* file, mode_t& mode);
-  static bool GetPermissions(const kwsys_stl::string& file, mode_t& mode);
-  static bool SetPermissions(const char* file, mode_t mode);
-  static bool SetPermissions(const kwsys_stl::string& file, mode_t mode);
+  static bool GetPermissions(const std::string& file, mode_t& mode);
+  static bool SetPermissions(const char* file, mode_t mode, bool honor_umask = false);
+  static bool SetPermissions(const std::string& file, mode_t mode, bool honor_umask = false);
 
   /** -----------------------------------------------------------------
    *               Time Manipulation Routines
@@ -741,7 +784,7 @@ public:
   /**
    * Get current date/time
    */
-  static kwsys_stl::string GetCurrentDateTime(const char* format);
+  static std::string GetCurrentDateTime(const char* format);
 
   /** -----------------------------------------------------------------
    *               Registry Manipulation Routines
@@ -758,26 +801,26 @@ public:
   /**
    * Get a list of subkeys.
    */
-  static bool GetRegistrySubKeys(const kwsys_stl::string& key,
-                                 kwsys_stl::vector<kwsys_stl::string>& subkeys,
+  static bool GetRegistrySubKeys(const std::string& key,
+                                 std::vector<std::string>& subkeys,
                                  KeyWOW64 view = KeyWOW64_Default);
 
   /**
    * Read a registry value
    */
-  static bool ReadRegistryValue(const kwsys_stl::string& key, kwsys_stl::string &value,
+  static bool ReadRegistryValue(const std::string& key, std::string &value,
                                 KeyWOW64 view = KeyWOW64_Default);
 
   /**
    * Write a registry value
    */
-  static bool WriteRegistryValue(const kwsys_stl::string& key, const kwsys_stl::string& value,
+  static bool WriteRegistryValue(const std::string& key, const std::string& value,
                                  KeyWOW64 view = KeyWOW64_Default);
 
   /**
    * Delete a registry value
    */
-  static bool DeleteRegistryValue(const kwsys_stl::string& key,
+  static bool DeleteRegistryValue(const std::string& key,
                                   KeyWOW64 view = KeyWOW64_Default);
 
   /** -----------------------------------------------------------------
@@ -790,39 +833,39 @@ public:
    *  string vector passed in.  If env is set then the value
    *  of env will be used instead of PATH.
    */
-  static void GetPath(kwsys_stl::vector<kwsys_stl::string>& path,
+  static void GetPath(std::vector<std::string>& path,
                       const char* env=0);
 
   /**
    * Read an environment variable
    */
   static const char* GetEnv(const char* key);
-  static const char* GetEnv(const kwsys_stl::string& key);
-  static bool GetEnv(const char* key, kwsys_stl::string& result);
-  static bool GetEnv(const kwsys_stl::string& key, kwsys_stl::string& result);
+  static const char* GetEnv(const std::string& key);
+  static bool GetEnv(const char* key, std::string& result);
+  static bool GetEnv(const std::string& key, std::string& result);
 
   /** Put a string into the environment
       of the form var=value */
-  static bool PutEnv(const kwsys_stl::string& env);
+  static bool PutEnv(const std::string& env);
 
   /** Remove a string from the environment.
       Input is of the form "var" or "var=value" (value is ignored). */
-  static bool UnPutEnv(const kwsys_stl::string& env);
+  static bool UnPutEnv(const std::string& env);
 
   /**
    * Get current working directory CWD
    */
-  static kwsys_stl::string GetCurrentWorkingDirectory(bool collapse =true);
+  static std::string GetCurrentWorkingDirectory(bool collapse =true);
 
   /**
    * Change directory to the directory specified
    */
-  static int ChangeDirectory(const kwsys_stl::string& dir);
+  static int ChangeDirectory(const std::string& dir);
 
   /**
    * Get the result of strerror(errno)
    */
-  static kwsys_stl::string GetLastSystemError();
+  static std::string GetLastSystemError();
 
   /**
    * When building DEBUG with MSVC, this enables a hook that prevents
@@ -841,18 +884,18 @@ public:
   /**
    * Add an entry in the path translation table.
    */
-  static void AddTranslationPath(const kwsys_stl::string& dir, const kwsys_stl::string& refdir);
+  static void AddTranslationPath(const std::string& dir, const std::string& refdir);
 
   /**
    * If dir is different after CollapseFullPath is called,
    * Then insert it into the path translation table
    */
-  static void AddKeepPath(const kwsys_stl::string& dir);
+  static void AddKeepPath(const std::string& dir);
 
   /**
    * Update path by going through the Path Translation table;
    */
-  static void CheckTranslationPath(kwsys_stl::string & path);
+  static void CheckTranslationPath(std::string & path);
 
   /**
    * Delay the execution for a specified amount of time specified
@@ -864,7 +907,7 @@ public:
    * Get the operating system name and version
    * This is implemented for Win32 only for the moment
    */
-  static kwsys_stl::string GetOperatingSystemNameAndVersion();
+  static std::string GetOperatingSystemNameAndVersion();
 
   /** -----------------------------------------------------------------
    *               URL Manipulation Routines
@@ -877,9 +920,9 @@ public:
    * and fill protocol as appropriate.
    * Return false if the URL does not have the required form, true otherwise.
    */
-   static bool ParseURLProtocol( const kwsys_stl::string& URL,
-                                 kwsys_stl::string& protocol,
-                                 kwsys_stl::string& dataglom );
+   static bool ParseURLProtocol( const std::string& URL,
+                                 std::string& protocol,
+                                 std::string& dataglom );
 
   /**
    * Parse a string (a URL without protocol prefix) with the form:
@@ -888,13 +931,13 @@ public:
    * when values are found.
    * Return true if the string matches the format; false otherwise.
    */
-  static bool ParseURL( const kwsys_stl::string& URL,
-                        kwsys_stl::string& protocol, 
-                        kwsys_stl::string& username, 
-                        kwsys_stl::string& password, 
-                        kwsys_stl::string& hostname, 
-                        kwsys_stl::string& dataport, 
-                        kwsys_stl::string& datapath );
+  static bool ParseURL( const std::string& URL,
+                        std::string& protocol,
+                        std::string& username,
+                        std::string& password,
+                        std::string& hostname,
+                        std::string& dataport,
+                        std::string& datapath );
 
 private:
   /**
@@ -918,10 +961,10 @@ private:
   /**
    * Actual implementation of ReplaceString.
    */
-  static void ReplaceString(kwsys_stl::string& source,
+  static void ReplaceString(std::string& source,
                             const char* replace,
                             size_t replaceSize,
-                            const kwsys_stl::string& with);
+                            const std::string& with);
 
   /**
    * Actual implementation of FileIsFullPath.
@@ -932,10 +975,10 @@ private:
    * Find a filename (file or directory) in the system PATH, with
    * optional extra paths.
    */
-  static kwsys_stl::string FindName(
-    const kwsys_stl::string& name,
-    const kwsys_stl::vector<kwsys_stl::string>& path = 
-    kwsys_stl::vector<kwsys_stl::string>(),
+  static std::string FindName(
+    const std::string& name,
+    const std::vector<std::string>& path =
+    std::vector<std::string>(),
     bool no_system_path = false);
 
 
@@ -944,7 +987,9 @@ private:
    * Each time 'dir' will be found it will be replace by 'refdir'
    */
   static SystemToolsTranslationMap *TranslationMap;
-  static SystemToolsTranslationMap *LongPathMap;
+#ifdef _WIN32
+  static SystemToolsPathCaseMap *PathCaseMap;
+#endif
 #ifdef __CYGWIN__
   static SystemToolsTranslationMap *Cyg2Win32Map;
 #endif
@@ -953,10 +998,4 @@ private:
 
 } // namespace @KWSYS_NAMESPACE@
 
-/* Undefine temporary macros.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# undef kwsys_stl
-# undef kwsys_ios
-#endif
-
 #endif
diff --git a/Source/kwsys/hash_fun.hxx.in b/Source/kwsys/hash_fun.hxx.in
index 6f787dd..4872b51 100644
--- a/Source/kwsys/hash_fun.hxx.in
+++ b/Source/kwsys/hash_fun.hxx.in
@@ -38,8 +38,8 @@
 #define @KWSYS_NAMESPACE at _hash_fun_hxx
 
 #include <@KWSYS_NAMESPACE@/Configure.hxx>
-#include <@KWSYS_NAMESPACE@/cstddef>        // size_t
-#include <@KWSYS_NAMESPACE@/stl/string>     // string
+#include <stddef.h>        // size_t
+#include <string>
 
 namespace @KWSYS_NAMESPACE@
 {
@@ -55,90 +55,90 @@ inline size_t _stl_hash_string(const char* __s)
   return size_t(__h);
 }
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<char*> {
   size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<const char*> {
   size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
-  struct hash<@KWSYS_NAMESPACE at _stl::string> {
-  size_t operator()(const @KWSYS_NAMESPACE at _stl::string & __s) const { return _stl_hash_string(__s.c_str()); }
+template <>
+  struct hash<std::string> {
+  size_t operator()(const std::string & __s) const { return _stl_hash_string(__s.c_str()); }
 };
 
 #if !defined(__BORLANDC__)
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
-  struct hash<const @KWSYS_NAMESPACE at _stl::string> {
-  size_t operator()(const @KWSYS_NAMESPACE at _stl::string & __s) const { return _stl_hash_string(__s.c_str()); }
+template <>
+  struct hash<const std::string> {
+  size_t operator()(const std::string & __s) const { return _stl_hash_string(__s.c_str()); }
 };
 #endif
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<char> {
   size_t operator()(char __x) const { return __x; }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<unsigned char> {
   size_t operator()(unsigned char __x) const { return __x; }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<signed char> {
   size_t operator()(unsigned char __x) const { return __x; }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<short> {
   size_t operator()(short __x) const { return __x; }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<unsigned short> {
   size_t operator()(unsigned short __x) const { return __x; }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<int> {
   size_t operator()(int __x) const { return __x; }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<unsigned int> {
   size_t operator()(unsigned int __x) const { return __x; }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<long> {
   size_t operator()(long __x) const { return __x; }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<unsigned long> {
   size_t operator()(unsigned long __x) const { return __x; }
 };
 
 // use long long or __int64
 #if @KWSYS_USE_LONG_LONG@
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<long long> {
   size_t operator()(long long __x) const { return __x; }
 };
 
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<unsigned long long> {
   size_t operator()(unsigned long long __x) const { return __x; }
 };
 #elif @KWSYS_USE___INT64@
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<__int64> {
   size_t operator()(__int64 __x) const { return __x; }
 };
- at KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
 struct hash<unsigned __int64> {
   size_t operator()(unsigned __int64 __x) const { return __x; }
 };
diff --git a/Source/kwsys/hash_map.hxx.in b/Source/kwsys/hash_map.hxx.in
index 6d4379d..60c7086 100644
--- a/Source/kwsys/hash_map.hxx.in
+++ b/Source/kwsys/hash_map.hxx.in
@@ -39,7 +39,7 @@
 
 #include <@KWSYS_NAMESPACE@/hashtable.hxx>
 #include <@KWSYS_NAMESPACE@/hash_fun.hxx>
-#include <@KWSYS_NAMESPACE@/stl/functional> // equal_to
+#include <functional> // equal_to
 
 #if defined(_MSC_VER)
 # pragma warning (push)
@@ -58,9 +58,9 @@ namespace @KWSYS_NAMESPACE@
 // select1st is an extension: it is not part of the standard.
 template <class T1, class T2>
 struct hash_select1st:
-    public @KWSYS_NAMESPACE at _stl::unary_function<@KWSYS_NAMESPACE at _stl::pair<T1, T2>, T1>
+    public std::unary_function<std::pair<T1, T2>, T1>
 {
-  const T1& operator()(const @KWSYS_NAMESPACE at _stl::pair<T1, T2>& __x) const
+  const T1& operator()(const std::pair<T1, T2>& __x) const
     { return __x.first; }
 };
 
@@ -68,8 +68,8 @@ struct hash_select1st:
 
 template <class _Key, class _Tp,
           class _HashFcn  = hash<_Key>,
-          class _EqualKey = @KWSYS_NAMESPACE at _stl::equal_to<_Key>,
-          class _Alloc = @KWSYS_NAMESPACE at _HASH_DEFAULT_ALLOCATOR(char) >
+          class _EqualKey = std::equal_to<_Key>,
+          class _Alloc = std::allocator<char> >
 class hash_map;
 
 template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
@@ -81,7 +81,7 @@ template <class _Key, class _Tp, class _HashFcn, class _EqualKey,
 class hash_map
 {
 private:
-  typedef hashtable<@KWSYS_NAMESPACE at _stl::pair<const _Key,_Tp>,_Key,_HashFcn,
+  typedef hashtable<std::pair<const _Key,_Tp>,_Key,_HashFcn,
                     hash_select1st<const _Key,_Tp>,_EqualKey,_Alloc> _Ht;
   _Ht _M_ht;
 
@@ -119,7 +119,6 @@ public:
            const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a) {}
 
-#if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
   template <class _InputIterator>
   hash_map(_InputIterator __f, _InputIterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
@@ -140,48 +139,14 @@ public:
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_unique(__f, __l); }
 
-#else
-  hash_map(const value_type* __f, const value_type* __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_map(const value_type* __f, const value_type* __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_map(const value_type* __f, const value_type* __l, size_type __n,
-           const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_map(const value_type* __f, const value_type* __l, size_type __n,
-           const hasher& __hf, const key_equal& __eql,
-           const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-    { _M_ht.insert_unique(__f, __l); }
-
-  hash_map(const_iterator __f, const_iterator __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_map(const_iterator __f, const_iterator __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_map(const_iterator __f, const_iterator __l, size_type __n,
-           const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_map(const_iterator __f, const_iterator __l, size_type __n,
-           const hasher& __hf, const key_equal& __eql,
-           const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-    { _M_ht.insert_unique(__f, __l); }
-#endif
-
 public:
   size_type size() const { return _M_ht.size(); }
   size_type max_size() const { return _M_ht.max_size(); }
   bool empty() const { return _M_ht.empty(); }
   void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); }
 
-  friend bool operator==@KWSYS_NAMESPACE at _CXX_NULL_TEMPLATE_ARGS(const hash_map&,
-                                                                 const hash_map&);
+  friend bool operator==<>(const hash_map&,
+                           const hash_map&);
 
   iterator begin() { return _M_ht.begin(); }
   iterator end() { return _M_ht.end(); }
@@ -189,20 +154,12 @@ public:
   const_iterator end() const { return _M_ht.end(); }
 
 public:
-  @KWSYS_NAMESPACE at _stl::pair<iterator,bool> insert(const value_type& __obj)
+  std::pair<iterator,bool> insert(const value_type& __obj)
     { return _M_ht.insert_unique(__obj); }
-#if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
   template <class _InputIterator>
   void insert(_InputIterator __f, _InputIterator __l)
     { _M_ht.insert_unique(__f,__l); }
-#else
-  void insert(const value_type* __f, const value_type* __l) {
-    _M_ht.insert_unique(__f,__l);
-  }
-  void insert(const_iterator __f, const_iterator __l)
-    { _M_ht.insert_unique(__f, __l); }
-#endif
-  @KWSYS_NAMESPACE at _stl::pair<iterator,bool> insert_noresize(const value_type& __obj)
+  std::pair<iterator,bool> insert_noresize(const value_type& __obj)
     { return _M_ht.insert_unique_noresize(__obj); }
 
   iterator find(const key_type& __key) { return _M_ht.find(__key); }
@@ -215,9 +172,9 @@ public:
 
   size_type count(const key_type& __key) const { return _M_ht.count(__key); }
 
-  @KWSYS_NAMESPACE at _stl::pair<iterator, iterator> equal_range(const key_type& __key)
+  std::pair<iterator, iterator> equal_range(const key_type& __key)
     { return _M_ht.equal_range(__key); }
-  @KWSYS_NAMESPACE at _stl::pair<const_iterator, const_iterator>
+  std::pair<const_iterator, const_iterator>
   equal_range(const key_type& __key) const
     { return _M_ht.equal_range(__key); }
 
@@ -260,8 +217,8 @@ swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
 
 template <class _Key, class _Tp,
           class _HashFcn  = hash<_Key>,
-          class _EqualKey = @KWSYS_NAMESPACE at _stl::equal_to<_Key>,
-          class _Alloc = @KWSYS_NAMESPACE at _HASH_DEFAULT_ALLOCATOR(char) >
+          class _EqualKey = std::equal_to<_Key>,
+          class _Alloc = std::allocator<char> >
 class hash_multimap;
 
 template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
@@ -274,7 +231,7 @@ template <class _Key, class _Tp, class _HashFcn, class _EqualKey,
 class hash_multimap
 {
 private:
-  typedef hashtable<@KWSYS_NAMESPACE at _stl::pair<const _Key, _Tp>, _Key, _HashFcn,
+  typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn,
                     hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc>
           _Ht;
   _Ht _M_ht;
@@ -313,7 +270,6 @@ public:
                 const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a) {}
 
-#if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
   template <class _InputIterator>
   hash_multimap(_InputIterator __f, _InputIterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
@@ -334,48 +290,14 @@ public:
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_equal(__f, __l); }
 
-#else
-  hash_multimap(const value_type* __f, const value_type* __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const value_type* __f, const value_type* __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const value_type* __f, const value_type* __l, size_type __n,
-                const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const value_type* __f, const value_type* __l, size_type __n,
-                const hasher& __hf, const key_equal& __eql,
-                const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-    { _M_ht.insert_equal(__f, __l); }
-
-  hash_multimap(const_iterator __f, const_iterator __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const_iterator __f, const_iterator __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const_iterator __f, const_iterator __l, size_type __n,
-                const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multimap(const_iterator __f, const_iterator __l, size_type __n,
-                const hasher& __hf, const key_equal& __eql,
-                const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-    { _M_ht.insert_equal(__f, __l); }
-#endif
-
 public:
   size_type size() const { return _M_ht.size(); }
   size_type max_size() const { return _M_ht.max_size(); }
   bool empty() const { return _M_ht.empty(); }
   void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); }
 
-  friend bool operator==@KWSYS_NAMESPACE at _CXX_NULL_TEMPLATE_ARGS(const hash_multimap&,
-                                                                 const hash_multimap&);
+  friend bool operator==<>(const hash_multimap&,
+                           const hash_multimap&);
 
   iterator begin() { return _M_ht.begin(); }
   iterator end() { return _M_ht.end(); }
@@ -385,17 +307,9 @@ public:
 public:
   iterator insert(const value_type& __obj)
     { return _M_ht.insert_equal(__obj); }
-#if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
   template <class _InputIterator>
   void insert(_InputIterator __f, _InputIterator __l)
     { _M_ht.insert_equal(__f,__l); }
-#else
-  void insert(const value_type* __f, const value_type* __l) {
-    _M_ht.insert_equal(__f,__l);
-  }
-  void insert(const_iterator __f, const_iterator __l)
-    { _M_ht.insert_equal(__f, __l); }
-#endif
   iterator insert_noresize(const value_type& __obj)
     { return _M_ht.insert_equal_noresize(__obj); }
 
@@ -405,9 +319,9 @@ public:
 
   size_type count(const key_type& __key) const { return _M_ht.count(__key); }
 
-  @KWSYS_NAMESPACE at _stl::pair<iterator, iterator> equal_range(const key_type& __key)
+  std::pair<iterator, iterator> equal_range(const key_type& __key)
     { return _M_ht.equal_range(__key); }
-  @KWSYS_NAMESPACE at _stl::pair<const_iterator, const_iterator>
+  std::pair<const_iterator, const_iterator>
   equal_range(const key_type& __key) const
     { return _M_ht.equal_range(__key); }
 
diff --git a/Source/kwsys/hash_set.hxx.in b/Source/kwsys/hash_set.hxx.in
index 5ee01a5..c314979 100644
--- a/Source/kwsys/hash_set.hxx.in
+++ b/Source/kwsys/hash_set.hxx.in
@@ -39,7 +39,7 @@
 
 #include <@KWSYS_NAMESPACE@/hashtable.hxx>
 #include <@KWSYS_NAMESPACE@/hash_fun.hxx>
-#include <@KWSYS_NAMESPACE@/stl/functional> // equal_to
+#include <functional> // equal_to
 
 #if defined(_MSC_VER)
 # pragma warning (push)
@@ -57,7 +57,7 @@ namespace @KWSYS_NAMESPACE@
 
 // identity is an extension: it is not part of the standard.
 template <class _Tp>
-struct _Identity : public @KWSYS_NAMESPACE at _stl::unary_function<_Tp,_Tp>
+struct _Identity : public std::unary_function<_Tp,_Tp>
 {
   const _Tp& operator()(const _Tp& __x) const { return __x; }
 };
@@ -66,8 +66,8 @@ struct _Identity : public @KWSYS_NAMESPACE at _stl::unary_function<_Tp,_Tp>
 
 template <class _Value,
           class _HashFcn  = hash<_Value>,
-          class _EqualKey = @KWSYS_NAMESPACE at _stl::equal_to<_Value>,
-          class _Alloc = @KWSYS_NAMESPACE at _HASH_DEFAULT_ALLOCATOR(char) >
+          class _EqualKey = std::equal_to<_Value>,
+          class _Alloc = std::allocator<char> >
 class hash_set;
 
 template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
@@ -116,7 +116,6 @@ public:
            const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a) {}
 
-#if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
   template <class _InputIterator>
   hash_set(_InputIterator __f, _InputIterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
@@ -136,40 +135,6 @@ public:
            const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_unique(__f, __l); }
-#else
-
-  hash_set(const value_type* __f, const value_type* __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_set(const value_type* __f, const value_type* __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_set(const value_type* __f, const value_type* __l, size_type __n,
-           const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_set(const value_type* __f, const value_type* __l, size_type __n,
-           const hasher& __hf, const key_equal& __eql,
-           const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-    { _M_ht.insert_unique(__f, __l); }
-
-  hash_set(const_iterator __f, const_iterator __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_set(const_iterator __f, const_iterator __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_set(const_iterator __f, const_iterator __l, size_type __n,
-           const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-    { _M_ht.insert_unique(__f, __l); }
-  hash_set(const_iterator __f, const_iterator __l, size_type __n,
-           const hasher& __hf, const key_equal& __eql,
-           const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-    { _M_ht.insert_unique(__f, __l); }
-#endif
 
 public:
   size_type size() const { return _M_ht.size(); }
@@ -177,43 +142,35 @@ public:
   bool empty() const { return _M_ht.empty(); }
   void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); }
 
-  friend bool operator==@KWSYS_NAMESPACE at _CXX_NULL_TEMPLATE_ARGS(const hash_set&,
-                                                                 const hash_set&);
+  friend bool operator==<>(const hash_set&,
+                           const hash_set&);
 
   iterator begin() const { return _M_ht.begin(); }
   iterator end() const { return _M_ht.end(); }
 
 public:
-  @KWSYS_NAMESPACE at _stl::pair<iterator, bool> insert(const value_type& __obj)
+  std::pair<iterator, bool> insert(const value_type& __obj)
     {
       typedef typename _Ht::iterator _Ht_iterator;
-      @KWSYS_NAMESPACE at _stl::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique(__obj);
-      return @KWSYS_NAMESPACE at _stl::pair<iterator,bool>(__p.first, __p.second);
+      std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique(__obj);
+      return std::pair<iterator,bool>(__p.first, __p.second);
     }
-#if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
   template <class _InputIterator>
   void insert(_InputIterator __f, _InputIterator __l)
     { _M_ht.insert_unique(__f,__l); }
-#else
-  void insert(const value_type* __f, const value_type* __l) {
-    _M_ht.insert_unique(__f,__l);
-  }
-  void insert(const_iterator __f, const_iterator __l)
-    {_M_ht.insert_unique(__f, __l); }
-#endif
-  @KWSYS_NAMESPACE at _stl::pair<iterator, bool> insert_noresize(const value_type& __obj)
+  std::pair<iterator, bool> insert_noresize(const value_type& __obj)
   {
     typedef typename _Ht::iterator _Ht_iterator;
-    @KWSYS_NAMESPACE at _stl::pair<_Ht_iterator, bool> __p =
+    std::pair<_Ht_iterator, bool> __p =
       _M_ht.insert_unique_noresize(__obj);
-    return @KWSYS_NAMESPACE at _stl::pair<iterator, bool>(__p.first, __p.second);
+    return std::pair<iterator, bool>(__p.first, __p.second);
   }
 
   iterator find(const key_type& __key) const { return _M_ht.find(__key); }
 
   size_type count(const key_type& __key) const { return _M_ht.count(__key); }
 
-  @KWSYS_NAMESPACE at _stl::pair<iterator, iterator> equal_range(const key_type& __key) const
+  std::pair<iterator, iterator> equal_range(const key_type& __key) const
     { return _M_ht.equal_range(__key); }
 
   size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
@@ -254,8 +211,8 @@ swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
 
 template <class _Value,
           class _HashFcn = hash<_Value>,
-          class _EqualKey = @KWSYS_NAMESPACE at _stl::equal_to<_Value>,
-          class _Alloc = @KWSYS_NAMESPACE at _HASH_DEFAULT_ALLOCATOR(char) >
+          class _EqualKey = std::equal_to<_Value>,
+          class _Alloc = std::allocator<char> >
 class hash_multiset;
 
 template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
@@ -305,7 +262,6 @@ public:
                 const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a) {}
 
-#if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
   template <class _InputIterator>
   hash_multiset(_InputIterator __f, _InputIterator __l)
     : _M_ht(100, hasher(), key_equal(), allocator_type())
@@ -325,40 +281,6 @@ public:
                 const allocator_type& __a = allocator_type())
     : _M_ht(__n, __hf, __eql, __a)
     { _M_ht.insert_equal(__f, __l); }
-#else
-
-  hash_multiset(const value_type* __f, const value_type* __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const value_type* __f, const value_type* __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const value_type* __f, const value_type* __l, size_type __n,
-                const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const value_type* __f, const value_type* __l, size_type __n,
-                const hasher& __hf, const key_equal& __eql,
-                const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-    { _M_ht.insert_equal(__f, __l); }
-
-  hash_multiset(const_iterator __f, const_iterator __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const_iterator __f, const_iterator __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const_iterator __f, const_iterator __l, size_type __n,
-                const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-    { _M_ht.insert_equal(__f, __l); }
-  hash_multiset(const_iterator __f, const_iterator __l, size_type __n,
-                const hasher& __hf, const key_equal& __eql,
-                const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-    { _M_ht.insert_equal(__f, __l); }
-#endif
 
 public:
   size_type size() const { return _M_ht.size(); }
@@ -366,8 +288,8 @@ public:
   bool empty() const { return _M_ht.empty(); }
   void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); }
 
-  friend bool operator==@KWSYS_NAMESPACE at _CXX_NULL_TEMPLATE_ARGS(const hash_multiset&,
-                                                                 const hash_multiset&);
+  friend bool operator==<>(const hash_multiset&,
+                           const hash_multiset&);
 
   iterator begin() const { return _M_ht.begin(); }
   iterator end() const { return _M_ht.end(); }
@@ -375,17 +297,9 @@ public:
 public:
   iterator insert(const value_type& __obj)
     { return _M_ht.insert_equal(__obj); }
-#if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
   template <class _InputIterator>
   void insert(_InputIterator __f, _InputIterator __l)
     { _M_ht.insert_equal(__f,__l); }
-#else
-  void insert(const value_type* __f, const value_type* __l) {
-    _M_ht.insert_equal(__f,__l);
-  }
-  void insert(const_iterator __f, const_iterator __l)
-    { _M_ht.insert_equal(__f, __l); }
-#endif
   iterator insert_noresize(const value_type& __obj)
     { return _M_ht.insert_equal_noresize(__obj); }
 
@@ -393,7 +307,7 @@ public:
 
   size_type count(const key_type& __key) const { return _M_ht.count(__key); }
 
-  @KWSYS_NAMESPACE at _stl::pair<iterator, iterator> equal_range(const key_type& __key) const
+  std::pair<iterator, iterator> equal_range(const key_type& __key) const
     { return _M_ht.equal_range(__key); }
 
   size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in
index 7e7dc42..9a20226 100644
--- a/Source/kwsys/hashtable.hxx.in
+++ b/Source/kwsys/hashtable.hxx.in
@@ -44,13 +44,13 @@
 
 #include <@KWSYS_NAMESPACE@/Configure.hxx>
 
-#include <@KWSYS_NAMESPACE@/cstddef>        // size_t
-#include <@KWSYS_NAMESPACE@/stl/algorithm>  // lower_bound
-#include <@KWSYS_NAMESPACE@/stl/functional> // unary_function
-#include <@KWSYS_NAMESPACE@/stl/iterator>   // iterator_traits
-#include <@KWSYS_NAMESPACE@/stl/memory>     // allocator
-#include <@KWSYS_NAMESPACE@/stl/utility>    // pair
-#include <@KWSYS_NAMESPACE@/stl/vector>     // vector
+#include <stddef.h>   // size_t
+#include <algorithm>  // lower_bound
+#include <functional> // unary_function
+#include <iterator>   // iterator_traits
+#include <memory>     // allocator
+#include <utility>    // pair
+#include <vector>     // vector
 
 #if defined(_MSC_VER)
 # pragma warning (push)
@@ -73,238 +73,9 @@
 # endif
 #endif
 
-#if @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_TEMPLATE
-# define @KWSYS_NAMESPACE at _HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE at _stl::allocator< T >
-#elif @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_NONTEMPLATE
-# define @KWSYS_NAMESPACE at _HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE at _stl::allocator
-#else
-# define @KWSYS_NAMESPACE at _HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE at _stl::alloc
-#endif
-
-#if @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_OBJECTS
-# define @KWSYS_NAMESPACE at _HASH_BUCKETS_INIT(__a) _M_buckets(__a)
-# define @KWSYS_NAMESPACE at _HASH_BUCKETS_GET_ALLOCATOR(__b) , __b.get_allocator()
-#else
-# define @KWSYS_NAMESPACE at _HASH_BUCKETS_INIT(__a) _M_buckets()
-# define @KWSYS_NAMESPACE at _HASH_BUCKETS_GET_ALLOCATOR(__b)
-#endif
-
 namespace @KWSYS_NAMESPACE@
 {
 
-//----------------------------------------------------------------------------
-// Define an allocator adaptor for platforms that do not provide an
-// allocator with the rebind member.
-#if !@KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_REBIND
-
-// Utility functions to convert item counts.
-inline size_t hash_sizeof(void*) { return sizeof(char); }
-inline size_t hash_sizeof(const void*) { return sizeof(char); }
-template <class TPtr> inline size_t hash_sizeof(TPtr p)
-{
-  static_cast<void>(p);
-  return sizeof(*p);
-}
-template <class POut, class PIn, class TSize>
-inline TSize hash_allocator_n(POut out, PIn in, TSize n)
-{
-  return n*(hash_sizeof(out)/hash_sizeof(in) +
-            (hash_sizeof(out)%hash_sizeof(in)>0));
-}
-
-// Define an allocation method to use the native allocator with
-// the proper signature.  The following signatures of the allocate
-// method are used on various STL implementations:
-//   pointer allocate(size_type, const void* hint)
-//   pointer allocate(size_type)
-//   static pointer allocate(size_type, const void* hint)
-//   static pointer allocate(size_type)
-// Where pointer might be a real type or void*.
-// This set of overloads decodes the signature for a particular STL.
-// The extra three int/long arguments will favor certain signatures
-// over others in the case that multiple are present to avoid
-// ambiguity errors.
-template <class TAlloc, class PIn, class TSize, class THint, class POut>
-inline void hash_allocate(TAlloc* a, PIn (TAlloc::*allocate)(TSize, THint),
-                          TSize n_out, const void* hint, POut& out,
-                          int, int, int)
-{
-  TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
-  void* vout = (a->*allocate)(n_in, const_cast<THint>(hint));
-  out = static_cast<POut>(vout);
-}
-
-template <class TAlloc, class PIn, class TSize, class POut>
-inline void hash_allocate(TAlloc* a, PIn (TAlloc::*allocate)(TSize),
-                          TSize n_out, const void*, POut& out,
-                          int, int, long)
-{
-  TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
-  void* vout = (a->*allocate)(n_in);
-  out = static_cast<POut>(vout);
-}
-
-template <class PIn, class TSize, class THint, class POut>
-inline void hash_allocate(void*, PIn (*allocate)(TSize, THint),
-                          TSize n_out, const void* hint, POut& out,
-                          int, long, long)
-{
-  TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
-  void* vout = allocate(n_in, const_cast<THint>(hint));
-  out = static_cast<POut>(vout);
-}
-
-template <class PIn, class TSize, class POut>
-inline void hash_allocate(void*, PIn (*allocate)(TSize),
-                          TSize n_out, const void*, POut& out,
-                          long, long, long)
-{
-  TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
-  void* vout = allocate(n_in);
-  out = static_cast<POut>(vout);
-}
-
-// Define a deallocation method to use the native allocator with
-// the proper signature.  The following signatures of the deallocate
-// method are used on various STL implementations:
-//   void deallocate(pointer, size_type)
-//   void deallocate(pointer)
-//   static void deallocate(pointer, size_type)
-//   static void deallocate(pointer)
-// Where pointer might be a real type or void*.
-// This set of overloads decodes the signature for a particular STL.
-// The extra three int/long arguments will favor certain signatures
-// over others in the case that multiple are present to avoid
-// ambiguity errors.
-template <class TAlloc, class PIn, class TSize, class PInReal, class POut>
-inline void hash_deallocate(TAlloc* a, void (TAlloc::*deallocate)(PIn, TSize),
-                            PInReal, POut p, TSize n_out, int, int, int)
-{
-  TSize n_in = hash_allocator_n(POut(), PInReal(), n_out);
-  void* vout = p;
-  (a->*deallocate)(static_cast<PIn>(vout), n_in);
-}
-
-template <class TAlloc, class PIn, class TSize, class PInReal, class POut>
-inline void hash_deallocate(TAlloc* a, void (TAlloc::*deallocate)(PIn),
-                            PInReal, POut p, TSize, int, int, long)
-{
-  void* vout = p;
-  (a->*deallocate)(static_cast<PIn>(vout));
-}
-
-template <class PIn, class TSize, class PInReal, class POut>
-inline void hash_deallocate(void*, void (*deallocate)(PIn, TSize),
-                            PInReal, POut p, TSize n_out, int, long, long)
-{
-  TSize n_in = hash_allocator_n(POut(), PInReal(), n_out);
-  void* vout = p;
-  deallocate(static_cast<PIn>(vout), n_in);
-}
-
-template <class PIn, class TSize, class PInReal, class POut>
-inline void hash_deallocate(void*, void (*deallocate)(PIn),
-                            PInReal, POut p, TSize, long, long, long)
-{
-  void* vout = p;
-  deallocate(static_cast<PIn>(vout));
-}
-
-// Use the same four overloads as hash_allocate to decode the type
-// really used for allocation.  This is passed as PInReal to the
-// deallocate functions so that hash_allocator_n has the proper size.
-template <class TAlloc, class PIn, class TSize, class THint>
-inline PIn hash_allocate_type(PIn (TAlloc::*)(TSize, THint),
-                              int, int, int) { return 0; }
-template <class TAlloc, class PIn, class TSize>
-inline PIn hash_allocate_type(PIn (TAlloc::*)(TSize),
-                              int, int, long) { return 0; }
-template <class PIn, class TSize, class THint>
-inline PIn hash_allocate_type(PIn (*)(TSize, THint),
-                              int, long, long) { return 0; }
-template <class PIn, class TSize>
-inline PIn hash_allocate_type(PIn (*)(TSize),
-                              long, long, long) { return 0; }
-
-// Define the comparison operators in terms of a base type to avoid
-// needing templated versions.
-class hash_allocator_base {};
-inline bool operator==(const hash_allocator_base&,
-                const hash_allocator_base&) throw() { return true; }
-inline bool operator!=(const hash_allocator_base&,
-                const hash_allocator_base&) throw() { return false; }
-
-// Define the allocator template.
-template <class T, class Alloc>
-class hash_allocator: public hash_allocator_base
-{
-private:
-  // Store the real allocator privately.
-  typedef Alloc alloc_type;
-  alloc_type alloc_;
-
-public:
-  // Standard allocator interface.
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef T* pointer;
-  typedef const T* const_pointer;
-  typedef T& reference;
-  typedef const T& const_reference;
-  typedef T value_type;
-
-  hash_allocator() throw(): alloc_() {}
-  hash_allocator(const hash_allocator_base&) throw() : alloc_() {}
-  hash_allocator(const hash_allocator& a) throw() : alloc_(a.alloc_) {}
-  hash_allocator(const alloc_type& a) throw() : alloc_(a) {}
-  ~hash_allocator() throw() {}
-# if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES
-  template <class U>
-  struct rebind { typedef hash_allocator<U, alloc_type> other; };
-# endif
-  pointer address(reference x) const { return &x; }
-  const_pointer address(const_reference x) const { return &x; }
-  typedef void* void_pointer;
-  typedef const void* const_void_pointer;
-  pointer allocate(size_type n=1, const_void_pointer hint = 0)
-    {
-    if(n)
-      {
-      pointer p;
-      hash_allocate(&alloc_, &alloc_type::allocate, n, hint, p, 1, 1, 1);
-      return p;
-      }
-    else
-      {
-      return 0;
-      }
-    }
-  void deallocate(pointer p, size_type n=1)
-    {
-    if(n)
-      {
-      hash_deallocate(&alloc_, &alloc_type::deallocate,
-                      hash_allocate_type(&alloc_type::allocate, 1, 1, 1),
-                      p, n, 1, 1, 1);
-      }
-    }
-#if @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
-  size_type max_size(size_type s) const throw()
-    {
-    return alloc_.max_size(s);
-    }
-#else
-  size_type max_size() const throw()
-    {
-    size_type n = alloc_.max_size() / sizeof(value_type);
-    return n>0? n:1;
-    }
-#endif
-  void construct(pointer p, const value_type& val) { new (p) value_type(val); }
-  void destroy(pointer p) { (void)p; p->~value_type(); }
-};
-#endif
-
 template <class _Val>
 struct _Hashtable_node
 {
@@ -317,7 +88,7 @@ private:
 
 template <class _Val, class _Key, class _HashFcn,
           class _ExtractKey, class _EqualKey,
-          class _Alloc = @KWSYS_NAMESPACE at _HASH_DEFAULT_ALLOCATOR(char) >
+          class _Alloc = std::allocator<char> >
 class hashtable;
 
 template <class _Val, class _Key, class _HashFcn,
@@ -341,7 +112,7 @@ struct _Hashtable_iterator {
           const_iterator;
   typedef _Hashtable_node<_Val> _Node;
 
-  typedef @KWSYS_NAMESPACE at _stl::forward_iterator_tag iterator_category;
+  typedef std::forward_iterator_tag iterator_category;
   typedef _Val value_type;
   typedef ptrdiff_t difference_type;
   typedef size_t size_type;
@@ -378,7 +149,7 @@ struct _Hashtable_const_iterator {
           const_iterator;
   typedef _Hashtable_node<_Val> _Node;
 
-  typedef @KWSYS_NAMESPACE at _stl::forward_iterator_tag iterator_category;
+  typedef std::forward_iterator_tag iterator_category;
   typedef _Val value_type;
   typedef ptrdiff_t difference_type;
   typedef size_t size_type;
@@ -427,7 +198,7 @@ static inline size_t _stl_next_prime(size_t __n)
 {
   const unsigned long* __first = get_stl_prime_list();
   const unsigned long* __last = get_stl_prime_list() + (int)_stl_num_primes;
-  const unsigned long* pos = @KWSYS_NAMESPACE at _stl::lower_bound(__first, __last, __n);
+  const unsigned long* pos = std::lower_bound(__first, __last, __n);
   return pos == __last ? *(__last - 1) : *pos;
 }
 
@@ -470,27 +241,13 @@ public:
 private:
   typedef _Hashtable_node<_Val> _Node;
 
-#if @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_REBIND
 public:
   typedef typename _Alloc::template rebind<_Val>::other allocator_type;
   allocator_type get_allocator() const { return _M_node_allocator; }
 private:
   typedef typename _Alloc::template rebind<_Node>::other _M_node_allocator_type;
   typedef typename _Alloc::template rebind<_Node*>::other _M_node_ptr_allocator_type;
-  typedef @KWSYS_NAMESPACE at _stl::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
-#else
-public:
-  typedef hash_allocator<_Val, _Alloc> allocator_type;
-  allocator_type get_allocator() const { return allocator_type(); }
-private:
-  typedef hash_allocator<_Node, _Alloc> _M_node_allocator_type;
-# if @KWSYS_NAMESPACE at _STL_HAS_ALLOCATOR_OBJECTS
-  typedef hash_allocator<_Node*, _Alloc> _M_node_ptr_allocator_type;
-# else
-  typedef _Alloc _M_node_ptr_allocator_type;
-# endif
-  typedef @KWSYS_NAMESPACE at _stl::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
-#endif
+  typedef std::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
 
 private:
   _M_node_allocator_type _M_node_allocator;
@@ -525,7 +282,7 @@ public:
       _M_hash(__hf),
       _M_equals(__eql),
       _M_get_key(__ext),
-      @KWSYS_NAMESPACE at _HASH_BUCKETS_INIT(__a),
+      _M_buckets(__a),
       _M_num_elements(0)
   {
     _M_initialize_buckets(__n);
@@ -539,7 +296,7 @@ public:
       _M_hash(__hf),
       _M_equals(__eql),
       _M_get_key(_ExtractKey()),
-      @KWSYS_NAMESPACE at _HASH_BUCKETS_INIT(__a),
+      _M_buckets(__a),
       _M_num_elements(0)
   {
     _M_initialize_buckets(__n);
@@ -550,7 +307,7 @@ public:
       _M_hash(__ht._M_hash),
       _M_equals(__ht._M_equals),
       _M_get_key(__ht._M_get_key),
-      @KWSYS_NAMESPACE at _HASH_BUCKETS_INIT(__ht.get_allocator()),
+      _M_buckets(__ht.get_allocator()),
       _M_num_elements(0)
   {
     _M_copy_from(__ht);
@@ -576,11 +333,11 @@ public:
 
   void swap(hashtable& __ht)
   {
-    @KWSYS_NAMESPACE at _stl::swap(_M_hash, __ht._M_hash);
-    @KWSYS_NAMESPACE at _stl::swap(_M_equals, __ht._M_equals);
-    @KWSYS_NAMESPACE at _stl::swap(_M_get_key, __ht._M_get_key);
+    std::swap(_M_hash, __ht._M_hash);
+    std::swap(_M_equals, __ht._M_equals);
+    std::swap(_M_get_key, __ht._M_get_key);
     _M_buckets.swap(__ht._M_buckets);
-    @KWSYS_NAMESPACE at _stl::swap(_M_num_elements, __ht._M_num_elements);
+    std::swap(_M_num_elements, __ht._M_num_elements);
   }
 
   iterator begin()
@@ -603,8 +360,8 @@ public:
 
   const_iterator end() const { return const_iterator(0, this); }
 
-  friend bool operator==@KWSYS_NAMESPACE at _CXX_NULL_TEMPLATE_ARGS(const hashtable&,
-                                                                 const hashtable&);
+  friend bool operator==<>(const hashtable&,
+                           const hashtable&);
 
 public:
 
@@ -621,7 +378,7 @@ public:
     return __result;
   }
 
-  @KWSYS_NAMESPACE at _stl::pair<iterator, bool> insert_unique(const value_type& __obj)
+  std::pair<iterator, bool> insert_unique(const value_type& __obj)
   {
     resize(_M_num_elements + 1);
     return insert_unique_noresize(__obj);
@@ -633,38 +390,26 @@ public:
     return insert_equal_noresize(__obj);
   }
 
-  @KWSYS_NAMESPACE at _stl::pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
+  std::pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
   iterator insert_equal_noresize(const value_type& __obj);
 
-#if @KWSYS_NAMESPACE at _STL_HAS_ITERATOR_TRAITS
-# define @KWSYS_NAMESPACE at _HASH_ITERATOR_CATEGORY(T,I) \
-  typename @KWSYS_NAMESPACE at _stl::iterator_traits< T >::iterator_category()
-#elif @KWSYS_NAMESPACE at _STL_HAS_ITERATOR_CATEGORY
-# define @KWSYS_NAMESPACE at _HASH_ITERATOR_CATEGORY(T,I) \
-  @KWSYS_NAMESPACE at _stl::iterator_category( I )
-#elif @KWSYS_NAMESPACE at _STL_HAS___ITERATOR_CATEGORY
-# define @KWSYS_NAMESPACE at _HASH_ITERATOR_CATEGORY(T,I) \
-  @KWSYS_NAMESPACE at _stl::__iterator_category( I )
-#endif
-
-#if @KWSYS_NAMESPACE at _CXX_HAS_MEMBER_TEMPLATES && defined(@KWSYS_NAMESPACE at _HASH_ITERATOR_CATEGORY)
   template <class _InputIterator>
   void insert_unique(_InputIterator __f, _InputIterator __l)
   {
     insert_unique(__f, __l,
-      @KWSYS_NAMESPACE at _HASH_ITERATOR_CATEGORY(_InputIterator, __f));
+      typename std::iterator_traits<_InputIterator>::iterator_category());
   }
 
   template <class _InputIterator>
   void insert_equal(_InputIterator __f, _InputIterator __l)
   {
     insert_equal(__f, __l,
-      @KWSYS_NAMESPACE at _HASH_ITERATOR_CATEGORY(_InputIterator, __f));
+      typename std::iterator_traits<_InputIterator>::iterator_category());
   }
 
   template <class _InputIterator>
   void insert_unique(_InputIterator __f, _InputIterator __l,
-                     @KWSYS_NAMESPACE at _stl::input_iterator_tag)
+                     std::input_iterator_tag)
   {
     for ( ; __f != __l; ++__f)
       insert_unique(*__f);
@@ -672,7 +417,7 @@ public:
 
   template <class _InputIterator>
   void insert_equal(_InputIterator __f, _InputIterator __l,
-                    @KWSYS_NAMESPACE at _stl::input_iterator_tag)
+                    std::input_iterator_tag)
   {
     for ( ; __f != __l; ++__f)
       insert_equal(*__f);
@@ -680,10 +425,10 @@ public:
 
   template <class _ForwardIterator>
   void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
-                     @KWSYS_NAMESPACE at _stl::forward_iterator_tag)
+                     std::forward_iterator_tag)
   {
     size_type __n = 0;
-    @KWSYS_NAMESPACE at _stl::distance(__f, __l, __n);
+    std::distance(__f, __l, __n);
     resize(_M_num_elements + __n);
     for ( ; __n > 0; --__n, ++__f)
       insert_unique_noresize(*__f);
@@ -691,51 +436,15 @@ public:
 
   template <class _ForwardIterator>
   void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
-                    @KWSYS_NAMESPACE at _stl::forward_iterator_tag)
+                    std::forward_iterator_tag)
   {
     size_type __n = 0;
-    @KWSYS_NAMESPACE at _stl::distance(__f, __l, __n);
+    std::distance(__f, __l, __n);
     resize(_M_num_elements + __n);
     for ( ; __n > 0; --__n, ++__f)
       insert_equal_noresize(*__f);
   }
 
-#else
-  void insert_unique(const value_type* __f, const value_type* __l)
-  {
-    size_type __n = __l - __f;
-    resize(_M_num_elements + __n);
-    for ( ; __n > 0; --__n, ++__f)
-      insert_unique_noresize(*__f);
-  }
-
-  void insert_equal(const value_type* __f, const value_type* __l)
-  {
-    size_type __n = __l - __f;
-    resize(_M_num_elements + __n);
-    for ( ; __n > 0; --__n, ++__f)
-      insert_equal_noresize(*__f);
-  }
-
-  void insert_unique(const_iterator __f, const_iterator __l)
-  {
-    size_type __n = 0;
-    @KWSYS_NAMESPACE at _stl::distance(__f, __l, __n);
-    resize(_M_num_elements + __n);
-    for ( ; __n > 0; --__n, ++__f)
-      insert_unique_noresize(*__f);
-  }
-
-  void insert_equal(const_iterator __f, const_iterator __l)
-  {
-    size_type __n = 0;
-    @KWSYS_NAMESPACE at _stl::distance(__f, __l, __n);
-    resize(_M_num_elements + __n);
-    for ( ; __n > 0; --__n, ++__f)
-      insert_equal_noresize(*__f);
-  }
-#endif
-
   reference find_or_insert(const value_type& __obj);
 
   iterator find(const key_type& __key)
@@ -771,10 +480,10 @@ public:
     return __result;
   }
 
-  @KWSYS_NAMESPACE at _stl::pair<iterator, iterator>
+  std::pair<iterator, iterator>
   equal_range(const key_type& __key);
 
-  @KWSYS_NAMESPACE at _stl::pair<const_iterator, const_iterator>
+  std::pair<const_iterator, const_iterator>
   equal_range(const key_type& __key) const;
 
   size_type erase(const key_type& __key);
@@ -936,7 +645,7 @@ inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
 }
 
 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- at KWSYS_NAMESPACE@_stl::pair<@KWSYS_NAMESPACE at _CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool>
+std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool>
 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
   ::insert_unique_noresize(const value_type& __obj)
 {
@@ -945,13 +654,13 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
 
   for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
     if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
-      return @KWSYS_NAMESPACE at _stl::pair<iterator, bool>(iterator(__cur, this), false);
+      return std::pair<iterator, bool>(iterator(__cur, this), false);
 
   _Node* __tmp = _M_new_node(__obj);
   __tmp->_M_next = __first;
   _M_buckets[__n] = __tmp;
   ++_M_num_elements;
-  return @KWSYS_NAMESPACE at _stl::pair<iterator, bool>(iterator(__tmp, this), true);
+  return std::pair<iterator, bool>(iterator(__tmp, this), true);
 }
 
 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
@@ -999,11 +708,11 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj)
 }
 
 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- at KWSYS_NAMESPACE@_stl::pair<@KWSYS_NAMESPACE at _CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator,
-     @KWSYS_NAMESPACE at _CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator>
+std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator,
+          typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator>
 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
 {
-  typedef @KWSYS_NAMESPACE at _stl::pair<iterator, iterator> _Pii;
+  typedef std::pair<iterator, iterator> _Pii;
   const size_type __n = _M_bkt_num_key(__key);
 
   for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next)
@@ -1021,12 +730,12 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
 }
 
 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- at KWSYS_NAMESPACE@_stl::pair<@KWSYS_NAMESPACE at _CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator,
-     @KWSYS_NAMESPACE at _CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator>
+std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator,
+          typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator>
 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
   ::equal_range(const key_type& __key) const
 {
-  typedef @KWSYS_NAMESPACE at _stl::pair<const_iterator, const_iterator> _Pii;
+  typedef std::pair<const_iterator, const_iterator> _Pii;
   const size_type __n = _M_bkt_num_key(__key);
 
   for (const _Node* __first = _M_buckets[__n] ;
@@ -1164,8 +873,8 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
     const size_type __n = _M_next_size(__num_elements_hint);
     if (__n > __old_n) {
       _M_buckets_type __tmp(
-        __n, (_Node*)(0)
-        @KWSYS_NAMESPACE at _HASH_BUCKETS_GET_ALLOCATOR(_M_buckets));
+        __n, (_Node*)(0),
+        _M_buckets.get_allocator());
       try {
         for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
           _Node* __first = _M_buckets[__bucket];
@@ -1274,14 +983,6 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
 
 } // namespace @KWSYS_NAMESPACE@
 
-// Normally the comparison operators should be found in the @KWSYS_NAMESPACE@
-// namespace by argument dependent lookup.  For compilers that do not
-// support it we must bring them into the global namespace now.
-#if !@KWSYS_NAMESPACE at _CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
-using @KWSYS_NAMESPACE@::operator==;
-using @KWSYS_NAMESPACE@::operator!=;
-#endif
-
 // Undo warning suppression.
 #if defined(__clang__) && defined(__has_warning)
 # if __has_warning("-Wdeprecated")
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index 82620da..94579b3 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -9,110 +9,11 @@
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the License for more information.
 ============================================================================*/
-// Setup for tests that use result of stl namespace test.
-#if defined(KWSYS_STL_HAVE_STD)
-# if KWSYS_STL_HAVE_STD
-#  define kwsys_stl std
-# else
-#  define kwsys_stl
-# endif
-#endif
-
-// Setup for tests that use iostreams.
-#if defined(KWSYS_IOS_USE_ANSI) && defined(KWSYS_IOS_HAVE_STD)
-# if defined(_MSC_VER)
-#  pragma warning (push,1)
-# endif
-# if KWSYS_IOS_USE_ANSI
-#  include <iostream>
-# else
-#  include <iostream.h>
-# endif
-# if defined(_MSC_VER)
-#  pragma warning (pop)
-# endif
-# if KWSYS_IOS_HAVE_STD
-#  define kwsys_ios std
-# else
-#  define kwsys_ios
-# endif
-#endif
-
-#ifdef TEST_KWSYS_STL_HAVE_STD
-#include <list>
-void f(std ::list<int>*) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_ANSI
-#include <iosfwd>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAVE_STD
-#include <iosfwd>
-void f(std ::ostream*) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_SSTREAM
-#include <sstream>
-#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ == 96
-# error "GCC 2.96 stringstream is buggy"
-#endif
-int main()
-{
-  std ::ostringstream ostr;
-  ostr << "hello";
-  if(ostr.str().size() == 5)
-    {
-    return 0;
-    }
-  return -1;
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_STRSTREAM_H
-#include <strstream.h>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_STRSTREA_H
-#include <strstrea.h>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_STRING_HAVE_OSTREAM
-# include <iostream.h>
-# include <string>
-void f(ostream& os, const kwsys_stl::string& s) { os << s; }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_STRING_HAVE_ISTREAM
-# include <iostream.h>
-# include <string>
-void f(istream& is, kwsys_stl::string& s) { is >> s; }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_STRING_HAVE_NEQ_CHAR
-# include <string>
-bool f(const kwsys_stl::string& s) { return s != ""; }
-int main() { return 0; }
-#endif
-
 #ifdef TEST_KWSYS_CXX_HAS_CSTDIO
 #include <cstdio>
 int main() { return 0; }
 #endif
 
-#ifdef TEST_KWSYS_CXX_HAS_CSTDDEF
-#include <cstddef>
-void f(size_t) {}
-int main() { return 0; }
-#endif
-
 #ifdef TEST_KWSYS_CXX_HAS_LONG_LONG
 long long f(long long n) { return n; }
 int main()
@@ -131,150 +32,6 @@ int main()
 }
 #endif
 
-#ifdef TEST_KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS
-template <class T> class A;
-template <class T> int f(A<T>&);
-template <class T> class A
-{
-public:
-  // "friend int f<>(A<T>&)" would conform
-  friend int f(A<T>&);
-private:
-  int x;
-};
-
-template <class T> int f(A<T>& a) { return a.x = 0; }
-template int f(A<int>&);
-
-int main()
-{
-  A<int> a;
-  return f(a);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_MEMBER_TEMPLATES
-template <class U>
-class A
-{
-public:
-  U u;
-  A(): u(0) {}
-  template <class V> V m(V* p) { return *p = u; }
-};
-
-int main()
-{
-  A<short> a;
-  int s = 1;
-  return a.m(&s);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_FULL_SPECIALIZATION
-template <class T> struct A {};
-template <> struct A<int*>
-{
-  static int f() { return 0; }
-};
-int main() { return A<int*>::f(); }
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
-namespace N
-{
-  class A {};
-  int f(A*) { return 0; }
-}
-void f(void*);
-int main()
-{
-  N::A* a = 0;
-  return f(a);
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ITERATOR_TRAITS
-#include <iterator>
-#include <list>
-void f(kwsys_stl::iterator_traits<kwsys_stl::list<int>::iterator>::iterator_category const&) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ITERATOR_CATEGORY
-#include <iterator>
-#include <list>
-void f(kwsys_stl::list<int>::iterator x) { kwsys_stl::iterator_category(x); }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS___ITERATOR_CATEGORY
-#include <iterator>
-#include <list>
-void f(kwsys_stl::list<int>::iterator x) { kwsys_stl::__iterator_category(x); }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_TEMPLATE
-#include <memory>
-template <class Alloc>
-void f(const Alloc&)
-{
-  typedef typename Alloc::size_type alloc_size_type;
-}
-int main()
-{
-  f(kwsys_stl::allocator<char>());
-  return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE
-#include <memory>
-void f(kwsys_stl::allocator::size_type const&) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_REBIND
-#include <memory>
-template <class T, class Alloc>
-void f(const T&, const Alloc&)
-{
-  typedef typename Alloc::template rebind<T>::other alloc_type;
-}
-int main()
-{
-  f(0, kwsys_stl::allocator<char>());
-  return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
-#include <memory>
-void f(kwsys_stl::allocator<char> const& a)
-{
-  a.max_size(sizeof(int));
-}
-int main()
-{
-  f(kwsys_stl::allocator<char>());
-  return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_OBJECTS
-#include <vector>
-void f(kwsys_stl::vector<int> const& v1)
-{
-  kwsys_stl::vector<int>(1, 1, v1.get_allocator());
-}
-int main()
-{
-  f(kwsys_stl::vector<int>());
-  return 0;
-}
-#endif
-
 #ifdef TEST_KWSYS_STAT_HAS_ST_MTIM
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -323,62 +80,55 @@ int main()
 }
 #endif
 
-#ifdef TEST_KWSYS_IOS_HAVE_BINARY
-int test_binary(int, ...)
-{
-  return 0;
-}
-int main()
-{
-  return test_binary(1, kwsys_ios::ios::binary);
-}
-#endif
-
 #ifdef TEST_KWSYS_IOS_HAS_ISTREAM_LONG_LONG
-int test_istream(kwsys_ios::istream& is, long long& x)
+# include <iostream>
+int test_istream(std::istream& is, long long& x)
 {
   return (is >> x)? 1:0;
 }
 int main()
 {
   long long x = 0;
-  return test_istream(kwsys_ios::cin, x);
+  return test_istream(std::cin, x);
 }
 #endif
 
 #ifdef TEST_KWSYS_IOS_HAS_OSTREAM_LONG_LONG
-int test_ostream(kwsys_ios::ostream& os, long long x)
+# include <iostream>
+int test_ostream(std::ostream& os, long long x)
 {
   return (os << x)? 1:0;
 }
 int main()
 {
   long long x = 0;
-  return test_ostream(kwsys_ios::cout, x);
+  return test_ostream(std::cout, x);
 }
 #endif
 
 #ifdef TEST_KWSYS_IOS_HAS_ISTREAM___INT64
-int test_istream(kwsys_ios::istream& is, __int64& x)
+# include <iostream>
+int test_istream(std::istream& is, __int64& x)
 {
   return (is >> x)? 1:0;
 }
 int main()
 {
   __int64 x = 0;
-  return test_istream(kwsys_ios::cin, x);
+  return test_istream(std::cin, x);
 }
 #endif
 
 #ifdef TEST_KWSYS_IOS_HAS_OSTREAM___INT64
-int test_ostream(kwsys_ios::ostream& os, __int64 x)
+# include <iostream>
+int test_ostream(std::ostream& os, __int64 x)
 {
   return (os << x)? 1:0;
 }
 int main()
 {
   __int64 x = 0;
-  return test_ostream(kwsys_ios::cout, x);
+  return test_ostream(std::cout, x);
 }
 #endif
 
@@ -452,6 +202,19 @@ int main()
 }
 #endif
 
+#ifdef TEST_KWSYS_CXX_HAS_GETLOADAVG
+// Match feature definitions from SystemInformation.cxx
+#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
+# define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+int main()
+{
+  double loadavg[3] = { 0.0, 0.0, 0.0 };
+  return getloadavg(loadavg, 3);
+}
+#endif
+
 #ifdef TEST_KWSYS_CXX_HAS_RLIMIT64
 # if defined(KWSYS_HAS_LFS)
 #  define _LARGEFILE_SOURCE
diff --git a/Source/kwsys/kwsys_cstddef.hxx.in b/Source/kwsys/kwsys_cstddef.hxx.in
deleted file mode 100644
index 925c030..0000000
--- a/Source/kwsys/kwsys_cstddef.hxx.in
+++ /dev/null
@@ -1,35 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE at _cstddef
-#define @KWSYS_NAMESPACE at _cstddef
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-/* Avoid warnings in MSVC standard headers.  */
-#ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# pragma warning (disable: 4786)
-#endif
-
-/* Include the real header.  */
-#if @KWSYS_NAMESPACE at _CXX_HAS_CSTDDEF
-# include <cstddef>
-#else
-# include <stddef.h>
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_ios_fstream.h.in b/Source/kwsys/kwsys_ios_fstream.h.in
deleted file mode 100644
index 4b1a8cf..0000000
--- a/Source/kwsys/kwsys_ios_fstream.h.in
+++ /dev/null
@@ -1,46 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE at _ios_fstream
-#define @KWSYS_NAMESPACE at _ios_fstream
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-#ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# pragma warning (disable: 4995) /* Old streams are deprecated.  */
-#endif
-
-#if @KWSYS_NAMESPACE at _IOS_USE_ANSI
-# include <fstream>
-#else
-# include <fstream.h>
-#endif
-
-#if !@KWSYS_NAMESPACE at _IOS_USE_SSTREAM
-namespace @KWSYS_NAMESPACE at _ios
-{
-  using @KWSYS_NAMESPACE at _ios_namespace::ostream;
-  using @KWSYS_NAMESPACE at _ios_namespace::istream;
-  using @KWSYS_NAMESPACE at _ios_namespace::ofstream;
-  using @KWSYS_NAMESPACE at _ios_namespace::ifstream;
-  using @KWSYS_NAMESPACE at _ios_namespace::ios;
-  using @KWSYS_NAMESPACE at _ios_namespace::endl;
-  using @KWSYS_NAMESPACE at _ios_namespace::flush;
-}
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_ios_iosfwd.h.in b/Source/kwsys/kwsys_ios_iosfwd.h.in
deleted file mode 100644
index f4fafeb..0000000
--- a/Source/kwsys/kwsys_ios_iosfwd.h.in
+++ /dev/null
@@ -1,49 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE at _ios_iosfwd
-#define @KWSYS_NAMESPACE at _ios_iosfwd
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-#ifdef _MSC_VER
-#pragma warning (push, 1)
-#pragma warning (disable: 4702)
-#endif
-
-#if @KWSYS_NAMESPACE at _IOS_USE_ANSI
-# include <iosfwd>
-#else
-class fstream;
-class ifstream;
-class ios;
-class istream;
-class ofstream;
-class ostream;
-#endif
-
-#if !@KWSYS_NAMESPACE at _IOS_USE_SSTREAM
-namespace @KWSYS_NAMESPACE at _ios
-{
-  using @KWSYS_NAMESPACE at _ios_namespace::fstream;
-  using @KWSYS_NAMESPACE at _ios_namespace::ifstream;
-  using @KWSYS_NAMESPACE at _ios_namespace::ios;
-  using @KWSYS_NAMESPACE at _ios_namespace::istream;
-  using @KWSYS_NAMESPACE at _ios_namespace::ofstream;
-  using @KWSYS_NAMESPACE at _ios_namespace::ostream;
-}
-#endif
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_ios_iostream.h.in b/Source/kwsys/kwsys_ios_iostream.h.in
deleted file mode 100644
index 43fc4d5..0000000
--- a/Source/kwsys/kwsys_ios_iostream.h.in
+++ /dev/null
@@ -1,99 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE at _ios_iostream
-#define @KWSYS_NAMESPACE at _ios_iostream
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-#ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# pragma warning (disable: 4995) /* Old streams are deprecated.  */
-#endif
-
-#if @KWSYS_NAMESPACE at _IOS_USE_ANSI
-# include <iostream>
-#else
-# include <iostream.h>
-#endif
-
-// The HP implementation of iostream defines cin, cout, cerr, and clog
-// as macros in order to do thread-private streams.
-// See /opt/aCC/include/iostream/iostream.h for details.
-// This block redefines the macros in a safe way that is also compatible
-// with the HP definitions and the using declarations below.
-
-#if !@KWSYS_NAMESPACE at _IOS_USE_SSTREAM
-# if defined(__HP_aCC) && (defined(HP_THREAD_SAFE) || defined(_THREAD_SAFE))
-#  if defined(cin) && !defined(@KWSYS_NAMESPACE at _IOS_HP_HACK_CIN)
-#   define @KWSYS_NAMESPACE at _IOS_HP_HACK_CIN
-#   undef cin
-#   define cin __tcin.ref()
-#  endif
-#  if defined(cout) && !defined(@KWSYS_NAMESPACE at _IOS_HP_HACK_COUT)
-#   define @KWSYS_NAMESPACE at _IOS_HP_HACK_COUT
-#   undef cout
-#   define cout __tcout.ref()
-#  endif
-#  if defined(cerr) && !defined(@KWSYS_NAMESPACE at _IOS_HP_HACK_CERR)
-#   define @KWSYS_NAMESPACE at _IOS_HP_HACK_CERR
-#   undef cerr
-#   define cerr __tcerr.ref()
-#  endif
-#  if defined(clog) && !defined(@KWSYS_NAMESPACE at _IOS_HP_HACK_CLOG)
-#   define @KWSYS_NAMESPACE at _IOS_HP_HACK_CLOG
-#   undef clog
-#   define clog __tclog.ref()
-#  endif
-# endif
-#endif
-
-// If using our own sstream emulation code, put the standard
-// streams in the same namespace.
-#if !@KWSYS_NAMESPACE at _IOS_USE_SSTREAM
-namespace @KWSYS_NAMESPACE at _ios
-{
-  typedef int streamsize;
-  typedef int streamoff;
-  using @KWSYS_NAMESPACE at _ios_namespace::ostream;
-  using @KWSYS_NAMESPACE at _ios_namespace::istream;
-  using @KWSYS_NAMESPACE at _ios_namespace::ios;
-  using @KWSYS_NAMESPACE at _ios_namespace::endl;
-  using @KWSYS_NAMESPACE at _ios_namespace::flush;
-# if defined(@KWSYS_NAMESPACE at _IOS_HP_HACK_CIN)
-  using @KWSYS_NAMESPACE at _ios_namespace::__tcin;
-# else
-  using @KWSYS_NAMESPACE at _ios_namespace::cin;
-# endif
-# if defined(@KWSYS_NAMESPACE at _IOS_HP_HACK_COUT)
-  using @KWSYS_NAMESPACE at _ios_namespace::__tcout;
-# else
-  using @KWSYS_NAMESPACE at _ios_namespace::cout;
-# endif
-# if defined(@KWSYS_NAMESPACE at _IOS_HP_HACK_CERR)
-  using @KWSYS_NAMESPACE at _ios_namespace::__tcerr;
-# else
-  using @KWSYS_NAMESPACE at _ios_namespace::cerr;
-# endif
-# if defined(@KWSYS_NAMESPACE at _IOS_HP_HACK_CLOG)
-  using @KWSYS_NAMESPACE at _ios_namespace::__tclog;
-# else
-  using @KWSYS_NAMESPACE at _ios_namespace::clog;
-# endif
-}
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_ios_sstream.h.in b/Source/kwsys/kwsys_ios_sstream.h.in
deleted file mode 100644
index 29d250c..0000000
--- a/Source/kwsys/kwsys_ios_sstream.h.in
+++ /dev/null
@@ -1,199 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE at _ios_sstream
-#define @KWSYS_NAMESPACE at _ios_sstream
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-/* Define this macro temporarily to keep the code readable.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE at _stl
-#endif
-
-#if @KWSYS_NAMESPACE at _IOS_USE_SSTREAM
-# ifdef _MSC_VER
-#  pragma warning (push, 1)
-#  pragma warning (disable: 4702)
-# endif
-# include <sstream>
-# ifdef _MSC_VER
-#  pragma warning(pop)
-# endif
-#else
-# ifdef _MSC_VER
-#  pragma warning (push, 1)
-#  pragma warning (disable: 4702)
-#  pragma warning (disable: 4995) /* Old streams are deprecated.  */
-# endif
-# if @KWSYS_NAMESPACE at _IOS_USE_ANSI
-#  include <strstream>
-# elif @KWSYS_NAMESPACE at _IOS_USE_STRSTREAM_H
-#  include <strstream.h>
-# elif @KWSYS_NAMESPACE at _IOS_USE_STRSTREA_H
-#  include <strstrea.h>
-# endif
-# if @KWSYS_NAMESPACE at _IOS_USE_ANSI
-#  include <new> // Need placement operator new.
-# else
-#  include <new.h> // Need placement operator new.
-# endif
-# ifdef _MSC_VER
-#  pragma warning(pop)
-# endif
-
-// Only have old std strstream classes.  Wrap them to look like new
-// ostringstream and istringstream classes.
-
-# include <@KWSYS_NAMESPACE@/stl/string>
-
-namespace @KWSYS_NAMESPACE at _ios
-{
-using @KWSYS_NAMESPACE at _ios_namespace::streambuf;
-using @KWSYS_NAMESPACE at _ios_namespace::ostream;
-using @KWSYS_NAMESPACE at _ios_namespace::istream;
-using @KWSYS_NAMESPACE at _ios_namespace::strstream;
-using @KWSYS_NAMESPACE at _ios_namespace::istrstream;
-using @KWSYS_NAMESPACE at _ios_namespace::ostrstream;
-using @KWSYS_NAMESPACE at _ios_namespace::ios;
-using @KWSYS_NAMESPACE at _ios_namespace::endl;
-using @KWSYS_NAMESPACE at _ios_namespace::ends;
-using @KWSYS_NAMESPACE at _ios_namespace::flush;
-
-class stringstream_cleanup
-{
-public:
-  stringstream_cleanup(strstream& str): m_StrStream(str) {}
-  ~stringstream_cleanup() { m_StrStream.rdbuf()->freeze(0); }
-  static void IgnoreUnusedVariable(const stringstream_cleanup&) {}
-protected:
-  strstream& m_StrStream;
-private:
-  void operator=(stringstream_cleanup const&);
-};
-
-class stringstream: public strstream
-{
-public:
-  typedef strstream Superclass;
-  stringstream() {}
-  stringstream(const kwsys_stl::string& s) { *this << s.c_str(); }
-  kwsys_stl::string str()
-    {
-    stringstream_cleanup cleanup(*this);
-    stringstream_cleanup::IgnoreUnusedVariable(cleanup);
-// Visual Studio 6 has a strstream::pcount, but this is not rdbuf()->pcount()
-#if (@KWSYS_NAMESPACE at _IOS_USE_STRSTREA_H) && defined(_MSC_VER) && (_MSC_VER == 1200)
-    int count = this->pcount();
-#elif defined(__WATCOMC__)
-    int count = this->rdbuf()->out_waiting();
-#else
-    int count = this->rdbuf()->pcount();
-#endif
-    const char* ptr = this->Superclass::str();
-    return kwsys_stl::string(ptr?ptr:"", count);
-    }
-  void str(const kwsys_stl::string& s)
-    {
-    this->~stringstream();
-    new (this) stringstream(s);
-    }
-private:
-  stringstream(const stringstream&);
-  void operator=(const stringstream&);
-};
-
-class ostringstream_cleanup
-{
-public:
-  ostringstream_cleanup(ostrstream& ostr): m_OStrStream(ostr) {}
-  ~ostringstream_cleanup() { m_OStrStream.rdbuf()->freeze(0); }
-  static void IgnoreUnusedVariable(const ostringstream_cleanup&) {}
-protected:
-  ostrstream& m_OStrStream;
-private:
-  void operator=(ostringstream_cleanup const&);
-};
-
-class ostringstream: public ostrstream
-{
-public:
-  typedef ostrstream Superclass;
-  ostringstream() {}
-  ostringstream(const kwsys_stl::string& s) { *this << s.c_str(); }
-  kwsys_stl::string str()
-    {
-    ostringstream_cleanup cleanup(*this);
-    ostringstream_cleanup::IgnoreUnusedVariable(cleanup);
-    int count = this->pcount();
-    const char* ptr = this->Superclass::str();
-    return kwsys_stl::string(ptr?ptr:"", count);
-    }
-  void str(const kwsys_stl::string& s)
-    {
-    this->~ostringstream();
-    new (this) ostringstream(s);
-    }
-private:
-  ostringstream(const ostringstream&);
-  void operator=(const ostringstream&);
-};
-
-#if defined(_MSC_VER)
-# pragma warning (push)
-# pragma warning (disable: 4097) /* typedef-name used as synonym for class */
-#endif
-#if defined(__WATCOMC__)
-// W728: class modifiers for 'A' conflict with class modifiers for 'B'
-# pragma warning 728 10
-#endif
-
-class istringstream: private kwsys_stl::string, public istrstream
-{
-public:
-  typedef kwsys_stl::string StdString;
-  typedef istrstream IStrStream;
-  istringstream(): StdString(),
-                   IStrStream(const_cast<char*>(StdString::c_str())) {}
-  istringstream(const kwsys_stl::string& s):
-    StdString(s), IStrStream(const_cast<char*>(StdString::c_str())) {}
-  kwsys_stl::string str() const { return *this; }
-  void str(const kwsys_stl::string& s)
-    {
-    this->~istringstream();
-    new (this) istringstream(s);
-    }
-  void clear(int flags)
-    {
-    this->IStrStream::clear(flags);
-    }
-private:
-  istringstream(const istringstream&);
-  void operator=(const istringstream&);
-};
-
-#if defined(__WATCOMC__)
-# pragma warning 728 9
-#endif
-#if defined(_MSC_VER)
-# pragma warning (pop)
-#endif
-
-} // namespace @KWSYS_NAMESPACE at _ios
-
-#endif
-
-/* Undefine temporary macro.  */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE at _NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_stl.hxx.in b/Source/kwsys/kwsys_stl.hxx.in
deleted file mode 100644
index 610e6d4..0000000
--- a/Source/kwsys/kwsys_stl.hxx.in
+++ /dev/null
@@ -1,49 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE at _stl_@KWSYS_STL_HEADER@
-#define @KWSYS_NAMESPACE at _stl_@KWSYS_STL_HEADER@
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-/* Avoid warnings in MSVC standard headers.  */
-#ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# pragma warning (disable: 4786)
-#endif
-
-/* The HP standard library defines the functor "times" instead of
-   "multiplies" as specified by C++98 20.3.2 for backward
-   compatibility with earlier specifications.  Defining this macro
-   fixes this behavior.  The name "times" also conflicts with the
-   function declared in sys/times.h on that platform, so we must do
-   this as a work-around anyway.  */
-#if defined(__HP_aCC) && !defined(__HPACC_USING_MULTIPLIES_IN_FUNCTIONAL)
-# define __HPACC_USING_MULTIPLIES_IN_FUNCTIONAL
-# define @KWSYS_NAMESPACE at _DEFINED___HPACC_USING_MULTIPLIES_IN_FUNCTIONAL
-#endif
-
-/* Include the real header.  */
-#include <@KWSYS_STL_HEADER@>
-
-/* Cleanup.  */
-#if defined(@KWSYS_NAMESPACE at _DEFINED___HPACC_USING_MULTIPLIES_IN_FUNCTIONAL)
-# undef @KWSYS_NAMESPACE at _DEFINED___HPACC_USING_MULTIPLIES_IN_FUNCTIONAL
-# undef __HPACC_USING_MULTIPLIES_IN_FUNCTIONAL
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
- at KWSYS_STL_HEADER_EXTRA@
-#endif
diff --git a/Source/kwsys/kwsys_stl_string.hxx.in b/Source/kwsys/kwsys_stl_string.hxx.in
deleted file mode 100644
index cd312cb..0000000
--- a/Source/kwsys/kwsys_stl_string.hxx.in
+++ /dev/null
@@ -1,123 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
-  Distributed under the OSI-approved BSD License (the "License");
-  see accompanying file Copyright.txt for details.
-
-  This software is distributed WITHOUT ANY WARRANTY; without even the
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the License for more information.
-============================================================================*/
-
-// This header is extra code for <@KWSYS_NAMESPACE@/stl/string>.
-#if !defined(@KWSYS_NAMESPACE at _stl_string_including_hxx)
-# error "The header <@KWSYS_NAMESPACE@/stl/string.hxx> may be included only by <@KWSYS_NAMESPACE@/stl/string>."
-#endif
-
-// Provide the istream operator for the stl string if it is not
-// provided by the system or another copy of kwsys.  Allow user code
-// to block this definition by defining the macro
-// @KWSYS_NAMESPACE at _STL_STRING_NO_ISTREAM
-// to avoid conflicts with other libraries.  User code can test for
-// this definition by checking the macro
-// @KWSYS_NAMESPACE at _STL_STRING_ISTREAM_DEFINED
-#if !@KWSYS_NAMESPACE at _STL_STRING_HAVE_ISTREAM && !defined(@KWSYS_NAMESPACE at _STL_STRING_NO_ISTREAM) && !defined(KWSYS_STL_STRING_ISTREAM_DEFINED)
-# define KWSYS_STL_STRING_ISTREAM_DEFINED
-# define @KWSYS_NAMESPACE at _STL_STRING_ISTREAM_DEFINED
-# include <ctype.h> // isspace
-# include <@KWSYS_NAMESPACE@/ios/iostream>
-# if defined(__WATCOMC__)
-namespace @KWSYS_NAMESPACE@
-{
-struct ios_istream_hack: public kwsys_ios::istream
-{ void eatwhite() { this->@KWSYS_NAMESPACE at _ios::istream::eatwhite(); } };
-}
-# endif
-inline @KWSYS_NAMESPACE at _ios::istream&
-operator>>(@KWSYS_NAMESPACE at _ios::istream& is,
-           @KWSYS_NAMESPACE at _stl::string& s)
-{
-  // Keep track of the resulting state.
-  int state = @KWSYS_NAMESPACE at _ios::ios::goodbit;
-
-  // Save the width setting and set it back to zero.
-  size_t n = static_cast<size_t>(is.width(0));
-
-  // Clear any old contents of the output string.
-  s.erase();
-
-  // Skip leading whitespace.
-#if defined(__WATCOMC__)
-  static_cast<@KWSYS_NAMESPACE@::ios_istream_hack&>(is).eatwhite();
-#else
-  is.eatwhite();
-#endif
-  @KWSYS_NAMESPACE at _ios::istream& okay = is;
-
-  if(okay)
-    {
-    // Select a maximum possible length.
-    if(n == 0 || n >= s.max_size())
-      {
-      n = s.max_size();
-      }
-
-    // Read until a space is found or the maximum length is reached.
-    bool success = false;
-    for(int c = is.peek(); (--n > 0 && c != EOF && !isspace(c)); c = is.peek())
-      {
-      s += static_cast<char>(c);
-      success = true;
-      is.ignore();
-      }
-
-    // Set flags for resulting state.
-    if(is.peek() == EOF) { state |= @KWSYS_NAMESPACE at _ios::ios::eofbit; }
-    if(!success) { state |= @KWSYS_NAMESPACE at _ios::ios::failbit; }
-    }
-
-  // Set the final result state.
-  is.clear(state);
-  return is;
-}
-#endif
-
-// Provide the ostream operator for the stl string if it is not
-// provided by the system or another copy of kwsys.  Allow user code
-// to block this definition by defining the macro
-// @KWSYS_NAMESPACE at _STL_STRING_NO_OSTREAM
-// to avoid conflicts with other libraries.  User code can test for
-// this definition by checking the macro
-// @KWSYS_NAMESPACE at _STL_STRING_OSTREAM_DEFINED
-#if !@KWSYS_NAMESPACE at _STL_STRING_HAVE_OSTREAM && !defined(@KWSYS_NAMESPACE at _STL_STRING_NO_OSTREAM) && !defined(KWSYS_STL_STRING_OSTREAM_DEFINED)
-# define KWSYS_STL_STRING_OSTREAM_DEFINED
-# define @KWSYS_NAMESPACE at _STL_STRING_OSTREAM_DEFINED
-# include <@KWSYS_NAMESPACE@/ios/iostream>
-inline @KWSYS_NAMESPACE at _ios::ostream&
-operator<<(@KWSYS_NAMESPACE at _ios::ostream& os,
-           @KWSYS_NAMESPACE at _stl::string const& s)
-{
-  return os << s.c_str();
-}
-#endif
-
-// Provide the operator!= for the stl string and char* if it is not
-// provided by the system or another copy of kwsys.  Allow user code
-// to block this definition by defining the macro
-// @KWSYS_NAMESPACE at _STL_STRING_NO_NEQ_CHAR
-// to avoid conflicts with other libraries.  User code can test for
-// this definition by checking the macro
-// @KWSYS_NAMESPACE at _STL_STRING_NEQ_CHAR_DEFINED
-#if !@KWSYS_NAMESPACE at _STL_STRING_HAVE_NEQ_CHAR && !defined(@KWSYS_NAMESPACE at _STL_STRING_NO_NEQ_CHAR) && !defined(KWSYS_STL_STRING_NEQ_CHAR_DEFINED)
-# define KWSYS_STL_STRING_NEQ_CHAR_DEFINED
-# define @KWSYS_NAMESPACE at _STL_STRING_NEQ_CHAR_DEFINED
-inline bool operator!=(@KWSYS_NAMESPACE at _stl::string const& s, const char* c)
-{
-  return !(s == c);
-}
-inline bool operator!=(const char* c, @KWSYS_NAMESPACE at _stl::string const& s)
-{
-  return !(s == c);
-}
-#endif
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
index 6a03c0f..525522d 100644
--- a/Source/kwsys/testCommandLineArguments.cxx
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -11,16 +11,16 @@
 ============================================================================*/
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(CommandLineArguments.hxx)
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(stl/vector)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
 # include "CommandLineArguments.hxx.in"
-# include "kwsys_ios_iostream.h.in"
 #endif
 
+#include <iostream>
+#include <vector>
+
 #include <stddef.h> /* size_t */
 #include <string.h> /* strcmp */
 
@@ -28,10 +28,10 @@ static void* random_ptr = reinterpret_cast<void*>(0x123);
 
 static int argument(const char* arg, const char* value, void* call_data)
 {
-  kwsys_ios::cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << kwsys_ios::endl;
+  std::cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << std::endl;
   if ( call_data != random_ptr )
     {
-    kwsys_ios::cerr << "Problem processing call_data" << kwsys_ios::endl;
+    std::cerr << "Problem processing call_data" << std::endl;
     return 0;
     }
   return 1;
@@ -39,10 +39,10 @@ static int argument(const char* arg, const char* value, void* call_data)
 
 static int unknown_argument(const char* argument, void* call_data)
 {
-  kwsys_ios::cout << "Got unknown argument: \"" << argument << "\"" << kwsys_ios::endl;
+  std::cout << "Got unknown argument: \"" << argument << "\"" << std::endl;
   if ( call_data != random_ptr )
     {
-    kwsys_ios::cerr << "Problem processing call_data" << kwsys_ios::endl;
+    std::cerr << "Problem processing call_data" << std::endl;
     return 0;
     }
   return 1;
@@ -53,8 +53,8 @@ static bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
 static bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
 static bool CompareTwoItemsOnList(const char* i1,
   const char* i2) { return strcmp(i1, i2) == 0; }
-static bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
-  const kwsys_stl::string& i2) { return i1 == i2; }
+static bool CompareTwoItemsOnList(const std::string& i1,
+  const std::string& i2) { return i1 == i2; }
 
 int testCommandLineArguments(int argc, char* argv[])
 {
@@ -74,26 +74,26 @@ int testCommandLineArguments(int argc, char* argv[])
   int some_int_variable = 10;
   double some_double_variable = 10.10;
   char* some_string_variable = 0;
-  kwsys_stl::string some_stl_string_variable = "";
+  std::string some_stl_string_variable = "";
   bool some_bool_variable = false;
   bool some_bool_variable1 = false;
   bool bool_arg1 = false;
   int bool_arg2 = 0;
 
-  kwsys_stl::vector<int> numbers_argument;
+  std::vector<int> numbers_argument;
   int valid_numbers[] = { 5, 1, 8, 3, 7, 1, 3, 9, 7, 1 };
 
-  kwsys_stl::vector<double> doubles_argument;
+  std::vector<double> doubles_argument;
   double valid_doubles[] = { 12.5, 1.31, 22 };
 
-  kwsys_stl::vector<bool> bools_argument;
+  std::vector<bool> bools_argument;
   bool valid_bools[] = { true, true, false };
 
-  kwsys_stl::vector<char*> strings_argument;
+  std::vector<char*> strings_argument;
   const char* valid_strings[] = { "andy", "bill", "brad", "ken" };
 
-  kwsys_stl::vector<kwsys_stl::string> stl_strings_argument;
-  kwsys_stl::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" };
+  std::vector<std::string> stl_strings_argument;
+  std::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" };
 
   typedef kwsys::CommandLineArguments argT;
 
@@ -122,47 +122,47 @@ int testCommandLineArguments(int argc, char* argv[])
 
   if ( !arg.Parse() )
     {
-    kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
+    std::cerr << "Problem parsing arguments" << std::endl;
     res = 1;
     }
-  kwsys_ios::cout << "Help: " << arg.GetHelp() << kwsys_ios::endl;
+  std::cout << "Help: " << arg.GetHelp() << std::endl;
 
-  kwsys_ios::cout << "Some int variable was set to: " << some_int_variable << kwsys_ios::endl;
-  kwsys_ios::cout << "Some double variable was set to: " << some_double_variable << kwsys_ios::endl;
+  std::cout << "Some int variable was set to: " << some_int_variable << std::endl;
+  std::cout << "Some double variable was set to: " << some_double_variable << std::endl;
   if ( some_string_variable && strcmp(some_string_variable, "test string with space") == 0)
     {
-    kwsys_ios::cout << "Some string variable was set to: " << some_string_variable << kwsys_ios::endl;
+    std::cout << "Some string variable was set to: " << some_string_variable << std::endl;
     delete [] some_string_variable;
     }
   else
     {
-    kwsys_ios::cerr << "Problem setting string variable" << kwsys_ios::endl;
+    std::cerr << "Problem setting string variable" << std::endl;
     res = 1;
     }
   size_t cc;
 #define CompareTwoLists(list1, list_valid, lsize) \
   if ( list1.size() != lsize ) \
     { \
-    kwsys_ios::cerr << "Problem setting " #list1 ". Size is: " << list1.size() \
-     << " should be: " << lsize << kwsys_ios::endl; \
+    std::cerr << "Problem setting " #list1 ". Size is: " << list1.size() \
+     << " should be: " << lsize << std::endl; \
     res = 1; \
     } \
   else \
     { \
-    kwsys_ios::cout << #list1 " argument set:"; \
+    std::cout << #list1 " argument set:"; \
     for ( cc =0; cc < lsize; ++ cc ) \
       { \
-      kwsys_ios::cout << " " << list1[cc]; \
+      std::cout << " " << list1[cc]; \
       if ( !CompareTwoItemsOnList(list1[cc], list_valid[cc]) ) \
         { \
-        kwsys_ios::cerr << "Problem setting " #list1 ". Value of " \
+        std::cerr << "Problem setting " #list1 ". Value of " \
         << cc << " is: [" << list1[cc] << "] <> [" \
-        << list_valid[cc] << "]" << kwsys_ios::endl; \
+        << list_valid[cc] << "]" << std::endl; \
         res = 1; \
         break; \
         } \
       } \
-    kwsys_ios::cout << kwsys_ios::endl; \
+    std::cout << std::endl; \
     }
 
   CompareTwoLists(numbers_argument, valid_numbers, 10);
@@ -171,12 +171,12 @@ int testCommandLineArguments(int argc, char* argv[])
   CompareTwoLists(strings_argument, valid_strings, 4);
   CompareTwoLists(stl_strings_argument, valid_stl_strings, 4);
 
-  kwsys_ios::cout << "Some STL String variable was set to: " << some_stl_string_variable << kwsys_ios::endl;
-  kwsys_ios::cout << "Some bool variable was set to: " << some_bool_variable << kwsys_ios::endl;
-  kwsys_ios::cout << "Some bool variable was set to: " << some_bool_variable1 << kwsys_ios::endl;
-  kwsys_ios::cout << "bool_arg1 variable was set to: " << bool_arg1 << kwsys_ios::endl;
-  kwsys_ios::cout << "bool_arg2 variable was set to: " << bool_arg2 << kwsys_ios::endl;
-  kwsys_ios::cout << kwsys_ios::endl;
+  std::cout << "Some STL String variable was set to: " << some_stl_string_variable << std::endl;
+  std::cout << "Some bool variable was set to: " << some_bool_variable << std::endl;
+  std::cout << "Some bool variable was set to: " << some_bool_variable1 << std::endl;
+  std::cout << "bool_arg1 variable was set to: " << bool_arg1 << std::endl;
+  std::cout << "bool_arg2 variable was set to: " << bool_arg2 << std::endl;
+  std::cout << std::endl;
 
   for ( cc = 0; cc < strings_argument.size(); ++ cc )
     {
diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx
index b65c37f..6eb465d 100644
--- a/Source/kwsys/testCommandLineArguments1.cxx
+++ b/Source/kwsys/testCommandLineArguments1.cxx
@@ -11,16 +11,16 @@
 ============================================================================*/
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(CommandLineArguments.hxx)
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(stl/vector)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
 # include "CommandLineArguments.hxx.in"
-# include "kwsys_ios_iostream.h.in"
 #endif
 
+#include <iostream>
+#include <vector>
+
 #include <assert.h> /* assert */
 #include <string.h> /* strcmp */
 
@@ -31,7 +31,7 @@ int testCommandLineArguments1(int argc, char* argv[])
 
   int n = 0;
   char* m = 0;
-  kwsys_stl::string p;
+  std::string p;
   int res = 0;
 
   typedef kwsys::CommandLineArguments argT;
@@ -43,27 +43,27 @@ int testCommandLineArguments1(int argc, char* argv[])
 
   if ( !arg.Parse() )
     {
-    kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
+    std::cerr << "Problem parsing arguments" << std::endl;
     res = 1;
     }
   if ( n != 24 )
     {
-    kwsys_ios::cout << "Problem setting N. Value of N: " << n << kwsys_ios::endl;
+    std::cout << "Problem setting N. Value of N: " << n << std::endl;
     res = 1;
     }
   if ( !m || strcmp(m, "test value") != 0 )
     {
-    kwsys_ios::cout << "Problem setting M. Value of M: " << m << kwsys_ios::endl;
+    std::cout << "Problem setting M. Value of M: " << m << std::endl;
     res = 1;
     }
   if ( p != "1" )
     {
-    kwsys_ios::cout << "Problem setting P. Value of P: " << p << kwsys_ios::endl;
+    std::cout << "Problem setting P. Value of P: " << p << std::endl;
     res = 1;
     }
-  kwsys_ios::cout << "Value of N: " << n << kwsys_ios::endl;
-  kwsys_ios::cout << "Value of M: " << m << kwsys_ios::endl;
-  kwsys_ios::cout << "Value of P: " << p << kwsys_ios::endl;
+  std::cout << "Value of N: " << n << std::endl;
+  std::cout << "Value of M: " << m << std::endl;
+  std::cout << "Value of P: " << p << std::endl;
   if ( m )
     {
     delete [] m;
@@ -79,25 +79,25 @@ int testCommandLineArguments1(int argc, char* argv[])
   };
   if ( newArgc != 9 )
     {
-    kwsys_ios::cerr << "Bad number of unused arguments: " << newArgc << kwsys_ios::endl;
+    std::cerr << "Bad number of unused arguments: " << newArgc << std::endl;
     res = 1;
     }
   for ( cc = 0; cc < newArgc; ++ cc )
     {
     assert(newArgv[cc]); /* Quiet Clang scan-build. */
-    kwsys_ios::cout << "Unused argument[" << cc << "] = [" << newArgv[cc] << "]"
-      << kwsys_ios::endl;
+    std::cout << "Unused argument[" << cc << "] = [" << newArgv[cc] << "]"
+      << std::endl;
     if ( cc >= 9 )
       {
-      kwsys_ios::cerr << "Too many unused arguments: " << cc << kwsys_ios::endl;
+      std::cerr << "Too many unused arguments: " << cc << std::endl;
       res = 1;
       }
     else if ( valid_unused_args[cc] &&
       strcmp(valid_unused_args[cc], newArgv[cc]) != 0 )
       {
-      kwsys_ios::cerr << "Bad unused argument [" << cc << "] \""
+      std::cerr << "Bad unused argument [" << cc << "] \""
         << newArgv[cc] << "\" should be: \"" << valid_unused_args[cc] << "\""
-        << kwsys_ios::endl;
+        << std::endl;
       res = 1;
       }
     }
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
index 58adb84..695a134 100644
--- a/Source/kwsys/testDynamicLoader.cxx
+++ b/Source/kwsys/testDynamicLoader.cxx
@@ -12,8 +12,6 @@
 #include "kwsysPrivate.h"
 
 #include KWSYS_HEADER(DynamicLoader.hxx)
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(stl/string)
 
 #if defined(__BEOS__) || defined(__HAIKU__)
 #include <be/kernel/OS.h>  /* disable_debugger() API. */
@@ -23,18 +21,19 @@
 // duplicate the above list of headers.
 #if 0
 # include "DynamicLoader.hxx.in"
-# include "kwsys_ios_iostream.h.in"
-# include "kwsys_stl_string.hxx.in"
 #endif
 
+#include <string>
+#include <iostream>
+
 // Include with <> instead of "" to avoid getting any in-source copy
 // left on disk.
 #include <testSystemTools.h>
 
-static kwsys_stl::string GetLibName(const char* lname)
+static std::string GetLibName(const char* lname)
 {
   // Construct proper name of lib
-  kwsys_stl::string slname;
+  std::string slname;
   slname = EXECUTABLE_OUTPUT_PATH;
 #ifdef CMAKE_INTDIR
   slname += "/";
@@ -56,30 +55,30 @@ static kwsys_stl::string GetLibName(const char* lname)
  */
 int TestDynamicLoader(const char* libname, const char* symbol, int r1, int r2, int r3)
 {
-  kwsys_ios::cerr << "Testing: " << libname << kwsys_ios::endl;
+  std::cerr << "Testing: " << libname << std::endl;
   kwsys::DynamicLoader::LibraryHandle l
     = kwsys::DynamicLoader::OpenLibrary(libname);
   // If result is incompatible with expectation just fails (xor):
   if( (r1 && !l) || (!r1 && l) )
     {
-    kwsys_ios::cerr
-      << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
+    std::cerr
+      << kwsys::DynamicLoader::LastError() << std::endl;
     return 1;
     }
   kwsys::DynamicLoader::SymbolPointer f
     = kwsys::DynamicLoader::GetSymbolAddress(l, symbol);
   if( (r2 && !f) || (!r2 && f) )
     {
-    kwsys_ios::cerr
-      << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
+    std::cerr
+      << kwsys::DynamicLoader::LastError() << std::endl;
     return 1;
     }
 #ifndef __APPLE__
   int s = kwsys::DynamicLoader::CloseLibrary(l);
   if( (r3 && !s) || (!r3 && s) )
     {
-    kwsys_ios::cerr
-      << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
+    std::cerr
+      << kwsys::DynamicLoader::LastError() << std::endl;
     return 1;
     }
 #else
@@ -118,7 +117,7 @@ int testDynamicLoader(int argc, char *argv[])
   res += TestDynamicLoader("libdl.so", "TestDynamicLoader",1,0,1);
 #endif
   // Now try on the generated library
-  kwsys_stl::string libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynload");
+  std::string libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynload");
   res += TestDynamicLoader(libname.c_str(), "dummy",1,0,1);
   res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderSymbolPointer",1,1,1);
   res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderSymbolPointer",1,0,1);
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index 094588c..842b17d 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -17,8 +17,8 @@
 
 #include KWSYS_HEADER(Encoding.hxx)
 #include KWSYS_HEADER(Encoding.h)
-#include KWSYS_HEADER(ios/iostream)
 
+#include <iostream>
 #include <locale.h>
 #include <string.h>
 #include <stdlib.h>
@@ -28,7 +28,6 @@
 #if 0
 # include "Encoding.hxx.in"
 # include "Encoding.h.in"
-# include "kwsys_ios_iostream.h.in"
 #endif
 
 //----------------------------------------------------------------------------
diff --git a/Source/kwsys/testFStream.cxx b/Source/kwsys/testFStream.cxx
index 9abfd4c..ac5220a 100644
--- a/Source/kwsys/testFStream.cxx
+++ b/Source/kwsys/testFStream.cxx
@@ -16,7 +16,6 @@
 #endif
 
 #include KWSYS_HEADER(FStream.hxx)
-#include KWSYS_HEADER(ios/iostream)
 #include <string.h>
 #ifdef __BORLANDC__
 # include <mem.h> /* memcmp */
@@ -26,9 +25,9 @@
 // duplicate the above list of headers.
 #if 0
 # include "FStream.hxx.in"
-# include "kwsys_ios_iostream.h.in"
 #endif
 
+#include <iostream>
 
 //----------------------------------------------------------------------------
 static int testNoFile()
@@ -95,20 +94,20 @@ static int testBOM()
     kwsys::FStream::BOM bom = kwsys::FStream::ReadBOM(in);
     if(bom != expected_bom[i])
       {
-      kwsys_ios::cout << "Unexpected BOM " << i << std::endl;
+      std::cout << "Unexpected BOM " << i << std::endl;
       return 1;
       }
     char data[45];
     in.read(data, file_data[i][0]);
     if(!in.good())
       {
-      kwsys_ios::cout << "Unable to read data " << i << std::endl;
+      std::cout << "Unable to read data " << i << std::endl;
       return 1;
       }
 
     if(memcmp(data, file_data[i]+1, file_data[i][0]) != 0)
       {
-      kwsys_ios::cout << "Incorrect read data " << i << std::endl;
+      std::cout << "Incorrect read data " << i << std::endl;
       return 1;
       }
 
@@ -125,20 +124,20 @@ static int testBOM()
     kwsys::FStream::BOM bom = kwsys::FStream::ReadBOM(in);
     if(bom != kwsys::FStream::BOM_None)
       {
-      kwsys_ios::cout << "Unexpected BOM for none case" << std::endl;
+      std::cout << "Unexpected BOM for none case" << std::endl;
       return 1;
       }
     char data[45];
     in.read(data, file_data[0][0]);
     if(!in.good())
       {
-      kwsys_ios::cout << "Unable to read data for none case" << std::endl;
+      std::cout << "Unable to read data for none case" << std::endl;
       return 1;
       }
 
     if(memcmp(data, file_data[0]+1, file_data[0][0]) != 0)
       {
-      kwsys_ios::cout << "Incorrect read data for none case" << std::endl;
+      std::cout << "Incorrect read data for none case" << std::endl;
       return 1;
       }
   }
@@ -156,20 +155,20 @@ static int testBOM()
     kwsys::FStream::BOM bom = kwsys::FStream::ReadBOM(in);
     if(bom != kwsys::FStream::BOM_UTF8)
       {
-      kwsys_ios::cout << "Unexpected BOM for utf-8 case" << std::endl;
+      std::cout << "Unexpected BOM for utf-8 case" << std::endl;
       return 1;
       }
     char data[45];
     in.read(data, file_data[0][0]);
     if(!in.good())
       {
-      kwsys_ios::cout << "Unable to read data for utf-8 case" << std::endl;
+      std::cout << "Unable to read data for utf-8 case" << std::endl;
       return 1;
       }
 
     if(memcmp(data, file_data[0]+1, file_data[0][0]) != 0)
       {
-      kwsys_ios::cout << "Incorrect read data for utf-8 case" << std::endl;
+      std::cout << "Incorrect read data for utf-8 case" << std::endl;
       return 1;
       }
   }
diff --git a/Source/kwsys/testHashSTL.cxx b/Source/kwsys/testHashSTL.cxx
index ac5cf74..ab1f83e 100644
--- a/Source/kwsys/testHashSTL.cxx
+++ b/Source/kwsys/testHashSTL.cxx
@@ -12,7 +12,6 @@
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(hash_map.hxx)
 #include KWSYS_HEADER(hash_set.hxx)
-#include KWSYS_HEADER(ios/iostream)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
@@ -20,9 +19,10 @@
 # include "hash_map.hxx.in"
 # include "hash_set.hxx.in"
 # include "hashtable.hxx.in"
-# include "kwsys_ios_iostream.h.in"
 #endif
 
+#include <iostream>
+
 #if defined(_MSC_VER)
 # pragma warning (disable:4786)
 #endif
@@ -44,8 +44,8 @@ static bool test_hash_map()
   int sum = 0;
   for(mtype::iterator mi = m.begin(); mi != m.end(); ++mi)
     {
-    kwsys_ios::cout << "Found entry [" << mi->first << "," << mi->second << "]"
-                    << kwsys_ios::endl;
+    std::cout << "Found entry [" << mi->first << "," << mi->second << "]"
+              << std::endl;
     sum += mi->second;
     }
   return sum == 3;
@@ -60,7 +60,7 @@ static bool test_hash_set()
   int sum = 0;
   for(stype::iterator si = s.begin(); si != s.end(); ++si)
     {
-    kwsys_ios::cout << "Found entry [" << *si << "]" << kwsys_ios::endl;
+    std::cout << "Found entry [" << *si << "]" << std::endl;
     sum += *si;
     }
   return sum == 3;
diff --git a/Source/kwsys/testIOS.cxx b/Source/kwsys/testIOS.cxx
index f0c7f1a..396a09d 100644
--- a/Source/kwsys/testIOS.cxx
+++ b/Source/kwsys/testIOS.cxx
@@ -10,158 +10,149 @@
   See the License for more information.
 ============================================================================*/
 #include "kwsysPrivate.h"
-#include KWSYS_HEADER(stl/vector)
-#include KWSYS_HEADER(ios/sstream)
-#include KWSYS_HEADER(ios/fstream)
-#include KWSYS_HEADER(ios/iostream)
-
-// Work-around CMake dependency scanning limitation.  This must
-// duplicate the above list of headers.
-#if 0
-# include "kwsys_stl_string.hxx.in"
-# include "kwsys_stl_vector.h.in"
-# include "kwsys_ios_sstream.h.in"
-# include "kwsys_ios_fstream.h.in"
-# include "kwsys_ios_iostream.h.in"
-#endif
+#include KWSYS_HEADER(Configure.hxx)
 
+#include <sstream>
+#include <fstream>
+#include <iostream>
+#include <vector>
 #include <string.h> /* strlen */
 
 int testIOS(int, char*[])
 {
-  kwsys_ios::ostringstream ostr;
+  std::ostringstream ostr;
   const char hello[] = "hello";
   ostr << hello;
   if(ostr.str() != hello)
     {
-    kwsys_ios::cerr << "failed to write hello to ostr" << kwsys_ios::endl;
+    std::cerr << "failed to write hello to ostr" << std::endl;
     return 1;
     }
   const char world[] = "world";
-  kwsys_ios::ostringstream ostr2;
+  std::ostringstream ostr2;
   ostr2.write( hello, strlen(hello) ); /* I could do sizeof */
   ostr2.put( '\0' );
   ostr2.write( world, strlen(world) );
   if(ostr2.str().size() !=  strlen(hello) + 1 + strlen(world) )
     {
-    kwsys_ios::cerr << "failed to write hello to ostr2" << kwsys_ios::endl;
+    std::cerr << "failed to write hello to ostr2" << std::endl;
     return 1;
     }
   static const unsigned char array[] = { 0xff,0x4f,0xff,0x51,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x01,0x01,0xff,0x52,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x05,0x04,0x04,0x00,0x01,0xff,0x5c,0x00,0x13,0x40,0x40,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0xff,0x64,0x00,0x2c,0x00,0x00,0x43,0x72,0x65,0x61,0 [...]
   const size_t narray = sizeof(array); // 180
-  kwsys_ios::stringstream strstr;
+  std::stringstream strstr;
   strstr.write( (char*)array, narray );
   //strstr.seekp( narray / 2 ); // set position of put pointer in mid string
   if(strstr.str().size() != narray )
     {
-    kwsys_ios::cerr << "failed to write array to strstr" << kwsys_ios::endl;
+    std::cerr << "failed to write array to strstr" << std::endl;
     return 1;
     }
 
-  kwsys_ios::istringstream istr(" 10 20 str ");
-  kwsys_stl::string s;
+  std::istringstream istr(" 10 20 str ");
+  std::string s;
   int x;
   if(istr >> x)
     {
     if(x != 10)
       {
-      kwsys_ios::cerr << "x != 10" << kwsys_ios::endl;
+      std::cerr << "x != 10" << std::endl;
       return 1;
       }
     }
   else
     {
-    kwsys_ios::cerr << "Failed to read 10 from istr" << kwsys_ios::endl;
+    std::cerr << "Failed to read 10 from istr" << std::endl;
     return 1;
     }
   if(istr >> x)
     {
     if(x != 20)
       {
-      kwsys_ios::cerr << "x != 20" << kwsys_ios::endl;
+      std::cerr << "x != 20" << std::endl;
       return 1;
       }
     }
   else
     {
-    kwsys_ios::cerr << "Failed to read 20 from istr" << kwsys_ios::endl;
+    std::cerr << "Failed to read 20 from istr" << std::endl;
     return 1;
     }
   if(istr >> s)
     {
     if(s != "str")
       {
-      kwsys_ios::cerr << "s != \"str\"" << kwsys_ios::endl;
+      std::cerr << "s != \"str\"" << std::endl;
       return 1;
       }
     }
   else
     {
-    kwsys_ios::cerr << "Failed to read str from istr" << kwsys_ios::endl;
+    std::cerr << "Failed to read str from istr" << std::endl;
     return 1;
     }
   if(istr >> s)
     {
-    kwsys_ios::cerr << "Able to read past end of stream" << kwsys_ios::endl;
+    std::cerr << "Able to read past end of stream" << std::endl;
     return 1;
     }
   else
     {
     // Clear the failure.
-    istr.clear(istr.rdstate() & ~kwsys_ios::ios::eofbit);
-    istr.clear(istr.rdstate() & ~kwsys_ios::ios::failbit);
+    istr.clear(istr.rdstate() & ~std::ios::eofbit);
+    istr.clear(istr.rdstate() & ~std::ios::failbit);
     }
   istr.str("30");
   if(istr >> x)
     {
     if(x != 30)
       {
-      kwsys_ios::cerr << "x != 30" << kwsys_ios::endl;
+      std::cerr << "x != 30" << std::endl;
       return 1;
       }
     }
   else
     {
-    kwsys_ios::cerr << "Failed to read 30 from istr" << kwsys_ios::endl;
+    std::cerr << "Failed to read 30 from istr" << std::endl;
     return 1;
     }
 
-  kwsys_ios::stringstream sstr;
+  std::stringstream sstr;
   sstr << "40 str2";
   if(sstr >> x)
     {
     if(x != 40)
       {
-      kwsys_ios::cerr << "x != 40" << kwsys_ios::endl;
+      std::cerr << "x != 40" << std::endl;
       return 1;
       }
     }
   else
     {
-    kwsys_ios::cerr << "Failed to read 40 from sstr" << kwsys_ios::endl;
+    std::cerr << "Failed to read 40 from sstr" << std::endl;
     return 1;
     }
   if(sstr >> s)
     {
     if(s != "str2")
       {
-      kwsys_ios::cerr << "s != \"str2\"" << kwsys_ios::endl;
+      std::cerr << "s != \"str2\"" << std::endl;
       return 1;
       }
     }
   else
     {
-    kwsys_ios::cerr << "Failed to read str2 from sstr" << kwsys_ios::endl;
+    std::cerr << "Failed to read str2 from sstr" << std::endl;
     return 1;
     }
 
   // Just try to compile this.
   if(x == 12345)
     {
-    kwsys_ios::ifstream fin("/does_not_exist",
-                            kwsys_ios::ios::in | kwsys_ios_binary);
+    std::ifstream fin("/does_not_exist",
+                      std::ios::in | std::ios::binary);
     }
 
-  kwsys_ios::cout << "IOS tests passed" << kwsys_ios::endl;
+  std::cout << "IOS tests passed" << std::endl;
   return 0;
 }
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 47c3fb0..8fd3382 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -21,6 +21,7 @@
 #endif
 
 #include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -29,29 +30,61 @@
 # include <windows.h>
 #else
 # include <unistd.h>
+# include <signal.h>
 #endif
 
 #if defined(__BORLANDC__)
 # pragma warn -8060 /* possibly incorrect assignment */
 #endif
 
+/* Platform-specific sleep functions. */
+
 #if defined(__BEOS__) && !defined(__ZETA__)
 /* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */
 # include <be/kernel/OS.h>
-static inline void testProcess_usleep(unsigned int msec)
+static inline void testProcess_usleep(unsigned int usec)
+{
+  snooze(usec);
+}
+#elif defined(_WIN32)
+/* Windows can only sleep in millisecond intervals. */
+static void testProcess_usleep(unsigned int usec)
 {
-  snooze(msec);
+  Sleep(usec / 1000);
 }
 #else
 # define testProcess_usleep usleep
 #endif
 
+#if defined(_WIN32)
+static void testProcess_sleep(unsigned int sec)
+{
+  Sleep(sec*1000);
+}
+#else
+static void testProcess_sleep(unsigned int sec)
+{
+  sleep(sec);
+}
+#endif
+
 int runChild(const char* cmd[], int state, int exception, int value,
              int share, int output, int delay, double timeout, int poll,
-             int repeat, int disown);
+             int repeat, int disown, int createNewGroup,
+             unsigned int interruptDelay);
 
 static int test1(int argc, const char* argv[])
 {
+  /* This is a very basic functional test of kwsysProcess.  It is repeated
+     numerous times to verify that there are no resource leaks in kwsysProcess
+     that eventually lead to an error.  Many versions of OS X will fail after
+     256 leaked file handles, so 257 iterations seems to be a good test.  On
+     the other hand, too many iterations will cause the test to time out -
+     especially if the test is instrumented with e.g. valgrind.
+
+     If you have problems with this test timing out on your system, or want to
+     run more than 257 iterations, you can change the number of iterations by
+     setting the KWSYS_TEST_PROCESS_1_COUNT environment variable.  */
   (void)argc; (void)argv;
   fprintf(stdout, "Output on stdout from test returning 0.\n");
   fprintf(stderr, "Output on stderr from test returning 0.\n");
@@ -73,11 +106,7 @@ static int test3(int argc, const char* argv[])
   fprintf(stderr, "Output before sleep on stderr from timeout test.\n");
   fflush(stdout);
   fflush(stderr);
-#if defined(_WIN32)
-  Sleep(15000);
-#else
-  sleep(15);
-#endif
+  testProcess_sleep(15);
   fprintf(stdout, "Output after sleep on stdout from timeout test.\n");
   fprintf(stderr, "Output after sleep on stderr from timeout test.\n");
   return 0;
@@ -102,7 +131,7 @@ static int test4(int argc, const char* argv[])
 #endif
   (void)argc; (void)argv;
   fprintf(stdout, "Output before crash on stdout from crash test.\n");
-  fprintf(stderr, "Output before crash on stderr from crash test.\n");  
+  fprintf(stderr, "Output before crash on stderr from crash test.\n");
   fflush(stdout);
   fflush(stderr);
   assert(invalidAddress); /* Quiet Clang scan-build. */
@@ -127,7 +156,7 @@ static int test5(int argc, const char* argv[])
   fflush(stdout);
   fflush(stderr);
   r = runChild(cmd, kwsysProcess_State_Exception,
-               kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1, 0);
+               kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1, 0, 0, 0);
   fprintf(stdout, "Output on stdout after recursive test.\n");
   fprintf(stderr, "Output on stderr after recursive test.\n");
   fflush(stdout);
@@ -168,11 +197,7 @@ static int test7(int argc, const char* argv[])
   fflush(stdout);
   fflush(stderr);
   /* Sleep for 1 second.  */
-#if defined(_WIN32)
-  Sleep(1000);
-#else
-  sleep(1);
-#endif
+  testProcess_sleep(1);
   fprintf(stdout, "Output on stdout after sleep.\n");
   fprintf(stderr, "Output on stderr after sleep.\n");
   fflush(stdout);
@@ -196,7 +221,7 @@ static int test8(int argc, const char* argv[])
   fflush(stdout);
   fflush(stderr);
   r = runChild(cmd, kwsysProcess_State_Disowned, kwsysProcess_Exception_None,
-               1, 1, 1, 0, 10, 0, 1, 1);
+               1, 1, 1, 0, 10, 0, 1, 1, 0, 0);
   fprintf(stdout, "Output on stdout after grandchild test.\n");
   fprintf(stderr, "Output on stderr after grandchild test.\n");
   fflush(stdout);
@@ -217,18 +242,137 @@ static int test8_grandchild(int argc, const char* argv[])
      implemented.  */
   fclose(stdout);
   fclose(stderr);
+  testProcess_sleep(15);
+  return 0;
+}
+
+static int test9(int argc, const char* argv[])
+{
+  /* Test Ctrl+C behavior: the root test program will send a Ctrl+C to this
+     process.  Here, we start a child process that sleeps for a long time
+     while ignoring signals.  The test is successful if this process waits
+     for the child to return before exiting from the Ctrl+C handler.
+
+     WARNING:  This test will falsely pass if the share parameter of runChild
+     was set to 0 when invoking the test9 process.  */
+  int r;
+  const char* cmd[4];
+  (void)argc;
+  cmd[0] = argv[0];
+  cmd[1] = "run";
+  cmd[2] = "109";
+  cmd[3] = 0;
+  fprintf(stdout, "Output on stdout before grandchild test.\n");
+  fprintf(stderr, "Output on stderr before grandchild test.\n");
+  fflush(stdout);
+  fflush(stderr);
+  r = runChild(cmd, kwsysProcess_State_Exited,
+               kwsysProcess_Exception_None,
+               0, 1, 1, 0, 30, 0, 1, 0, 0, 0);
+  /* This sleep will avoid a race condition between this function exiting
+     normally and our Ctrl+C handler exiting abnormally after the process
+     exits.  */
+  testProcess_sleep(1);
+  fprintf(stdout, "Output on stdout after grandchild test.\n");
+  fprintf(stderr, "Output on stderr after grandchild test.\n");
+  fflush(stdout);
+  fflush(stderr);
+  return r;
+}
+
+#if defined(_WIN32)
+static BOOL WINAPI test9_grandchild_handler(DWORD dwCtrlType)
+{
+  /* Ignore all Ctrl+C/Break signals.  We must use an actual handler function
+     instead of using SetConsoleCtrlHandler(NULL, TRUE) so that we can also
+     ignore Ctrl+Break in addition to Ctrl+C.  */
+  (void)dwCtrlType;
+  return TRUE;
+}
+#endif
+
+static int test9_grandchild(int argc, const char* argv[])
+{
+  /* The grandchild just sleeps for a few seconds while ignoring signals.  */
+  (void)argc; (void)argv;
 #if defined(_WIN32)
-  Sleep(15000);
+  if(!SetConsoleCtrlHandler(test9_grandchild_handler, TRUE))
+    {
+    return 1;
+    }
 #else
-  sleep(15);
+  struct sigaction sa;
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_handler = SIG_IGN;
+  sigemptyset(&sa.sa_mask);
+  if(sigaction(SIGINT, &sa, 0) < 0)
+    {
+    return 1;
+    }
 #endif
+  fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
+  fprintf(stderr, "Output on stderr from grandchild before sleep.\n");
+  fflush(stdout);
+  fflush(stderr);
+  /* Sleep for 9 seconds.  */
+  testProcess_sleep(9);
+  fprintf(stdout, "Output on stdout from grandchild after sleep.\n");
+  fprintf(stderr, "Output on stderr from grandchild after sleep.\n");
+  fflush(stdout);
+  fflush(stderr);
+  return 0;
+}
+
+static int test10(int argc, const char* argv[])
+{
+  /* Test Ctrl+C behavior: the root test program will send a Ctrl+C to this
+     process.  Here, we start a child process that sleeps for a long time and
+     processes signals normally.  However, this grandchild is created in a new
+     process group - ensuring that Ctrl+C we receive is sent to our process
+     groups.  We make sure it exits anyway.  */
+  int r;
+  const char* cmd[4];
+  (void)argc;
+  cmd[0] = argv[0];
+  cmd[1] = "run";
+  cmd[2] = "110";
+  cmd[3] = 0;
+  fprintf(stdout, "Output on stdout before grandchild test.\n");
+  fprintf(stderr, "Output on stderr before grandchild test.\n");
+  fflush(stdout);
+  fflush(stderr);
+  r = runChild(cmd, kwsysProcess_State_Exception,
+               kwsysProcess_Exception_Interrupt,
+               0, 1, 1, 0, 30, 0, 1, 0, 1, 0);
+  fprintf(stdout, "Output on stdout after grandchild test.\n");
+  fprintf(stderr, "Output on stderr after grandchild test.\n");
+  fflush(stdout);
+  fflush(stderr);
+  return r;
+}
+
+static int test10_grandchild(int argc, const char* argv[])
+{
+  /* The grandchild just sleeps for a few seconds and handles signals.  */
+  (void)argc; (void)argv;
+  fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
+  fprintf(stderr, "Output on stderr from grandchild before sleep.\n");
+  fflush(stdout);
+  fflush(stderr);
+  /* Sleep for 6 seconds.  */
+  testProcess_sleep(6);
+  fprintf(stdout, "Output on stdout from grandchild after sleep.\n");
+  fprintf(stderr, "Output on stderr from grandchild after sleep.\n");
+  fflush(stdout);
+  fflush(stderr);
   return 0;
 }
 
 static int runChild2(kwsysProcess* kp,
               const char* cmd[], int state, int exception, int value,
               int share, int output, int delay, double timeout,
-              int poll, int disown)
+              int poll, int disown, int createNewGroup,
+              unsigned int interruptDelay)
 {
   int result = 0;
   char* data = 0;
@@ -249,6 +393,10 @@ static int runChild2(kwsysProcess* kp,
     {
     kwsysProcess_SetOption(kp, kwsysProcess_Option_Detach, 1);
     }
+  if(createNewGroup)
+    {
+    kwsysProcess_SetOption(kp, kwsysProcess_Option_CreateProcessGroup, 1);
+    }
   kwsysProcess_Execute(kp);
 
   if(poll)
@@ -256,6 +404,12 @@ static int runChild2(kwsysProcess* kp,
     pUserTimeout = &userTimeout;
     }
 
+  if(interruptDelay)
+    {
+    testProcess_sleep(interruptDelay);
+    kwsysProcess_Interrupt(kp);
+    }
+
   if(!share && !disown)
     {
     int p;
@@ -286,17 +440,13 @@ static int runChild2(kwsysProcess* kp,
       if(poll)
         {
         /* Delay to avoid busy loop during polling.  */
-#if defined(_WIN32)
-        Sleep(100);
-#else
         testProcess_usleep(100000);
-#endif
         }
       if(delay)
         {
         /* Purposely sleeping only on Win32 to let pipe fill up.  */
 #if defined(_WIN32)
-        Sleep(100);
+        testProcess_usleep(100000);
 #endif
         }
       }
@@ -337,7 +487,7 @@ static int runChild2(kwsysProcess* kp,
       printf("Error in administrating child process: [%s]\n",
              kwsysProcess_GetErrorString(kp)); break;
     };
-  
+
   if(result)
     {
     if(exception != kwsysProcess_GetExitException(kp))
@@ -353,7 +503,7 @@ static int runChild2(kwsysProcess* kp,
               value, kwsysProcess_GetExitValue(kp));
       }
     }
-  
+
   if(kwsysProcess_GetState(kp) != state)
     {
     fprintf(stderr, "Mismatch in state.  "
@@ -374,9 +524,37 @@ static int runChild2(kwsysProcess* kp,
   return result;
 }
 
+/**
+ * Runs a child process and blocks until it returns.  Arguments as follows:
+ *
+ * cmd            = Command line to run.
+ * state          = Expected return value of kwsysProcess_GetState after exit.
+ * exception      = Expected return value of kwsysProcess_GetExitException.
+ * value          = Expected return value of kwsysProcess_GetExitValue.
+ * share          = Whether to share stdout/stderr child pipes with our pipes
+ *                  by way of kwsysProcess_SetPipeShared.  If false, new pipes
+ *                  are created.
+ * output         = If !share && !disown, whether to write the child's stdout
+ *                  and stderr output to our stdout.
+ * delay          = If !share && !disown, adds an additional short delay to
+ *                  the pipe loop to allow the pipes to fill up; Windows only.
+ * timeout        = Non-zero to sets a timeout in seconds via
+ *                  kwsysProcess_SetTimeout.
+ * poll           = If !share && !disown, we count the number of 0.1 second
+ *                  intervals where the child pipes had no new data.  We fail
+ *                  if not in the bounds of MINPOLL/MAXPOLL.
+ * repeat         = Number of times to run the process.
+ * disown         = If set, the process is disowned.
+ * createNewGroup = If set, the process is created in a new process group.
+ * interruptDelay = If non-zero, number of seconds to delay before
+ *                  interrupting the process.  Note that this delay will occur
+ *                  BEFORE any reading/polling of pipes occurs and before any
+ *                  detachment occurs.
+ */
 int runChild(const char* cmd[], int state, int exception, int value,
              int share, int output, int delay, double timeout,
-             int poll, int repeat, int disown)
+             int poll, int repeat, int disown, int createNewGroup,
+             unsigned int interruptDelay)
 {
   int result = 1;
   kwsysProcess* kp = kwsysProcess_New();
@@ -388,7 +566,12 @@ int runChild(const char* cmd[], int state, int exception, int value,
   while(repeat-- > 0)
     {
     result = runChild2(kp, cmd, state, exception, value, share,
-                       output, delay, timeout, poll, disown);
+                       output, delay, timeout, poll, disown, createNewGroup,
+                       interruptDelay);
+    if(result)
+      {
+      break;
+      }
     }
   kwsysProcess_Delete(kp);
   return result;
@@ -435,7 +618,7 @@ int main(int argc, const char* argv[])
     n = atoi(argv[2]);
     }
   /* Check arguments.  */
-  if(((n >= 1 && n <= 8) || n == 108) && argc == 3)
+  if(((n >= 1 && n <= 10) || n == 108 || n == 109 || n == 110) && argc == 3)
     {
     /* This is the child process for a requested test number.  */
     switch (n)
@@ -448,15 +631,19 @@ int main(int argc, const char* argv[])
       case 6: test6(argc, argv); return 0;
       case 7: return test7(argc, argv);
       case 8: return test8(argc, argv);
+      case 9: return test9(argc, argv);
+      case 10: return test10(argc, argv);
       case 108: return test8_grandchild(argc, argv);
+      case 109: return test9_grandchild(argc, argv);
+      case 110: return test10_grandchild(argc, argv);
       }
     fprintf(stderr, "Invalid test number %d.\n", n);
     return 1;
     }
-  else if(n >= 1 && n <= 8)
+  else if(n >= 1 && n <= 10)
     {
     /* This is the parent process for a requested test number.  */
-    int states[8] =
+    int states[10] =
     {
       kwsysProcess_State_Exited,
       kwsysProcess_State_Exited,
@@ -465,9 +652,11 @@ int main(int argc, const char* argv[])
       kwsysProcess_State_Exited,
       kwsysProcess_State_Expired,
       kwsysProcess_State_Exited,
-      kwsysProcess_State_Exited
+      kwsysProcess_State_Exited,
+      kwsysProcess_State_Expired, /* Ctrl+C handler test */
+      kwsysProcess_State_Exception /* Process group test */
     };
-    int exceptions[8] =
+    int exceptions[10] =
     {
       kwsysProcess_Exception_None,
       kwsysProcess_Exception_None,
@@ -476,18 +665,34 @@ int main(int argc, const char* argv[])
       kwsysProcess_Exception_None,
       kwsysProcess_Exception_None,
       kwsysProcess_Exception_None,
-      kwsysProcess_Exception_None
+      kwsysProcess_Exception_None,
+      kwsysProcess_Exception_None,
+      kwsysProcess_Exception_Interrupt
     };
-    int values[8] = {0, 123, 1, 1, 0, 0, 0, 0};
-    int outputs[8] = {1, 1, 1, 1, 1, 0, 1, 1};
-    int delays[8] = {0, 0, 0, 0, 0, 1, 0, 0};
-    double timeouts[8] = {10, 10, 10, 30, 30, 10, -1, 10};
-    int polls[8] = {0, 0, 0, 0, 0, 0, 1, 0};
-    int repeat[8] = {2, 1, 1, 1, 1, 1, 1, 1};
+    int values[10] = {0, 123, 1, 1, 0, 0, 0, 0, 1, 1};
+    int shares[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
+    int outputs[10] = {1, 1, 1, 1, 1, 0, 1, 1, 1, 1};
+    int delays[10] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0};
+    double timeouts[10] = {10, 10, 10, 30, 30, 10, -1, 10, 6, 4};
+    int polls[10] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0};
+    int repeat[10] = {257, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+    int createNewGroups[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
+    unsigned int interruptDelays[10] = {0, 0, 0, 0, 0, 0, 0, 0, 3, 2};
     int r;
     const char* cmd[4];
 #ifdef _WIN32
     char* argv0 = 0;
+#endif
+    char* test1IterationsStr = getenv("KWSYS_TEST_PROCESS_1_COUNT");
+    if(test1IterationsStr)
+      {
+      long int test1Iterations = strtol(test1IterationsStr, 0, 10);
+      if(test1Iterations > 10 && test1Iterations != LONG_MAX)
+        {
+        repeat[0] = (int)test1Iterations;
+        }
+      }
+#ifdef _WIN32
     if(n == 0 && (argv0 = strdup(argv[0])))
       {
       /* Try converting to forward slashes to see if it works.  */
@@ -515,9 +720,10 @@ int main(int argc, const char* argv[])
     fprintf(stderr, "Output on stderr before test %d.\n", n);
     fflush(stdout);
     fflush(stderr);
-    r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], 0,
+    r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], shares[n-1],
                  outputs[n-1], delays[n-1], timeouts[n-1],
-                 polls[n-1], repeat[n-1], 0);
+                 polls[n-1], repeat[n-1], 0, createNewGroups[n-1],
+                 interruptDelays[n-1]);
     fprintf(stdout, "Output on stdout after test %d.\n", n);
     fprintf(stderr, "Output on stderr after test %d.\n", n);
     fflush(stdout);
@@ -536,7 +742,8 @@ int main(int argc, const char* argv[])
     int exception = kwsysProcess_Exception_None;
     int value = 0;
     double timeout = 0;
-    int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0);
+    int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout,
+      0, 1, 0, 0, 0);
     return r;
     }
   else
diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx
index 53d51ac..c96751a 100644
--- a/Source/kwsys/testSystemInformation.cxx
+++ b/Source/kwsys/testSystemInformation.cxx
@@ -11,15 +11,15 @@
 ============================================================================*/
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(SystemInformation.hxx)
-#include KWSYS_HEADER(ios/iostream)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
 # include "SystemInformation.hxx.in"
-# include "kwsys_ios_iostream.h.in"
 #endif
 
+#include <iostream>
+
 #if defined(KWSYS_USE_LONG_LONG)
 # if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
 #  define iostreamLongLong(x) (x)
@@ -36,18 +36,18 @@
 # error "No Long Long"
 #endif
 
-#define printMethod(info, m) kwsys_ios::cout << #m << ": " \
+#define printMethod(info, m) std::cout << #m << ": " \
 << info.m() << "\n"
 
-#define printMethod2(info, m, unit) kwsys_ios::cout << #m << ": " \
+#define printMethod2(info, m, unit) std::cout << #m << ": " \
 << info.m() << " " << unit << "\n"
 
-#define printMethod3(info, m, unit) kwsys_ios::cout << #m << ": " \
+#define printMethod3(info, m, unit) std::cout << #m << ": " \
 << iostreamLongLong(info.m) << " " << unit << "\n"
 
 int testSystemInformation(int, char*[])
 {
-  kwsys_ios::cout << "CTEST_FULL_OUTPUT\n"; // avoid truncation
+  std::cout << "CTEST_FULL_OUTPUT\n"; // avoid truncation
 
   kwsys::SystemInformation info;
   info.RunCPUCheck();
@@ -87,21 +87,22 @@ int testSystemInformation(int, char*[])
   printMethod3(info, GetProcMemoryAvailable("KWSHL","KWSPL"), "KiB");
   printMethod3(info, GetHostMemoryUsed(), "KiB");
   printMethod3(info, GetProcMemoryUsed(), "KiB");
+  printMethod(info, GetLoadAverage);
 
   for (long int i = 0; i <= 31; i++)
     {
     if (info.DoesCPUSupportFeature(static_cast<long int>(1) << i))
       {
-      kwsys_ios::cout << "CPU feature " << i << "\n";
+      std::cout << "CPU feature " << i << "\n";
       }
     }
 
   /* test stack trace
   */
-  kwsys_ios::cout
-    << "Program Stack:" << kwsys_ios::endl
-    << kwsys::SystemInformation::GetProgramStack(0,0) << kwsys_ios::endl
-    << kwsys_ios::endl;
+  std::cout
+    << "Program Stack:" << std::endl
+    << kwsys::SystemInformation::GetProgramStack(0,0) << std::endl
+    << std::endl;
 
   /* test segv handler
   info.SetStackTraceOnError(1);
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 15d8eab..a0f904f 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -16,20 +16,31 @@
 #endif
 
 #include KWSYS_HEADER(SystemTools.hxx)
-#include KWSYS_HEADER(ios/iostream)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
 # include "SystemTools.hxx.in"
-# include "kwsys_ios_iostream.h.in"
 #endif
 
 // Include with <> instead of "" to avoid getting any in-source copy
 // left on disk.
 #include <testSystemTools.h>
 
+#include <iostream>
+#include <sstream>
 #include <string.h> /* strcmp */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <io.h> /* _umask (MSVC) / umask (Borland) */
+# ifdef _MSC_VER
+#  define umask _umask // Note this is still umask on Borland
+# endif
+#endif
+#include <sys/stat.h> /* umask (POSIX), _S_I* constants (Windows) */
+// Visual C++ does not define mode_t (note that Borland does, however).
+#if defined( _MSC_VER )
+typedef unsigned short mode_t;
+#endif
 
 //----------------------------------------------------------------------------
 static const char* toUnixPaths[][2] =
@@ -52,17 +63,17 @@ static const char* toUnixPaths[][2] =
     {0, 0}
 };
 
-static bool CheckConvertToUnixSlashes(kwsys_stl::string input,
-                                      kwsys_stl::string output)
+static bool CheckConvertToUnixSlashes(std::string input,
+                                      std::string output)
 {
-  kwsys_stl::string result = input;
+  std::string result = input;
   kwsys::SystemTools::ConvertToUnixSlashes(result);
   if ( result != output )
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToUnixSlashes - input: " << input
       << " output: " << result << " expected: " << output
-      << kwsys_ios::endl;
+      << std::endl;
     return false;
     }
   return true;
@@ -76,19 +87,19 @@ static const char* checkEscapeChars[][4] =
   {0, 0, 0, 0}
 };
 
-static bool CheckEscapeChars(kwsys_stl::string input,
+static bool CheckEscapeChars(std::string input,
                              const char *chars_to_escape,
                              char escape_char,
-                             kwsys_stl::string output)
+                             std::string output)
 {
-  kwsys_stl::string result = kwsys::SystemTools::EscapeChars(
+  std::string result = kwsys::SystemTools::EscapeChars(
     input.c_str(), chars_to_escape, escape_char);
   if (result != output)
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with CheckEscapeChars - input: " << input
       << " output: " << result << " expected: " << output
-      << kwsys_ios::endl;
+      << std::endl;
     return false;
     }
   return true;
@@ -98,78 +109,229 @@ static bool CheckEscapeChars(kwsys_stl::string input,
 static bool CheckFileOperations()
 {
   bool res = true;
-  const kwsys_stl::string testBinFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+  const std::string testNonExistingFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+    "/testSystemToolsNonExistingFile");
+  const std::string testDotFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+    "/.");
+  const std::string testBinFile(TEST_SYSTEMTOOLS_SOURCE_DIR
     "/testSystemTools.bin");
-  const kwsys_stl::string testTxtFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+  const std::string testTxtFile(TEST_SYSTEMTOOLS_SOURCE_DIR
     "/testSystemTools.cxx");
-  const kwsys_stl::string testNewDir(TEST_SYSTEMTOOLS_BINARY_DIR
+  const std::string testNewDir(TEST_SYSTEMTOOLS_BINARY_DIR
     "/testSystemToolsNewDir");
-  const kwsys_stl::string testNewFile(testNewDir + "/testNewFile.txt");
+  const std::string testNewFile(testNewDir + "/testNewFile.txt");
+
+  if (kwsys::SystemTools::DetectFileType(testNonExistingFile.c_str()) !=
+      kwsys::SystemTools::FileTypeUnknown)
+    {
+    std::cerr
+      << "Problem with DetectFileType - failed to detect type of: "
+      << testNonExistingFile << std::endl;
+    res = false;
+    }
+
+  if (kwsys::SystemTools::DetectFileType(testDotFile.c_str()) !=
+      kwsys::SystemTools::FileTypeUnknown)
+    {
+    std::cerr
+      << "Problem with DetectFileType - failed to detect type of: "
+      << testDotFile << std::endl;
+    res = false;
+    }
 
   if (kwsys::SystemTools::DetectFileType(testBinFile.c_str()) !=
       kwsys::SystemTools::FileTypeBinary)
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with DetectFileType - failed to detect type of: "
-      << testBinFile << kwsys_ios::endl;
+      << testBinFile << std::endl;
     res = false;
     }
 
   if (kwsys::SystemTools::DetectFileType(testTxtFile.c_str()) !=
       kwsys::SystemTools::FileTypeText)
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with DetectFileType - failed to detect type of: "
-      << testTxtFile << kwsys_ios::endl;
+      << testTxtFile << std::endl;
     res = false;
     }
 
   if (kwsys::SystemTools::FileLength(testBinFile) != 766)
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with FileLength - incorrect length for: "
-      << testBinFile << kwsys_ios::endl;
+      << testBinFile << std::endl;
     res = false;
     }
 
   if (!kwsys::SystemTools::MakeDirectory(testNewDir))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with MakeDirectory for: "
-      << testNewDir << kwsys_ios::endl;
+      << testNewDir << std::endl;
     res = false;
     }
 
   if (!kwsys::SystemTools::Touch(testNewFile.c_str(), true))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with Touch for: "
-      << testNewFile << kwsys_ios::endl;
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  // Reset umask
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  // NOTE:  Windows doesn't support toggling _S_IREAD.
+  mode_t fullMask = _S_IWRITE;
+#else
+  // On a normal POSIX platform, we can toggle all permissions.
+  mode_t fullMask = S_IRWXU | S_IRWXG | S_IRWXO;
+#endif
+  mode_t orig_umask = umask(fullMask);
+
+  // Test file permissions without umask
+  mode_t origPerm, thisPerm;
+  if (!kwsys::SystemTools::GetPermissions(testNewFile, origPerm))
+    {
+    std::cerr
+      << "Problem with GetPermissions (1) for: "
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::SetPermissions(testNewFile, 0))
+    {
+    std::cerr
+      << "Problem with SetPermissions (1) for: "
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
+    {
+    std::cerr
+      << "Problem with GetPermissions (2) for: "
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  if ((thisPerm & fullMask) != 0)
+    {
+    std::cerr
+      << "SetPermissions failed to set permissions (1) for: "
+      << testNewFile << ": actual = " << thisPerm << "; expected = "
+      << 0 << std::endl;
+    res = false;
+    }
+
+  // While we're at it, check proper TestFileAccess functionality.
+  if (kwsys::SystemTools::TestFileAccess(testNewFile,
+                                         kwsys::TEST_FILE_WRITE))
+    {
+    std::cerr
+      << "TestFileAccess incorrectly indicated that this is a writable file:"
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::TestFileAccess(testNewFile,
+                                          kwsys::TEST_FILE_OK))
+    {
+    std::cerr
+      << "TestFileAccess incorrectly indicated that this file does not exist:"
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  // Test restoring/setting full permissions.
+  if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask))
+    {
+    std::cerr
+      << "Problem with SetPermissions (2) for: "
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
+    {
+    std::cerr
+      << "Problem with GetPermissions (3) for: "
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  if ((thisPerm & fullMask) != fullMask)
+    {
+    std::cerr
+      << "SetPermissions failed to set permissions (2) for: "
+      << testNewFile << ": actual = " << thisPerm << "; expected = "
+      << fullMask << std::endl;
+    res = false;
+    }
+
+  // Test setting file permissions while honoring umask
+  if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask, true))
+    {
+    std::cerr
+      << "Problem with SetPermissions (3) for: "
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
+    {
+    std::cerr
+      << "Problem with GetPermissions (4) for: "
+      << testNewFile << std::endl;
+    res = false;
+    }
+
+  if ((thisPerm & fullMask) != 0)
+    {
+    std::cerr
+      << "SetPermissions failed to honor umask for: "
+      << testNewFile << ": actual = " << thisPerm << "; expected = "
+      << 0 << std::endl;
+    res = false;
+    }
+
+  // Restore umask
+  umask(orig_umask);
+
+  // Restore file permissions
+  if (!kwsys::SystemTools::SetPermissions(testNewFile, origPerm))
+    {
+    std::cerr
+      << "Problem with SetPermissions (4) for: "
+      << testNewFile << std::endl;
     res = false;
     }
 
+  // Remove the test file
   if (!kwsys::SystemTools::RemoveFile(testNewFile))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with RemoveFile: "
-      << testNewFile << kwsys_ios::endl;
+      << testNewFile << std::endl;
     res = false;
     }
 
-  kwsys_stl::string const testFileMissing(testNewDir + "/testMissingFile.txt");
+  std::string const testFileMissing(testNewDir + "/testMissingFile.txt");
   if (!kwsys::SystemTools::RemoveFile(testFileMissing))
     {
     std::string const& msg = kwsys::SystemTools::GetLastSystemError();
-    kwsys_ios::cerr <<
+    std::cerr <<
       "RemoveFile(\"" << testFileMissing << "\") failed: " << msg << "\n";
     res = false;
     }
 
-  kwsys_stl::string const testFileMissingDir(testNewDir + "/missing/file.txt");
+  std::string const testFileMissingDir(testNewDir + "/missing/file.txt");
   if (!kwsys::SystemTools::RemoveFile(testFileMissingDir))
     {
     std::string const& msg = kwsys::SystemTools::GetLastSystemError();
-    kwsys_ios::cerr <<
+    std::cerr <<
       "RemoveFile(\"" << testFileMissingDir << "\") failed: " << msg << "\n";
     res = false;
     }
@@ -177,9 +339,9 @@ static bool CheckFileOperations()
   kwsys::SystemTools::Touch(testNewFile.c_str(), true);
   if (!kwsys::SystemTools::RemoveADirectory(testNewDir))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with RemoveADirectory for: "
-      << testNewDir << kwsys_ios::endl;
+      << testNewDir << std::endl;
     res = false;
     }
 
@@ -187,14 +349,14 @@ static bool CheckFileOperations()
   // Perform the same file and directory creation and deletion tests but
   // with paths > 256 characters in length.
 
-  const kwsys_stl::string testNewLongDir(
+  const std::string testNewLongDir(
     TEST_SYSTEMTOOLS_BINARY_DIR "/"
     "012345678901234567890123456789012345678901234567890123456789"
     "012345678901234567890123456789012345678901234567890123456789"
     "012345678901234567890123456789012345678901234567890123456789"
     "012345678901234567890123456789012345678901234567890123456789"
     "01234567890123");
-  const kwsys_stl::string testNewLongFile(testNewLongDir + "/"
+  const std::string testNewLongFile(testNewLongDir + "/"
     "012345678901234567890123456789012345678901234567890123456789"
     "012345678901234567890123456789012345678901234567890123456789"
     "012345678901234567890123456789012345678901234567890123456789"
@@ -203,34 +365,34 @@ static bool CheckFileOperations()
 
   if (!kwsys::SystemTools::MakeDirectory(testNewLongDir))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with MakeDirectory for: "
-      << testNewLongDir << kwsys_ios::endl;
+      << testNewLongDir << std::endl;
     res = false;
     }
 
   if (!kwsys::SystemTools::Touch(testNewLongFile.c_str(), true))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with Touch for: "
-      << testNewLongFile << kwsys_ios::endl;
+      << testNewLongFile << std::endl;
     res = false;
     }
 
   if (!kwsys::SystemTools::RemoveFile(testNewLongFile))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with RemoveFile: "
-      << testNewLongFile << kwsys_ios::endl;
+      << testNewLongFile << std::endl;
     res = false;
     }
 
   kwsys::SystemTools::Touch(testNewLongFile.c_str(), true);
   if (!kwsys::SystemTools::RemoveADirectory(testNewLongDir))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with RemoveADirectory for: "
-      << testNewLongDir << kwsys_ios::endl;
+      << testNewLongDir << std::endl;
     res = false;
     }
 #endif
@@ -243,84 +405,84 @@ static bool CheckStringOperations()
 {
   bool res = true;
 
-  kwsys_stl::string test = "mary had a little lamb.";
+  std::string test = "mary had a little lamb.";
   if (kwsys::SystemTools::CapitalizedWords(test) != "Mary Had A Little Lamb.")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with CapitalizedWords "
-      << '"' << test << '"' << kwsys_ios::endl;
-    res = false;    
+      << '"' << test << '"' << std::endl;
+    res = false;
     }
 
   test = "Mary Had A Little Lamb.";
-  if (kwsys::SystemTools::UnCapitalizedWords(test) != 
+  if (kwsys::SystemTools::UnCapitalizedWords(test) !=
       "mary had a little lamb.")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with UnCapitalizedWords "
-      << '"' << test << '"' << kwsys_ios::endl;
-    res = false;    
+      << '"' << test << '"' << std::endl;
+    res = false;
     }
 
   test = "MaryHadTheLittleLamb.";
-  if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) != 
+  if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) !=
       "Mary Had The Little Lamb.")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with AddSpaceBetweenCapitalizedWords "
-      << '"' << test << '"' << kwsys_ios::endl;
-    res = false;    
+      << '"' << test << '"' << std::endl;
+    res = false;
     }
 
-  char * cres = 
+  char * cres =
     kwsys::SystemTools::AppendStrings("Mary Had A"," Little Lamb.");
   if (strcmp(cres,"Mary Had A Little Lamb."))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with AppendStrings "
-      << "\"Mary Had A\" \" Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A\" \" Little Lamb.\"" << std::endl;
+    res = false;
     }
   delete [] cres;
 
-  cres = 
+  cres =
     kwsys::SystemTools::AppendStrings("Mary Had"," A ","Little Lamb.");
   if (strcmp(cres,"Mary Had A Little Lamb."))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with AppendStrings "
-      << "\"Mary Had\" \" A \" \"Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had\" \" A \" \"Little Lamb.\"" << std::endl;
+    res = false;
     }
   delete [] cres;
 
   if (kwsys::SystemTools::CountChar("Mary Had A Little Lamb.",'a') != 3)
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with CountChar "
-      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A Little Lamb.\"" << std::endl;
+    res = false;
     }
 
-  cres = 
+  cres =
     kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.","aeiou");
   if (strcmp(cres,"Mry Hd A Lttl Lmb."))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with RemoveChars "
-      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A Little Lamb.\"" << std::endl;
+    res = false;
     }
   delete [] cres;
 
-  cres = 
+  cres =
     kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
   if (strcmp(cres,"A"))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with RemoveCharsButUpperHex "
-      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A Little Lamb.\"" << std::endl;
+    res = false;
     }
   delete [] cres;
 
@@ -329,59 +491,59 @@ static bool CheckStringOperations()
   kwsys::SystemTools::ReplaceChars(cres2,"aeiou",'X');
   if (strcmp(cres2,"MXry HXd A LXttlX LXmb."))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ReplaceChars "
-      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A Little Lamb.\"" << std::endl;
+    res = false;
     }
   delete [] cres2;
 
   if (!kwsys::SystemTools::StringStartsWith("Mary Had A Little Lamb.",
                                             "Mary "))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with StringStartsWith "
-      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A Little Lamb.\"" << std::endl;
+    res = false;
     }
 
   if (!kwsys::SystemTools::StringEndsWith("Mary Had A Little Lamb.",
                                           " Lamb."))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with StringEndsWith "
-      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A Little Lamb.\"" << std::endl;
+    res = false;
     }
 
   cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb.");
   if (strcmp(cres,"Mary Had A Little Lamb."))
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with DuplicateString "
-      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A Little Lamb.\"" << std::endl;
+    res = false;
     }
   delete [] cres;
 
   test = "Mary Had A Little Lamb.";
-  if (kwsys::SystemTools::CropString(test,13) != 
+  if (kwsys::SystemTools::CropString(test,13) !=
       "Mary ...Lamb.")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with CropString "
-      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
-    res = false;    
+      << "\"Mary Had A Little Lamb.\"" << std::endl;
+    res = false;
     }
 
-  kwsys_stl::vector<kwsys_stl::string> lines;
+  std::vector<std::string> lines;
   kwsys::SystemTools::Split("Mary Had A Little Lamb.",lines,' ');
   if (lines[0] != "Mary" || lines[1] != "Had" ||
       lines[2] != "A" || lines[3] != "Little" || lines[4] != "Lamb.")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with Split "
-      << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
+      << "\"Mary Had A Little Lamb.\"" << std::endl;
     res = false;
     }
 
@@ -390,10 +552,10 @@ static bool CheckStringOperations()
       ("L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
       L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
@@ -401,10 +563,10 @@ static bool CheckStringOperations()
       ("L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
       L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
@@ -412,10 +574,10 @@ static bool CheckStringOperations()
       ("\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
       L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
@@ -423,106 +585,106 @@ static bool CheckStringOperations()
       ("//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
       L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
   if (kwsys::SystemTools::ConvertToWindowsExtendedPath("//") !=
       L"//")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"//\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
   if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\") !=
       L"\\\\.\\")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"\\\\.\\\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
   if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X") !=
       L"\\\\.\\X")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"\\\\.\\X\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
   if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:") !=
       L"\\\\?\\X:")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"\\\\.\\X:\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
   if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:\\") !=
       L"\\\\?\\X:\\")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"\\\\.\\X:\\\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
   if (kwsys::SystemTools::ConvertToWindowsExtendedPath("NUL") !=
       L"\\\\.\\NUL")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsExtendedPath "
       << "\"NUL\""
-      << kwsys_ios::endl;
+      << std::endl;
     res = false;
     }
 
 #endif
 
   if (kwsys::SystemTools::ConvertToWindowsOutputPath
-      ("L://Local Mojo/Hex Power Pack/Iffy Voodoo") != 
+      ("L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
       "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsOutputPath "
       << "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\""
-      << kwsys_ios::endl;
-    res = false;    
+      << std::endl;
+    res = false;
     }
-  
+
   if (kwsys::SystemTools::ConvertToWindowsOutputPath
-      ("//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") != 
+      ("//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
       "\"\\\\grayson\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToWindowsOutputPath "
       << "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\""
-      << kwsys_ios::endl;
-    res = false;    
+      << std::endl;
+    res = false;
     }
 
   if (kwsys::SystemTools::ConvertToUnixOutputPath
-      ("//Local Mojo/Hex Power Pack/Iffy Voodoo") != 
+      ("//Local Mojo/Hex Power Pack/Iffy Voodoo") !=
       "//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo")
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Problem with ConvertToUnixOutputPath "
       << "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\""
-      << kwsys_ios::endl;
-    res = false;    
+      << std::endl;
+    res = false;
     }
 
   return res;
@@ -530,20 +692,20 @@ static bool CheckStringOperations()
 
 //----------------------------------------------------------------------------
 
-static bool CheckPutEnv(const kwsys_stl::string& env, const char* name, const char* value)
+static bool CheckPutEnv(const std::string& env, const char* name, const char* value)
 {
   if(!kwsys::SystemTools::PutEnv(env))
     {
-    kwsys_ios::cerr << "PutEnv(\"" << env
-                    << "\") failed!" << kwsys_ios::endl;
+    std::cerr << "PutEnv(\"" << env
+                    << "\") failed!" << std::endl;
     return false;
     }
   const char* v = kwsys::SystemTools::GetEnv(name);
   v = v? v : "(null)";
   if(strcmp(v, value) != 0)
     {
-    kwsys_ios::cerr << "GetEnv(\"" << name << "\") returned \""
-                    << v << "\", not \"" << value << "\"!" << kwsys_ios::endl;
+    std::cerr << "GetEnv(\"" << name << "\") returned \""
+                    << v << "\", not \"" << value << "\"!" << std::endl;
     return false;
     }
   return true;
@@ -553,14 +715,14 @@ static bool CheckUnPutEnv(const char* env, const char* name)
 {
   if(!kwsys::SystemTools::UnPutEnv(env))
     {
-    kwsys_ios::cerr << "UnPutEnv(\"" << env << "\") failed!"
-                    << kwsys_ios::endl;
+    std::cerr << "UnPutEnv(\"" << env << "\") failed!"
+                    << std::endl;
     return false;
     }
   if(const char* v = kwsys::SystemTools::GetEnv(name))
     {
-    kwsys_ios::cerr << "GetEnv(\"" << name << "\") returned \""
-                    << v << "\", not (null)!" << kwsys_ios::endl;
+    std::cerr << "GetEnv(\"" << name << "\") returned \""
+                    << v << "\", not (null)!" << std::endl;
     return false;
     }
   return true;
@@ -582,15 +744,15 @@ static bool CheckEnvironmentOperations()
 
 
 static bool CheckRelativePath(
-  const kwsys_stl::string& local,
-  const kwsys_stl::string& remote,
-  const kwsys_stl::string& expected)
+  const std::string& local,
+  const std::string& remote,
+  const std::string& expected)
 {
-  kwsys_stl::string result = kwsys::SystemTools::RelativePath(local, remote);
+  std::string result = kwsys::SystemTools::RelativePath(local, remote);
   if(expected != result)
     {
-    kwsys_ios::cerr << "RelativePath(" << local << ", " << remote
-      << ")  yielded " << result << " instead of " << expected << kwsys_ios::endl;
+    std::cerr << "RelativePath(" << local << ", " << remote
+      << ")  yielded " << result << " instead of " << expected << std::endl;
     return false;
     }
   return true;
@@ -608,14 +770,14 @@ static bool CheckRelativePaths()
 }
 
 static bool CheckCollapsePath(
-  const kwsys_stl::string& path,
-  const kwsys_stl::string& expected)
+  const std::string& path,
+  const std::string& expected)
 {
-  kwsys_stl::string result = kwsys::SystemTools::CollapseFullPath(path);
+  std::string result = kwsys::SystemTools::CollapseFullPath(path);
   if(expected != result)
     {
-    kwsys_ios::cerr << "CollapseFullPath(" << path
-      << ")  yielded " << result << " instead of " << expected << kwsys_ios::endl;
+    std::cerr << "CollapseFullPath(" << path
+      << ")  yielded " << result << " instead of " << expected << std::endl;
     return false;
     }
   return true;
@@ -629,6 +791,66 @@ static bool CheckCollapsePath()
   return res;
 }
 
+static std::string StringVectorToString(const std::vector<std::string>& vec)
+{
+  std::stringstream ss;
+  ss << "vector(";
+  for (std::vector<std::string>::const_iterator i = vec.begin();
+       i != vec.end(); ++i)
+    {
+    if (i != vec.begin())
+      {
+      ss << ", ";
+      }
+    ss << *i;
+    }
+  ss << ")";
+  return ss.str();
+}
+
+static bool CheckGetPath()
+{
+  const char* envName = "S";
+#ifdef _WIN32
+  const char* envValue = "C:\\Somewhere\\something;D:\\Temp";
+#else
+  const char* envValue = "/Somewhere/something:/tmp";
+#endif
+  const char* registryPath = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp; MyKey]";
+
+  std::vector<std::string> originalPathes;
+  originalPathes.push_back(registryPath);
+
+  std::vector<std::string> expectedPathes;
+  expectedPathes.push_back(registryPath);
+#ifdef _WIN32
+  expectedPathes.push_back("C:/Somewhere/something");
+  expectedPathes.push_back("D:/Temp");
+#else
+  expectedPathes.push_back("/Somewhere/something");
+  expectedPathes.push_back("/tmp");
+#endif
+
+  bool res = true;
+  res &= CheckPutEnv(std::string(envName) + "=" + envValue, envName, envValue);
+
+  std::vector<std::string> pathes = originalPathes;
+  kwsys::SystemTools::GetPath(pathes, envName);
+
+  if (pathes != expectedPathes)
+    {
+    std::cerr <<
+      "GetPath(" << StringVectorToString(originalPathes) <<
+      ", " << envName << ")  yielded " << StringVectorToString(pathes) <<
+      " instead of " << StringVectorToString(expectedPathes) <<
+      std::endl;
+    res = false;
+    }
+
+  res &= CheckUnPutEnv(envName, envName);
+  return res;
+}
+
 //----------------------------------------------------------------------------
 int testSystemTools(int, char*[])
 {
@@ -641,7 +863,7 @@ int testSystemTools(int, char*[])
     }
 
   // Special check for ~
-  kwsys_stl::string output;
+  std::string output;
   if(kwsys::SystemTools::GetEnv("HOME", output))
     {
     output += "/foo bar/lala";
@@ -650,7 +872,7 @@ int testSystemTools(int, char*[])
 
   for (cc = 0; checkEscapeChars[cc][0]; cc ++ )
     {
-    res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1], 
+    res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1],
                             *checkEscapeChars[cc][2], checkEscapeChars[cc][3]);
     }
 
@@ -664,5 +886,7 @@ int testSystemTools(int, char*[])
 
   res &= CheckCollapsePath();
 
+  res &= CheckGetPath();
+
   return res ? 0 : 1;
 }
diff --git a/Templates/CPack.GenericDescription.txt b/Templates/CPack.GenericDescription.txt
index 9ca1802..712ee14 100644
--- a/Templates/CPack.GenericDescription.txt
+++ b/Templates/CPack.GenericDescription.txt
@@ -1,5 +1,5 @@
 DESCRIPTION
 ===========
 
-This is an installer created using CPack (http://www.cmake.org). No additional installation instructions provided.
+This is an installer created using CPack (https://cmake.org). No additional installation instructions provided.
 
diff --git a/Templates/CPack.GenericLicense.txt b/Templates/CPack.GenericLicense.txt
index c211bb3..09c6218 100644
--- a/Templates/CPack.GenericLicense.txt
+++ b/Templates/CPack.GenericLicense.txt
@@ -1,5 +1,5 @@
 LICENSE
 =======
 
-This is an installer created using CPack (http://www.cmake.org). No license provided.
+This is an installer created using CPack (https://cmake.org). No license provided.
 
diff --git a/Templates/Windows/SmallLogo44x44.png b/Templates/Windows/SmallLogo44x44.png
new file mode 100644
index 0000000..28810b7
Binary files /dev/null and b/Templates/Windows/SmallLogo44x44.png differ
diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt
index 2be59b6..36987de 100644
--- a/Tests/BuildDepends/CMakeLists.txt
+++ b/Tests/BuildDepends/CMakeLists.txt
@@ -34,7 +34,7 @@ if(WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel")
   set(_cmake_options "-DCMAKE_EXE_LINKER_FLAGS=")
 endif()
 
-if("${CMAKE_GENERATOR}" MATCHES "Make")
+if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
   set(TEST_LINK_DEPENDS ${BuildDepends_BINARY_DIR}/Project/linkdep.txt)
   file(WRITE ${TEST_LINK_DEPENDS} "1")
 endif()
@@ -69,6 +69,9 @@ file(WRITE ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_exe.h
   "#define link_depends_no_shared_exe_value 0\n")
 set(link_depends_no_shared_check_txt ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_check.txt)
 
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/object_depends.txt "0\n")
+set(object_depends_check_txt ${BuildDepends_BINARY_DIR}/Project/object_depends_check.txt)
+
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/external.in "external original\n")
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi1-in.txt "multi1-in original\n")
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt "multi2-stamp original\n")
@@ -246,6 +249,8 @@ file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_tgt.hxx
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_lib.h
   "#define link_depends_no_shared_lib_value 0\n")
 
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/object_depends.txt "1\n")
+
 if(TEST_LINK_DEPENDS)
   file(WRITE ${TEST_LINK_DEPENDS} "2")
 endif()
@@ -359,6 +364,20 @@ else()
     "Targets link_depends_no_shared_lib and link_depends_no_shared_exe not both built.")
 endif()
 
+if(EXISTS "${object_depends_check_txt}")
+  file(STRINGS "${object_depends_check_txt}" object_depends_check LIMIT_COUNT 1)
+  if("${object_depends_check}" STREQUAL "1")
+    message(STATUS "object_depends exe is newer than object_depends.txt as expected.")
+  elseif(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
+    message(STATUS "Known limitation: OBJECT_DEPENDS does not work on ${CMAKE_GENERATOR}")
+  else()
+    message(SEND_ERROR "Project did not rebuild properly: object_depends exe is not newer than object_depends.txt.")
+  endif()
+else()
+  message(SEND_ERROR "Project did not rebuild properly.  "
+    "object_depends exe and object_depends.txt are not both present.")
+endif()
+
 if(EXISTS ${BuildDepends_BINARY_DIR}/Project/external.out)
   file(STRINGS ${BuildDepends_BINARY_DIR}/Project/external.out external_out)
   if("${external_out}" STREQUAL "external changed")
diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt
index 0db39c5..3aa57fc 100644
--- a/Tests/BuildDepends/Project/CMakeLists.txt
+++ b/Tests/BuildDepends/Project/CMakeLists.txt
@@ -182,3 +182,15 @@ if(TEST_MULTI3)
   set_property(SOURCE multi3-real.txt multi3-dummy.txt PROPERTY SYMBOLIC 1)
   add_custom_target(multi3 ALL DEPENDS multi3-real.txt)
 endif()
+
+add_executable(object_depends object_depends.cxx)
+set_property(SOURCE object_depends.cxx PROPERTY OBJECT_DEPENDS
+  ${CMAKE_CURRENT_BINARY_DIR}/object_depends.txt)
+add_custom_target(object_depends_check ALL
+  COMMAND ${CMAKE_COMMAND}
+   -Dexe=$<TARGET_FILE:object_depends>
+   -Dout=${CMAKE_CURRENT_BINARY_DIR}/object_depends_check.txt
+   -Dtxt=${CMAKE_CURRENT_BINARY_DIR}/object_depends.txt
+   -P ${CMAKE_CURRENT_SOURCE_DIR}/object_depends_check.cmake
+  )
+add_dependencies(object_depends_check object_depends)
diff --git a/Tests/BuildDepends/Project/object_depends.cxx b/Tests/BuildDepends/Project/object_depends.cxx
new file mode 100644
index 0000000..76e8197
--- /dev/null
+++ b/Tests/BuildDepends/Project/object_depends.cxx
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/Tests/BuildDepends/Project/object_depends_check.cmake b/Tests/BuildDepends/Project/object_depends_check.cmake
new file mode 100644
index 0000000..e009892
--- /dev/null
+++ b/Tests/BuildDepends/Project/object_depends_check.cmake
@@ -0,0 +1,7 @@
+if(NOT EXISTS "${txt}" OR NOT EXISTS "${exe}")
+  file(REMOVE "${out}")
+elseif("${exe}" IS_NEWER_THAN "${txt}")
+  file(WRITE "${out}" "1\n")
+else()
+  file(WRITE "${out}" "0\n")
+endif()
diff --git a/Tests/CMakeLib/testVisualStudioSlnParser.cxx b/Tests/CMakeLib/testVisualStudioSlnParser.cxx
index 5b62f23..5007ab8 100644
--- a/Tests/CMakeLib/testVisualStudioSlnParser.cxx
+++ b/Tests/CMakeLib/testVisualStudioSlnParser.cxx
@@ -3,7 +3,7 @@
 #include "cmVisualStudioSlnData.h"
 #include "cmVisualStudioSlnParser.h"
 
-#include <cmsys/ios/iostream>
+#include <iostream>
 
 //----------------------------------------------------------------------------
 static bool parsedRight(cmVisualStudioSlnParser& parser,
@@ -27,10 +27,10 @@ static bool parsedRight(cmVisualStudioSlnParser& parser,
       return true;
       }
     }
-  cmsys_ios::cerr << "cmVisualStudioSlnParser mis-parsed " << file
-                  << "." SLN_EXTENSION << "; expected result " << expected
-                  << ", got " << parser.GetParseResult()
-                  << cmsys_ios::endl;
+  std::cerr << "cmVisualStudioSlnParser mis-parsed " << file
+            << "." SLN_EXTENSION << "; expected result " << expected
+            << ", got " << parser.GetParseResult()
+            << std::endl;
   return false;
 }
 
@@ -42,8 +42,8 @@ int testVisualStudioSlnParser(int, char*[])
   // Test clean parser
   if (parser.GetParseResult() != cmVisualStudioSlnParser::ResultOK)
     {
-    cmsys_ios::cerr << "cmVisualStudioSlnParser initialisation failed"
-                    << cmsys_ios::endl;
+    std::cerr << "cmVisualStudioSlnParser initialisation failed"
+              << std::endl;
     return 1;
     }
 
@@ -73,38 +73,38 @@ int testVisualStudioSlnParser(int, char*[])
   const size_t expectedProjectCount = sizeof(names) / sizeof(*names);
   if (projects.size() != expectedProjectCount)
     {
-    cmsys_ios::cerr << "cmVisualStudioSlnParser returned bad number of "
-                    << "projects (" << projects.size() << " instead of "
-                    << expectedProjectCount << ')'
-                    << cmsys_ios::endl;
+    std::cerr << "cmVisualStudioSlnParser returned bad number of "
+              << "projects (" << projects.size() << " instead of "
+              << expectedProjectCount << ')'
+              << std::endl;
     return 1;
     }
   for (size_t idx = 0; idx < expectedProjectCount; ++idx)
     {
     if (projects[idx].GetName() != names[idx])
       {
-      cmsys_ios::cerr << "cmVisualStudioSlnParser returned bad project #"
-                      << idx << "; expected \"" << names[idx] << "\", got \""
-                      << projects[idx].GetName() << '"'
-                      << cmsys_ios::endl;
+      std::cerr << "cmVisualStudioSlnParser returned bad project #"
+                << idx << "; expected \"" << names[idx] << "\", got \""
+                << projects[idx].GetName() << '"'
+                << std::endl;
       return 1;
       }
     }
   if (projects[0].GetRelativePath() != "Utilities\\3rdParty")
     {
-    cmsys_ios::cerr << "cmVisualStudioSlnParser returned bad relative path of "
-                    << "project 3rdParty; expected \"Utilities\\3rdParty\", "
-                    << "got \"" << projects[0].GetRelativePath() << '"'
-                    << cmsys_ios::endl;
+    std::cerr << "cmVisualStudioSlnParser returned bad relative path of "
+              << "project 3rdParty; expected \"Utilities\\3rdParty\", "
+              << "got \"" << projects[0].GetRelativePath() << '"'
+              << std::endl;
     return 1;
     }
   if (projects[2].GetGUID() != "{59BCCCCD-3AD1-4491-B8F4-C5793AC007E2}")
     {
-    cmsys_ios::cerr << "cmVisualStudioSlnParser returned bad relative path of "
-                    << "project CMakeLib; expected "
-                    << "\"{59BCCCCD-3AD1-4491-B8F4-C5793AC007E2}\", "
-                    << "got \"" << projects[2].GetGUID() << '"'
-                    << cmsys_ios::endl;
+    std::cerr << "cmVisualStudioSlnParser returned bad relative path of "
+              << "project CMakeLib; expected "
+              << "\"{59BCCCCD-3AD1-4491-B8F4-C5793AC007E2}\", "
+              << "got \"" << projects[2].GetGUID() << '"'
+              << std::endl;
     return 1;
     }
   }
@@ -119,9 +119,9 @@ int testVisualStudioSlnParser(int, char*[])
     }
   if (!parser.GetParseHadBOM())
     {
-    cmsys_ios::cerr << "cmVisualStudioSlnParser didn't find BOM in bom."
-                    << SLN_EXTENSION
-                    << cmsys_ios::endl;
+    std::cerr << "cmVisualStudioSlnParser didn't find BOM in bom."
+              << SLN_EXTENSION
+              << std::endl;
     return 1;
     }
 
@@ -131,9 +131,9 @@ int testVisualStudioSlnParser(int, char*[])
     }
   if (parser.GetParseHadBOM())
     {
-    cmsys_ios::cerr << "cmVisualStudioSlnParser found BOM in nobom."
-                    << SLN_EXTENSION
-                    << cmsys_ios::endl;
+    std::cerr << "cmVisualStudioSlnParser found BOM in nobom."
+              << SLN_EXTENSION
+              << std::endl;
     return 1;
     }
   }
diff --git a/Tests/CMakeLib/testXMLParser.cxx b/Tests/CMakeLib/testXMLParser.cxx
index 54ed5dc..b5219e2 100644
--- a/Tests/CMakeLib/testXMLParser.cxx
+++ b/Tests/CMakeLib/testXMLParser.cxx
@@ -2,7 +2,7 @@
 
 #include "cmXMLParser.h"
 
-#include <cmsys/ios/iostream>
+#include <iostream>
 
 int testXMLParser(int, char*[])
 {
@@ -10,7 +10,7 @@ int testXMLParser(int, char*[])
   cmXMLParser parser;
   if(!parser.ParseFile(SOURCE_DIR "/testXMLParser.xml"))
     {
-    cmsys_ios::cerr << "cmXMLParser failed!" << cmsys_ios::endl;
+    std::cerr << "cmXMLParser failed!" << std::endl;
     return 1;
     }
   return 0;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 8865063..c82cb68 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -17,8 +17,6 @@ macro(ADD_TEST_MACRO NAME COMMAND)
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}")
 endmacro()
 
-include(${CMAKE_CURRENT_SOURCE_DIR}/RegexEscapeString.cmake)
-
 include(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake)
 
 # Fake a user home directory to avoid polluting the real one.
@@ -215,6 +213,29 @@ if(BUILD_TESTING)
         set(CMake_TEST_XCODE_VERSION "${CMAKE_MATCH_1}")
       endif()
     endif()
+    if(CMAKE_OSX_SYSROOT)
+      execute_process(
+        COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version ProductName
+        OUTPUT_VARIABLE _stdout
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        ERROR_VARIABLE _stderr
+        RESULT_VARIABLE _failed
+        )
+      if(NOT _failed)
+        set(CMAKE_OSX_SDKPRODUCT "${_stdout}")
+      endif()
+
+      execute_process(
+        COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version SDKVersion
+        OUTPUT_VARIABLE _stdout
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        ERROR_VARIABLE _stderr
+        RESULT_VARIABLE _failed
+        )
+      if(NOT _failed)
+        set(CMAKE_OSX_SDKVERSION "${_stdout}")
+      endif()
+    endif()
   endif()
 
   # Use 1500 or CTEST_TEST_TIMEOUT for long test timeout value,
@@ -255,11 +276,22 @@ if(BUILD_TESTING)
   if(TEST_RESOURCES)
     ADD_TEST_MACRO(VSResource VSResource)
   endif()
+  ADD_TEST_MACRO(MSManifest MSManifest)
   ADD_TEST_MACRO(Simple Simple)
   ADD_TEST_MACRO(PreOrder PreOrder)
   ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)
   set_tests_properties(MissingSourceFile PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Error at CMakeLists.txt:3 \\(add_executable\\):[ \r\n]*Cannot find source file:[ \r\n]*DoesNotExist/MissingSourceFile.c")
+  if(CMake_TEST_XCODE_VERSION AND CMAKE_OSX_SDKVERSION AND CMAKE_OSX_SDKPRODUCT)
+    if((NOT CMake_TEST_XCODE_VERSION VERSION_LESS 6.1) AND
+       ((NOT CMAKE_OSX_SDKPRODUCT STREQUAL "Mac OS X") OR
+        (NOT CMAKE_OSX_SDKVERSION VERSION_LESS 10.10)))
+      if(CMAKE_GENERATOR STREQUAL "Xcode")
+        ADD_TEST_MACRO(SwiftMix SwiftMix)
+        ADD_TEST_MACRO(SwiftOnly SwiftOnly)
+      endif()
+    endif()
+  endif()
   if(CMAKE_Fortran_COMPILER)
     ADD_TEST_MACRO(FortranOnly FortranOnly)
   endif()
@@ -1329,6 +1361,12 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     add_subdirectory(FindJsonCpp)
   endif()
 
+  if(CMake_TEST_FindOpenSSL)
+    add_subdirectory(FindOpenSSL)
+  endif()
+
+  add_subdirectory(FindThreads)
+
   # Matlab module
   if(CMake_TEST_FindMatlab)
     ADD_TEST_MACRO(FindMatlab.basic_checks      ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>)
@@ -1917,13 +1955,15 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     set(reg_vs10 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;InstallDir]")
     set(reg_vs11 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0;InstallDir]")
     set(reg_vs12 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0;InstallDir]")
+    set(reg_vs14 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]")
     set(reg_ws80 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.0;InstallationFolder]")
     set(reg_ws81 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.1;InstallationFolder]")
+    set(reg_ws10_0 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0\\Setup\\Build Tools for Windows 10;srcPath]")
     set(reg_wp80 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\WindowsPhone\\v8.0;InstallationFolder]")
     set(reg_wp81 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\WindowsPhone\\v8.1;InstallationFolder]")
     select_wince_sdk(reg_wince wince_sdk)
     set(reg_tegra "[HKEY_LOCAL_MACHINE\\SOFTWARE\\NVIDIA Corporation\\Nsight Tegra;sdkRoot]")
-    foreach(reg vs10 vs11 vs12 ws80 ws81 wp80 wp81 wince tegra)
+    foreach(reg vs10 vs11 vs12 vs14 ws80 ws81 ws10_0 wp80 wp81 wince tegra)
       get_filename_component(r "${reg_${reg}}" ABSOLUTE)
       if(IS_DIRECTORY "${r}")
         set(${reg} 1)
@@ -1970,6 +2010,11 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
                           -DCMAKE_SYSTEM_VERSION=8.1
         )
     endif()
+    if(vs14 AND ws10_0)
+      add_test_VSWinStorePhone(vs14-store10_0-X86 "Visual Studio 14 2015" WindowsStore 10.0)
+      add_test_VSWinStorePhone(vs14-store10_0-ARM "Visual Studio 14 2015 ARM" WindowsStore 10.0)
+      add_test_VSWinStorePhone(vs14-store10_0-X64 "Visual Studio 14 2015 Win64" WindowsStore 10.0)
+    endif()
     if(vs11 AND wp80)
       add_test_VSWinStorePhone(vs11-phone80-X86 "Visual Studio 11 2012" WindowsPhone 8.0)
       add_test_VSWinStorePhone(vs11-phone80-ARM "Visual Studio 11 2012 ARM" WindowsPhone 8.0)
@@ -2424,37 +2469,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
   set_tests_properties(CTestTestEmptyBinaryDirectory PROPERTIES
     PASS_REGULAR_EXPRESSION "TEST_SUCCESS")
 
-  configure_file(
-    "${CMake_SOURCE_DIR}/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in"
-    "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir1/test1.cmake"
-    @ONLY ESCAPE_QUOTES)
-  add_test(CTestTestConfigFileInBuildDir1 ${CMAKE_CTEST_COMMAND}
-    -S "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir1/test1.cmake" -V
-    --output-log "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir1/testOut1.log"
-    )
-  REGEX_ESCAPE_STRING(CTEST_TEST_ESCAPED_SOURCE_DIR "${CMake_SOURCE_DIR}")
-  set_tests_properties(CTestTestConfigFileInBuildDir1 PROPERTIES DEPENDS CTestTestNoBuild
-    PASS_REGULAR_EXPRESSION
-      "Reading ctest configuration file: ${CTEST_TEST_ESCAPED_SOURCE_DIR}.Tests.CTestTestConfigFileInBuildDir.CTestConfig.cmake")
-
-  configure_file(
-    "${CMake_SOURCE_DIR}/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in"
-    "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/test2.cmake"
-    @ONLY ESCAPE_QUOTES)
-  configure_file(
-    "${CMake_SOURCE_DIR}/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake"
-    "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/CTestConfig.cmake"
-    @ONLY ESCAPE_QUOTES COPYONLY)
-  add_test(CTestTestConfigFileInBuildDir2 ${CMAKE_CTEST_COMMAND}
-    -S "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/test2.cmake" -V
-    --output-log "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/testOut2.log"
-    )
-  REGEX_ESCAPE_STRING(CTEST_TEST_ESCAPED_BINARY_DIR "${CMake_BINARY_DIR}")
-  set_tests_properties(CTestTestConfigFileInBuildDir2 PROPERTIES DEPENDS CTestTestNoBuild
-    REQUIRED_FILES ${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/CTestConfig.cmake
-    PASS_REGULAR_EXPRESSION
-      "Reading ctest configuration file: ${CTEST_TEST_ESCAPED_BINARY_DIR}.Tests.CTestTestConfigFileInBuildDir2.CTestConfig.cmake")
-
   # test coverage for mumps
   # create a MumpsCoverage dir in the binary tree under Testing to
   # avoid the .NoDartCoverage files in the cmake testing tree
@@ -3035,17 +3049,55 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     if(JNI_H AND EXISTS "${JNI_H}") # in case jni.h is a broken symlink
       file(READ "${JNI_H}" JNI_FILE)
       if("${JNI_FILE}" MATCHES "JDK1_2")
-        add_test(Java ${CMAKE_CTEST_COMMAND}
+        add_test(Java.Jar ${CMAKE_CTEST_COMMAND}
           --build-and-test
           "${CMake_SOURCE_DIR}/Tests/Java"
-          "${CMake_BINARY_DIR}/Tests/Java"
+          "${CMake_BINARY_DIR}/Tests/JavaJar"
           ${build_generator_args}
           --build-project hello
+          --build-target hello
           --build-two-config
-          --build-run-dir "${CMake_BINARY_DIR}/Tests/Java/"
+          --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJar/"
           --build-options ${build_options}
           --test-command ${JAVA_RUNTIME} -classpath hello.jar HelloWorld)
-        list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Java")
+        list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJar")
+        add_test(Java.JarSourceList ${CMAKE_CTEST_COMMAND}
+          --build-and-test
+          "${CMake_SOURCE_DIR}/Tests/Java"
+          "${CMake_BINARY_DIR}/Tests/JavaJarSourceList"
+          ${build_generator_args}
+          --build-project hello
+          --build-target hello2
+          --build-two-config
+          --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJarSourceList/"
+          --build-options ${build_options}
+          --test-command ${JAVA_RUNTIME} -classpath hello2.jar HelloWorld)
+        list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJarSourceList")
+
+        # For next test, java tool must have same architecture as toolchain
+        math(EXPR _object_mode "${CMAKE_SIZEOF_VOID_P} * 8")
+        execute_process(
+          COMMAND "${Java_JAVA_EXECUTABLE}" -d${_object_mode} -version
+          OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE _result
+          )
+        if(_result EQUAL 0)
+          if(CMAKE_CONFIGURATION_TYPES)
+            set (JAVAH_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaJavah/$<CONFIGURATION>)
+          else()
+            set (JAVAH_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaJavah)
+          endif()
+          add_test(NAME Java.Javah COMMAND ${CMAKE_CTEST_COMMAND}
+            --build-and-test
+            "${CMake_SOURCE_DIR}/Tests/JavaJavah"
+            "${CMake_BINARY_DIR}/Tests/JavaJavah"
+            ${build_generator_args}
+            --build-project helloJavah
+            --build-two-config
+            --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJavah/"
+            --build-options ${build_options}
+            --test-command ${JAVA_RUNTIME} -Djava.library.path=${JAVAH_LIBRARY_PATH} -classpath hello3.jar HelloWorld2)
+          list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJavah")
+        endif()
       endif()
     endif()
   endif()
diff --git a/Tests/CMakeOnly/Test.cmake.in b/Tests/CMakeOnly/Test.cmake.in
index 8d3258b..0ae8af1 100644
--- a/Tests/CMakeOnly/Test.cmake.in
+++ b/Tests/CMakeOnly/Test.cmake.in
@@ -2,6 +2,11 @@ if (NOT TEST_SOURCE)
   set(TEST_SOURCE "${TEST}")
 endif ()
 
+set(make_program "@CMake_TEST_EXPLICIT_MAKE_PROGRAM@")
+if(make_program)
+  set(maybe_make_program "-DCMAKE_MAKE_PROGRAM=${make_program}")
+endif()
+
 set(source_dir "@CMAKE_CURRENT_SOURCE_DIR@/${TEST_SOURCE}")
 set(binary_dir "@CMAKE_CURRENT_BINARY_DIR@/${TEST}-build")
 file(REMOVE_RECURSE "${binary_dir}")
@@ -11,6 +16,7 @@ execute_process(
   "${source_dir}" -G "@CMAKE_GENERATOR@"
   -A "@CMAKE_GENERATOR_PLATFORM@"
   -T "@CMAKE_GENERATOR_TOOLSET@"
+  ${maybe_make_program}
   WORKING_DIRECTORY "${binary_dir}"
   RESULT_VARIABLE result
   )
diff --git a/Tests/CMakeTests/GetPropertyTest.cmake.in b/Tests/CMakeTests/GetPropertyTest.cmake.in
index e99193e..1ad8956 100644
--- a/Tests/CMakeTests/GetPropertyTest.cmake.in
+++ b/Tests/CMakeTests/GetPropertyTest.cmake.in
@@ -1,5 +1,3 @@
-include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
-
 get_property(FOO_BRIEF GLOBAL PROPERTY FOO BRIEF_DOCS)
 get_property(FOO_FULL GLOBAL PROPERTY FOO FULL_DOCS)
 
@@ -16,97 +14,3 @@ get_property(result VARIABLE PROPERTY test_var)
 if(NOT result STREQUAL "alpha")
   message(SEND_ERROR "bad value of VARIABLE PROPERTY test_var: got '${result}' instead of 'alpha'")
 endif()
-
-include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
-REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
-
-set(Missing-Argument-RESULT 1)
-set(Missing-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Missing-Argument.cmake:1 \\(get_property\\):.*get_property called with incorrect number of arguments.*")
-
-check_cmake_test(GetProperty
-  Missing-Argument
-)
-
-set(Bad-Scope-RESULT 1)
-set(Bad-Scope-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Scope.cmake:1 \\(get_property\\):.*get_property given invalid scope FOO\\..*")
-
-check_cmake_test(GetProperty
-  Bad-Scope
-)
-
-set(Bad-Argument-RESULT 1)
-set(Bad-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Argument.cmake:1 \\(get_property\\):.*get_property given invalid argument \"FOO\"\\..*")
-
-check_cmake_test(GetProperty
-  Bad-Argument
-)
-
-set(No-Property-RESULT 1)
-set(No-Property-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Property.cmake:1 \\(get_property\\):.*get_property not given a PROPERTY <name> argument\\..*")
-
-check_cmake_test(GetProperty
-  No-Property
-)
-
-set(Global-Name-RESULT 1)
-set(Global-Name-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Global-Name.cmake:1 \\(get_property\\):.*get_property given name for GLOBAL scope\\..*")
-
-check_cmake_test(GetProperty
-  Global-Name
-)
-
-set(Bad-Directory-RESULT 1)
-set(Bad-Directory-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Directory.cmake:1 \\(get_property\\):.*get_property DIRECTORY scope provided but requested directory was not.*found\\..*")
-
-check_cmake_test(GetProperty
-  Bad-Directory
-)
-
-set(No-Target-RESULT 1)
-set(No-Target-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Target.cmake:1 \\(get_property\\):.*get_property not given name for TARGET scope\\..*")
-
-check_cmake_test(GetProperty
-  No-Target
-)
-
-set(Bad-Target-RESULT 1)
-set(Bad-Target-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Target.cmake:1 \\(get_property\\):.*get_property could not find TARGET FOO\\..*")
-
-check_cmake_test(GetProperty
-  Bad-Target
-)
-
-set(No-Source-RESULT 1)
-set(No-Source-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Source.cmake:1 \\(get_property\\):.*get_property not given name for SOURCE scope\\..*")
-
-check_cmake_test(GetProperty
-  No-Source
-)
-
-set(No-Test-RESULT 1)
-set(No-Test-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Test.cmake:1 \\(get_property\\):.*get_property not given name for TEST scope\\..*")
-
-check_cmake_test(GetProperty
-  No-Test
-)
-
-set(Bad-Test-RESULT 1)
-set(Bad-Test-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Test.cmake:1 \\(get_property\\):.*get_property given TEST name that does not exist: FOO.*")
-
-check_cmake_test(GetProperty
-  Bad-Test
-)
-
-set(Variable-Name-RESULT 1)
-set(Variable-Name-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Variable-Name.cmake:1 \\(get_property\\):.*get_property given name for VARIABLE scope\\..*")
-
-check_cmake_test(GetProperty
-  Variable-Name
-)
-
-set(No-Cache-RESULT 1)
-set(No-Cache-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Cache.cmake:1 \\(get_property\\):.*get_property not given name for CACHE scope\\..*")
-
-check_cmake_test(GetProperty
-  No-Cache
-)
diff --git a/Tests/CMakeTests/IfTest.cmake.in b/Tests/CMakeTests/IfTest.cmake.in
index 74b8e32..e5211b4 100644
--- a/Tests/CMakeTests/IfTest.cmake.in
+++ b/Tests/CMakeTests/IfTest.cmake.in
@@ -7,9 +7,6 @@ foreach(_arg "" 0 1 2 ${TRUE_NAMES} ${FALSE_NAMES})
   set(VAR_${_arg} "${_arg}")
 endforeach()
 
-include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
-REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
-
 macro(test_vars _old)
   # Variables set to false or not set.
   foreach(_var "" 0 ${FALSE_NAMES} UNDEFINED)
@@ -159,11 +156,3 @@ foreach(_bad 2x -2x)
 endforeach()
 
 test_vars("")
-
-set(Invalid-Argument-RESULT 1)
-set(Invalid-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?If-Invalid-Argument.cmake:1 \\(if\\):.*Unknown arguments specified.*")
-
-include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
-check_cmake_test(If
-  Invalid-Argument
-)
diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
index 055b183..da614e9 100644
--- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
+++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
@@ -105,6 +105,13 @@ set(linux64_test2_libs "c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
 set(linux64_test2_dirs "/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
 list(APPEND platforms linux64_test2)
 
+# -specs=redhat-hardened-ld
+set(linux64_test3_text "COLLECT_GCC_OPTIONS='-specs=/usr/lib/rpm/redhat/redhat-hardened-ld' '-v' '-O2' '-g' '-pipe' '-Wall' '-Werror=format-security' '-fexceptions' '-fstack-protector-strong' '--param' 'ssp-buffer-size=4' '-grecord-gcc-switches' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1' '-m64' '-mtune=generic' '-I' '/usr/lib64/gfortran/modules' '-o' 'a.out' '-rdynamic' '-shared-libgcc' '-march=x86-64' '-pie'
+ /usr/libexec/gcc/x86_64-redhat-linux/5.1.1/collect2 -plugin /usr/libexec/gcc/x86_64-redhat-linux/5.1.1/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/5.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccNzxFD8.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lquadmath -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_ [...]
+set(linux64_test3_libs "gfortran;m;quadmath;m;c")
+set(linux64_test3_dirs "/usr/lib/gcc/x86_64-redhat-linux/5.1.1;/usr/lib64;/lib64;/usr/lib")
+list(APPEND platforms linux64_test3)
+
 #-----------------------------------------------------------------------------
 # Mac
 
diff --git a/Tests/CMakeTests/List-Get-CMP0007-Warn.cmake b/Tests/CMakeTests/List-Get-CMP0007-Warn.cmake
deleted file mode 100644
index 0a9264f..0000000
--- a/Tests/CMakeTests/List-Get-CMP0007-Warn.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-set(thelist "" NEW OLD)
-
-list(GET thelist 1 thevalue)
-if (NOT thevalue STREQUAL "OLD")
-    message(SEND_ERROR "returned element '${thevalue}', but expected 'OLD'")
-endif()
diff --git a/Tests/CMakeTests/ListTest.cmake.in b/Tests/CMakeTests/ListTest.cmake.in
index 77c34a9..76f5e4f 100644
--- a/Tests/CMakeTests/ListTest.cmake.in
+++ b/Tests/CMakeTests/ListTest.cmake.in
@@ -1,8 +1,5 @@
 include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
 
-include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
-REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
-
 macro(TEST command expected)
   if("x${result}" STREQUAL "x${expected}")
     #message("TEST \"${command}\" success: \"${result}\" expected: \"${expected}\"")
@@ -103,9 +100,6 @@ TEST("REVERSE empty result" "")
 list(SORT result)
 TEST("SORT empty result" "")
 
-set(No-Arguments-RESULT 1)
-set(No-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-No-Arguments.cmake:1 \\(list\\):.*list must be called with at least two arguments.*")
-
 # these trigger top-level condition
 foreach(cmd IN ITEMS Append Find Get Insert Length Reverse Remove_At Remove_Duplicates Remove_Item Sort)
   set(${cmd}-No-Arguments-RESULT 1)
@@ -132,53 +126,6 @@ foreach(cmd IN ITEMS Find Get Insert Length Remove_At Remove_Item)
   check_cmake_test_single(List "${cmd}-List-Only" "${_test_file_name}")
 endforeach()
 
-set(Length-Too-Many-Arguments-RESULT 1)
-set(Length-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Length-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command LENGTH requires two arguments.*")
-
-set(Reverse-Too-Many-Arguments-RESULT 1)
-set(Reverse-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Reverse-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REVERSE only takes one argument.*")
-
-set(Remove_Duplicates-Too-Many-Arguments-RESULT 1)
-set(Remove_Duplicates-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Remove_Duplicates-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REMOVE_DUPLICATES only takes one argument.*")
-
-set(Sort-Too-Many-Arguments-RESULT 1)
-set(Sort-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Sort-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command SORT only takes one argument.*")
-
-set(Invalid-Subcommand-RESULT 1)
-set(Invalid-Subcommand-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Invalid-Subcommand.cmake:1 \\(list\\):.*list does not recognize sub-command NO_SUCH_SUBCOMMAND.*")
-
-foreach(cmd Get Insert Remove_At)
-  set(${cmd}-Invalid-Index-RESULT 1)
-  set(${cmd}-Invalid-Index-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-${cmd}-Invalid-Index.cmake:2 \\(list\\):.*list index: 3 out of range \\(-3, 2\\).*")
-endforeach()
-
-foreach(cmd Remove_Item Reverse Remove_Duplicates Sort Remove_At)
-  string(TOUPPER ${cmd} Cmd)
-  set(${cmd}-Nonexistent-List-RESULT 1)
-  set(${cmd}-Nonexistent-List-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-${cmd}-Nonexistent-List.cmake:2 \\(list\\):.*sub-command ${Cmd} requires list to be present.*")
-endforeach()
-
-set(Get-CMP0007-Warn-RESULT 0)
-set(Get-CMP0007-Warn-STDERR ".*CMake Warning \\(dev\\) at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Get-CMP0007-Warn.cmake:3 \\(list\\):.*Policy CMP0007 is not set:.*")
-
-check_cmake_test(List
-  No-Arguments
-  Length-Too-Many-Arguments
-  Reverse-Too-Many-Arguments
-  Remove_Duplicates-Too-Many-Arguments
-  Sort-Too-Many-Arguments
-  Invalid-Subcommand
-  Get-Invalid-Index
-  Insert-Invalid-Index
-  Remove_Item-Nonexistent-List
-  Reverse-Nonexistent-List
-  Remove_Duplicates-Nonexistent-List
-  Sort-Nonexistent-List
-  Remove_At-Nonexistent-List
-  Remove_At-Invalid-Index
-  Get-CMP0007-Warn
-)
-
 set(thelist "" NEW OLD)
 
 foreach (_pol ${thelist})
diff --git a/Tests/CMakeTests/WhileTest.cmake.in b/Tests/CMakeTests/WhileTest.cmake.in
index d4cf7d7..cc22978 100644
--- a/Tests/CMakeTests/WhileTest.cmake.in
+++ b/Tests/CMakeTests/WhileTest.cmake.in
@@ -1,9 +1,6 @@
 set(NUMBERS "")
 set(COUNT 0)
 
-include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
-REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
-
 while(COUNT LESS 200)
     set(NUMBERS "${NUMBERS} ${COUNT}")
     set(COUNT "2${COUNT}")
@@ -18,40 +15,3 @@ endwhile()
 if(NOT NUMBERS STREQUAL " 0 3 30 20 3 30")
     message(SEND_ERROR "while loop nesting error, result: '${NUMBERS}'")
 endif()
-
-
-set(Missing-Argument-RESULT 1)
-set(Missing-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Argument.cmake:1 \\(while\\):.*while called with incorrect number of arguments.*")
-
-include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
-check_cmake_test(While
-  Missing-Argument
-)
-
-set(Missing-Endwhile-RESULT 1)
-set(Missing-Endwhile-STDERR ".*CMake Error in (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Endwhile.cmake:.*A logical block opening on the line.*(${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Endwhile.cmake:1 \\(while\\).*is not closed\\..*")
-
-check_cmake_test(While
-  Missing-Endwhile
-)
-
-set(Endwhile-Mismatch-RESULT 0)
-set(Endwhile-Mismatch-STDERR ".*CMake Warning \\(dev\\) in (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Mismatch.cmake:.*A logical block opening on the line.*(${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Mismatch.cmake:1 \\(while\\).*with mis-matching arguments\\..*")
-
-check_cmake_test(While
-  Endwhile-Mismatch
-)
-
-set(Endwhile-Alone-RESULT 1)
-set(Endwhile-Alone-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Alone.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.\n.*$")
-
-check_cmake_test(While
-  Endwhile-Alone
-)
-
-set(Endwhile-Alone-Args-RESULT 1)
-set(Endwhile-Alone-Args-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Alone-Args.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.  Or its arguments did not.*$")
-
-check_cmake_test(While
-  Endwhile-Alone-Args
-)
diff --git a/Tests/CPackComponents/CMakeLists.txt b/Tests/CPackComponents/CMakeLists.txt
index 1cb8669..3c8ae35 100644
--- a/Tests/CPackComponents/CMakeLists.txt
+++ b/Tests/CPackComponents/CMakeLists.txt
@@ -72,7 +72,7 @@ set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
 set(CPACK_NSIS_MENU_LINKS
   "ftp://ftpserver" "Test Ftp Link"
   "ftps://ftpsserver" "Test Ftps Link"
-  "http://www.cmake.org" "CMake Web Site"
+  "https://cmake.org" "CMake Web Site"
   "https://github.com/" "Test Https Link"
   "mailto:kitware at kitware.com" "Test MailTo Link"
   "news://newsserver" "Test News Link"
diff --git a/Tests/CPackComponentsDEB/CMakeLists.txt b/Tests/CPackComponentsDEB/CMakeLists.txt
index 5c4eeab..093b23f 100644
--- a/Tests/CPackComponentsDEB/CMakeLists.txt
+++ b/Tests/CPackComponentsDEB/CMakeLists.txt
@@ -80,6 +80,43 @@ set(CPACK_COMPONENT_HEADERS_DESCRIPTION
 # depend on the libraries component.
 set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
 
+# creates preinst/prerm scripts with specific permissions. Those permissions
+# (especially executable) should be in the final archive
+find_program(CHMOD_PROG chmod)
+if(CHMOD_PROG)
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/preinst "echo default_preinst")
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/prerm "echo default_prerm")
+
+  # Those should have 755 permission normally. We mess it up to see if
+  # CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION is able to fix
+  # it.
+  execute_process(COMMAND ${CHMOD_PROG} 640 ${CMAKE_CURRENT_BINARY_DIR}/preinst)
+  execute_process(COMMAND ${CHMOD_PROG} 640 ${CMAKE_CURRENT_BINARY_DIR}/prerm)
+
+  set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_EXTRA
+      "${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm")
+
+  set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+endif()
+
+# creates a symbolic link and a directory. Those should not be hashed.
+# warning: relocation of the symlink is not supported (symlinks with relative
+# paths)
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink mylibapp symtest)
+install(FILES ${CPackComponentsDEB_BINARY_DIR}/symtest
+        DESTINATION bin
+        COMPONENT applications)
+
+if(EXISTS "./dirtest")
+  execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ./dirtest)
+endif()
+# NOTE: directory left empty on purpose
+execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ./dirtest)
+# NOTE: we should not add the trailing "/" to dirtest
+install(DIRECTORY ${CPackComponentsDEB_BINARY_DIR}/dirtest
+        DESTINATION bin/
+        COMPONENT applications)
+
 # We may use the CPack specific config file in order
 # to tailor CPack behavior on a CPack generator specific way
 # (Behavior would be different for RPM or TGZ or DEB ...)
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake
index 5460b1a..ff22f8f 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake
@@ -36,7 +36,7 @@ find_program(LINTIAN_EXECUTABLE lintian)
 if(LINTIAN_EXECUTABLE)
   set(lintian_output_errors_all "")
   foreach(_f IN LISTS actual_output)
-    set(STRINGS_TO_AVOID "E:([^\r\n]*)control-file-has-bad-permissions")
+    set(STRINGS_TO_AVOID "E:([^\r\n]*)control-file-has-bad-permissions" "E:([^\r\n]*)md5sums-lists-nonexistent-file")
     lintian_check_specific_errors(lintian_output_errors
                                   FILENAME "${_f}"
                                   ERROR_REGEX_STRINGS "${STRINGS_TO_AVOID}")
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake
index b96669e..bf9f81d 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake
@@ -137,6 +137,8 @@ endfunction()
 
 
 # This function runs dpkg-deb on a .deb and returns its output
+# the default behaviour it to run "--info" on the specified Debian package
+# ACTION is one of the option accepted by dpkg-deb
 function(run_dpkgdeb dpkg_deb_output)
   set(${dpkg_deb_output} "" PARENT_SCOPE)
 
@@ -144,7 +146,7 @@ function(run_dpkgdeb dpkg_deb_output)
   if(DPKGDEB_EXECUTABLE)
 
     set(options "")
-    set(oneValueArgs "FILENAME")
+    set(oneValueArgs "FILENAME" "ACTION")
     set(multiValueArgs "")
     cmake_parse_arguments(run_dpkgdeb_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
 
@@ -153,8 +155,12 @@ function(run_dpkgdeb dpkg_deb_output)
       message(FATAL_ERROR "error: run_dpkgdeb needs FILENAME to be set")
     endif()
 
-    # run lintian
-    execute_process(COMMAND ${DPKGDEB_EXECUTABLE} -I ${run_dpkgdeb_deb_FILENAME}
+    if(NOT run_dpkgdeb_deb_ACTION)
+      set(run_dpkgdeb_deb_ACTION "--info")
+    endif()
+
+    # run dpkg-deb
+    execute_process(COMMAND ${DPKGDEB_EXECUTABLE} ${run_dpkgdeb_deb_ACTION} ${run_dpkgdeb_deb_FILENAME}
       WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
       OUTPUT_VARIABLE DPKGDEB_OUTPUT
       RESULT_VARIABLE DPKGDEB_RESULT
diff --git a/Tests/CPackComponentsDEB/license.txt b/Tests/CPackComponentsDEB/license.txt
index ba8ba48..d829d93 100644
--- a/Tests/CPackComponentsDEB/license.txt
+++ b/Tests/CPackComponentsDEB/license.txt
@@ -1,3 +1,3 @@
 LICENSE
 -------
-This is an installer created using CPack (http://www.cmake.org). No license provided.
+This is an installer created using CPack (https://cmake.org). No license provided.
diff --git a/Tests/CPackComponentsForAll/license.txt b/Tests/CPackComponentsForAll/license.txt
index ba8ba48..d829d93 100644
--- a/Tests/CPackComponentsForAll/license.txt
+++ b/Tests/CPackComponentsForAll/license.txt
@@ -1,3 +1,3 @@
 LICENSE
 -------
-This is an installer created using CPack (http://www.cmake.org). No license provided.
+This is an installer created using CPack (https://cmake.org). No license provided.
diff --git a/Tests/CPackWiXGenerator/CMakeLists.txt b/Tests/CPackWiXGenerator/CMakeLists.txt
index 638e788..73eaf4f 100644
--- a/Tests/CPackWiXGenerator/CMakeLists.txt
+++ b/Tests/CPackWiXGenerator/CMakeLists.txt
@@ -64,7 +64,7 @@ set(CPACK_WIX_PATCH_FILE "${CMAKE_CURRENT_SOURCE_DIR}/patch.xml")
 set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")
 
 set(CPACK_WIX_PROPERTY_ARPCOMMENTS "My Custom ARPCOMMENTS")
-set(CPACK_WIX_PROPERTY_ARPHELPLINK "http://www.cmake.org")
+set(CPACK_WIX_PROPERTY_ARPHELPLINK "https://cmake.org")
 
 include(CPack)
 
diff --git a/Tests/CTestCoverageCollectGCOV/test.cmake.in b/Tests/CTestCoverageCollectGCOV/test.cmake.in
index 29f7e7f..b2e6d6d 100644
--- a/Tests/CTestCoverageCollectGCOV/test.cmake.in
+++ b/Tests/CTestCoverageCollectGCOV/test.cmake.in
@@ -12,9 +12,9 @@ ctest_build()
 ctest_test()
 
 list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
-	"/foo/something"
-	"/3rdparty/"
-	"/bar/somethingelse"
+  "/foo/something"
+  "/3rdparty/"
+  "/bar/somethingelse"
 )
 
 include(CTestCoverageCollectGCOV)
diff --git a/Tests/CTestTest2/test.cmake.in b/Tests/CTestTest2/test.cmake.in
index 852bb6b..825b957 100644
--- a/Tests/CTestTest2/test.cmake.in
+++ b/Tests/CTestTest2/test.cmake.in
@@ -39,14 +39,19 @@ CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@
 CTEST_TEST_KWSYS:BOOL=ON
 ")
 
+set(test_exclude
+  kwsys.testProcess-10
+  )
+
 CTEST_START(Experimental)
 #CTEST_UPDATE(SOURCE "${CTEST_SOURCE_DIRECTORY}" RETURN_VALUE res)
 CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_READ_CUSTOM_FILES(${CTEST_BINARY_DIRECTORY})
 CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res START 1 END 5 STRIDE 2)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res START 7 STRIDE 2 SUBMIT_INDEX 1)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res START 2 END 4 STRIDE 2 SUBMIT_INDEX 2)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res START 6 STRIDE 2 SUBMIT_INDEX 3)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res EXCLUDE ${test_exclude} START 1 END 5 STRIDE 2)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res EXCLUDE ${test_exclude} START 7 STRIDE 2 SUBMIT_INDEX 1)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res EXCLUDE ${test_exclude} START 2 END 4 STRIDE 2 SUBMIT_INDEX 2)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res EXCLUDE ${test_exclude} START 6 STRIDE 2 SUBMIT_INDEX 3)
 CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res STRIDE 1.5)
 CTEST_COVERAGE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
 
diff --git a/Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt b/Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt
deleted file mode 100644
index 3c53e66..0000000
--- a/Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-project(CTestTestConfigFileInBuildDir)
-include(CTest)
diff --git a/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake b/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake
deleted file mode 100644
index 4458348..0000000
--- a/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-set(CTEST_PROJECT_NAME "CTestTestConfigFileInBuildDir")
-set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
-set(CTEST_DART_SERVER_VERSION "2")
-set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "open.cdash.org")
-set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
-set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in b/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in
deleted file mode 100644
index 6d29af7..0000000
--- a/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-# Settings:
-set(CTEST_DASHBOARD_ROOT                "@CMake_BINARY_DIR@/Tests/CTestTest")
-set(CTEST_SITE                          "@SITE@")
-set(CTEST_BUILD_NAME                    "CTestTest- at BUILDNAME@-ConfigFileInBuildDir1")
-
-set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestConfigFileInBuildDir")
-set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestConfigFileInBuildDir1")
-set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR               "@CMAKE_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_PLATFORM      "@CMAKE_GENERATOR_PLATFORM@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_GENERATOR_TOOLSET@")
-set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
-set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
-
-CTEST_START(Experimental)
-CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in b/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in
deleted file mode 100644
index fb298d4..0000000
--- a/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-# Settings:
-set(CTEST_DASHBOARD_ROOT                "@CMake_BINARY_DIR@/Tests/CTestTest")
-set(CTEST_SITE                          "@SITE@")
-set(CTEST_BUILD_NAME                    "CTestTest- at BUILDNAME@-ConfigFileInBuildDir2")
-
-set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestConfigFileInBuildDir")
-set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestConfigFileInBuildDir2")
-set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR               "@CMAKE_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_PLATFORM      "@CMAKE_GENERATOR_PLATFORM@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_GENERATOR_TOOLSET@")
-set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
-set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
-
-CTEST_START(Experimental)
-CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestUpdateCVS.cmake.in b/Tests/CTestUpdateCVS.cmake.in
index 1699c3f..277b3a6 100644
--- a/Tests/CTestUpdateCVS.cmake.in
+++ b/Tests/CTestUpdateCVS.cmake.in
@@ -170,3 +170,22 @@ set(CTEST_CHECKOUT_COMMAND
 
 # Run the dashboard script with CTest.
 run_dashboard_script(dash-binary)
+
+#-----------------------------------------------------------------------------
+# Test ctest_update(RETURN_VALUE) on failure
+message("Running CTest Dashboard Script (fail to update)...")
+
+set(ctest_update_check [[
+if(NOT ret LESS 0)
+  message(FATAL_ERROR "ctest_update incorrectly succeeded with ${ret}")
+endif()
+]])
+create_dashboard_script(dash-binary-fail
+  "set(CTEST_CVS_COMMAND \"update-command-does-not-exist\")
+")
+unset(ctest_update_check)
+
+# Run the dashboard script with CTest.
+set(FAIL_UPDATE 1)
+run_dashboard_script(dash-binary-fail)
+unset(FAIL_UPDATE)
diff --git a/Tests/CTestUpdateCommon.cmake b/Tests/CTestUpdateCommon.cmake
index 77b3398..458e427 100644
--- a/Tests/CTestUpdateCommon.cmake
+++ b/Tests/CTestUpdateCommon.cmake
@@ -182,6 +182,14 @@ endfunction()
 #-----------------------------------------------------------------------------
 # Function to write the dashboard test script.
 function(create_dashboard_script bin_dir custom_text)
+  if (NOT ctest_update_check)
+    set(ctest_update_check [[
+if(ret LESS 0)
+  message(FATAL_ERROR "ctest_update failed with ${ret}")
+endif()
+]])
+  endif()
+
   # Write the dashboard script.
   file(WRITE ${TOP}/${bin_dir}.cmake
     "# CTest Dashboard Script
@@ -193,8 +201,8 @@ set(CTEST_BINARY_DIRECTORY \${CTEST_DASHBOARD_ROOT}/${bin_dir})
 ${custom_text}
 # Start a dashboard and run the update step
 ctest_start(Experimental)
-ctest_update(SOURCE \${CTEST_SOURCE_DIRECTORY})
-")
+ctest_update(SOURCE \${CTEST_SOURCE_DIRECTORY} RETURN_VALUE ret ${ctest_update_args})
+${ctest_update_check}")
 endfunction()
 
 #-----------------------------------------------------------------------------
@@ -250,6 +258,24 @@ function(check_no_update bin_dir)
   endif()
 endfunction()
 
+#-----------------------------------------------------------------------------
+# Function to find the Update.xml file and make sure
+# it only has the UpdateReturnStatus failure message and no updates.
+function(check_fail_update bin_dir)
+  set(PATTERN ${TOP}/${bin_dir}/Testing/*/Update.xml)
+  file(GLOB UPDATE_XML_FILE RELATIVE ${TOP} ${PATTERN})
+  string(REGEX REPLACE "//Update.xml$" "/Update.xml"
+    UPDATE_XML_FILE "${UPDATE_XML_FILE}")
+  message(" found ${UPDATE_XML_FILE}")
+  file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_STATUS
+    REGEX "^\t<UpdateReturnStatus>[^<\n]+"
+    )
+  if(UPDATE_XML_STATUS MATCHES "Update command failed")
+    message(" correctly found 'Update command failed'")
+  else()
+    message(FATAL_ERROR " missing 'Update command failed'")
+  endif()
+endfunction()
 
 #-----------------------------------------------------------------------------
 # Function to run the dashboard through a script
@@ -263,6 +289,8 @@ function(run_dashboard_script bin_dir)
   list(APPEND UPDATE_MAYBE Updated{subdir} Updated{CTestConfig.cmake})
   if(NO_UPDATE)
     check_no_update(${bin_dir})
+  elseif(FAIL_UPDATE)
+    check_fail_update(${bin_dir})
   else()
     check_updates(${bin_dir}
       Updated{foo.txt}
diff --git a/Tests/CTestUpdateGIT.cmake.in b/Tests/CTestUpdateGIT.cmake.in
index 5987a30..6488a1f 100644
--- a/Tests/CTestUpdateGIT.cmake.in
+++ b/Tests/CTestUpdateGIT.cmake.in
@@ -334,31 +334,22 @@ set(CTEST_UPDATE_VERSION_ONLY TRUE)
 # Run the dashboard script with CTest.
 set(NO_UPDATE 1)
 run_dashboard_script(dash-binary-no-update)
+unset(NO_UPDATE)
 
 rewind_source(dash-source)
 
 #-----------------------------------------------------------------------------
 # Test ctest_update(QUIET)
-set(NO_UPDATE 0)
 message("Running CTest Dashboard Script (update quietly)...")
 
+set(ctest_update_args QUIET)
 create_dashboard_script(dash-binary-quiet
   "# git command configuration
 set(CTEST_GIT_COMMAND \"${GIT}\")
 set(CTEST_GIT_UPDATE_OPTIONS)
 set(CTEST_GIT_UPDATE_CUSTOM \${CTEST_GIT_COMMAND} pull origin master)
 ")
-
-# We need to modify the created dashboard script to include our "QUIET"
-# option.
-set(filename "${TOP}/dash-binary-quiet.cmake")
-file(READ "${filename}" contents)
-string(REPLACE
-  [=[ctest_update(SOURCE ${CTEST_SOURCE_DIRECTORY})]=]
-  [=[ctest_update(SOURCE ${CTEST_SOURCE_DIRECTORY} QUIET)]=]
-  contents
-  "${contents}")
-file(WRITE "${filename}" "${contents}")
+unset(ctest_update_args)
 
 # Run the dashboard script with CTest.
 run_dashboard_script(dash-binary-quiet)
@@ -367,3 +358,23 @@ run_dashboard_script(dash-binary-quiet)
 if("${OUTPUT}" MATCHES "Updating the repository")
   message(FATAL_ERROR "Found 'Updating the repository' in quiet output")
 endif()
+
+#-----------------------------------------------------------------------------
+# Test ctest_update(RETURN_VALUE) on failure
+message("Running CTest Dashboard Script (fail to update)...")
+
+set(ctest_update_check [[
+
+if(NOT ret LESS 0)
+  message(FATAL_ERROR "ctest_update incorrectly succeeded with ${ret}")
+endif()
+]])
+create_dashboard_script(dash-binary-fail
+  "set(CTEST_GIT_COMMAND \"update-command-does-not-exist\")
+")
+unset(ctest_update_check)
+
+# Run the dashboard script with CTest.
+set(FAIL_UPDATE 1)
+run_dashboard_script(dash-binary-fail)
+unset(FAIL_UPDATE)
diff --git a/Tests/CTestUpdateHG.cmake.in b/Tests/CTestUpdateHG.cmake.in
index c5440f9..c76bf91 100644
--- a/Tests/CTestUpdateHG.cmake.in
+++ b/Tests/CTestUpdateHG.cmake.in
@@ -164,3 +164,22 @@ execute_process(
 
 # Run the dashboard script with CTest.
 run_dashboard_script(dash-binary)
+
+#-----------------------------------------------------------------------------
+# Test ctest_update(RETURN_VALUE) on failure
+message("Running CTest Dashboard Script (fail to update)...")
+
+set(ctest_update_check [[
+if(NOT ret LESS 0)
+  message(FATAL_ERROR "ctest_update incorrectly succeeded with ${ret}")
+endif()
+]])
+create_dashboard_script(dash-binary-fail
+  "set(CTEST_HG_COMMAND \"update-command-does-not-exist\")
+")
+unset(ctest_update_check)
+
+# Run the dashboard script with CTest.
+set(FAIL_UPDATE 1)
+run_dashboard_script(dash-binary-fail)
+unset(FAIL_UPDATE)
diff --git a/Tests/CTestUpdateSVN.cmake.in b/Tests/CTestUpdateSVN.cmake.in
index b5728fd..b757a44 100644
--- a/Tests/CTestUpdateSVN.cmake.in
+++ b/Tests/CTestUpdateSVN.cmake.in
@@ -147,3 +147,22 @@ set(CTEST_CHECKOUT_COMMAND
 
 # Run the dashboard script with CTest.
 run_dashboard_script(dash-binary)
+
+#-----------------------------------------------------------------------------
+# Test ctest_update(RETURN_VALUE) on failure
+message("Running CTest Dashboard Script (fail to update)...")
+
+set(ctest_update_check [[
+if(NOT ret LESS 0)
+  message(FATAL_ERROR "ctest_update incorrectly succeeded with ${ret}")
+endif()
+]])
+create_dashboard_script(dash-binary-fail
+  "set(CTEST_SVN_COMMAND \"update-command-does-not-exist\")
+")
+unset(ctest_update_check)
+
+# Run the dashboard script with CTest.
+set(FAIL_UPDATE 1)
+run_dashboard_script(dash-binary-fail)
+unset(FAIL_UPDATE)
diff --git a/Tests/Contracts/Trilinos/CMakeLists.txt b/Tests/Contracts/Trilinos/CMakeLists.txt
index f5757b5..8d74ca5 100644
--- a/Tests/Contracts/Trilinos/CMakeLists.txt
+++ b/Tests/Contracts/Trilinos/CMakeLists.txt
@@ -27,7 +27,7 @@ endif()
 message(STATUS "HOME='${HOME}'")
 
 if(NOT DEFINED url)
-  set(url "http://www.cmake.org/files/contracts/trilinos-11.4.1.tar.gz")
+  set(url "https://cmake.org/files/contracts/trilinos-11.4.1.tar.gz")
 endif()
 message(STATUS "url='${url}'")
 
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index 0df42d9..aedc89b 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -29,14 +29,14 @@ add_custom_command(TARGET testLib1 POST_BUILD
                                    $<TARGET_FILE:testLib1>.genex
   )
 install(FILES $<TARGET_FILE:testLib1>.genex
-  DESTINATION lib
+  DESTINATION $<1:lib>$<0:/wrong>
   )
 set_property(TARGET testLib1 PROPERTY MY_FILES
   ${CMAKE_CURRENT_SOURCE_DIR}/testLib1file1.txt
   ${CMAKE_CURRENT_SOURCE_DIR}/testLib1file2.txt
   )
 install(FILES $<TARGET_PROPERTY:testLib1,MY_FILES>
-  DESTINATION doc
+  DESTINATION $<1:doc>$<0:/wrong>
   )
 
 # Test library with empty link interface.  Link it to an implementation
@@ -73,6 +73,12 @@ install(TARGETS testLibPerConfigDest EXPORT exp
   DESTINATION lib/$<$<BOOL:$<CONFIG>>:$<CONFIG>>$<$<NOT:$<BOOL:$<CONFIG>>>:NoConfig>
   )
 
+# Test OUTPUT_NAME properties with generator expressions
+add_library(testLib7 STATIC testLib7.c)
+set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_DEBUG testLib7D-$<CONFIG>)
+set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_RELEASE testLib7R-$<CONFIG>)
+set_property(TARGET testLib7 PROPERTY OUTPUT_NAME testLib7-$<CONFIG>)
+
 # Work-around: Visual Studio 6 does not support per-target object files.
 set(VS6)
 if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
@@ -99,6 +105,19 @@ target_link_libraries(testLib4
 add_executable(testExe3 testExe3.c)
 set_property(TARGET testExe3 PROPERTY MACOSX_BUNDLE 1)
 
+# Test <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_DIRECTORY[_<CONFIG>] properties with generator expressions
+add_executable(testExe4 testExe4.c)
+target_link_libraries(testExe4 testExe1lib)
+set_property(TARGET testLib7 PROPERTY ARCHIVE_OUTPUT_DIRECTORY_DEBUG testLib7D-$<CONFIG>)
+set_property(TARGET testLib7 PROPERTY ARCHIVE_OUTPUT_DIRECTORY_RELEASE testLib7R-$<CONFIG>)
+set_property(TARGET testLib7 PROPERTY ARCHIVE_OUTPUT_DIRECTORY testLib7-$<CONFIG>)
+set_property(TARGET testLib5 PROPERTY LIBRARY_OUTPUT_DIRECTORY_DEBUG testLib5D-$<CONFIG>)
+set_property(TARGET testLib5 PROPERTY LIBRARY_OUTPUT_DIRECTORY_RELEASE testLib5R-$<CONFIG>)
+set_property(TARGET testLib5 PROPERTY LIBRARY_OUTPUT_DIRECTORY testLib5-$<CONFIG>)
+set_property(TARGET testExe4 PROPERTY RUNTIME_OUTPUT_DIRECTORY_DEBUG testExe4D-$<CONFIG>)
+set_property(TARGET testExe4 PROPERTY RUNTIME_OUTPUT_DIRECTORY_RELEASE testExe4R-$<CONFIG>)
+set_property(TARGET testExe4 PROPERTY RUNTIME_OUTPUT_DIRECTORY testExe4-$<CONFIG>)
+
 # Test cyclic dependencies.
 add_library(testLibCycleA STATIC
   testLibCycleA1.c testLibCycleA2.c testLibCycleA3.c)
@@ -108,13 +127,16 @@ target_link_libraries(testLibCycleA testLibCycleB)
 target_link_libraries(testLibCycleB testLibCycleA)
 set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
 
+add_library(testLibNoSONAME SHARED testLibNoSONAME.c)
+set_property(TARGET testLibNoSONAME PROPERTY NO_SONAME 1)
+
 # Test exporting dependent libraries into different exports
 add_library(testLibRequired testLibRequired.c)
 add_library(testLibDepends testLibDepends.c)
 target_link_libraries(testLibDepends LINK_PUBLIC testLibRequired)
 
 macro(add_include_lib _libName)
-  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "// no content\n")
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "/* no content */\n")
   add_library(${_libName} "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c")
   file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_libName}")
   set_property(TARGET ${_libName} APPEND PROPERTY
@@ -122,7 +144,7 @@ macro(add_include_lib _libName)
         "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${_libName}>"
       )
   if (NOT "${ARGV1}" STREQUAL "NO_HEADER")
-      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" "// no content\n")
+      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" "/* no content */\n")
       install(FILES
         "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h"
           DESTINATION include/${_libName}
@@ -160,7 +182,7 @@ install(FILES
 )
 add_include_lib(testLibIncludeRequired6)
 
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired7/testLibIncludeRequired7.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired7/testLibIncludeRequired7.h" "/* No content */\n")
 install(FILES
   "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired7/testLibIncludeRequired7.h"
     DESTINATION include/testLibIncludeRequired7
@@ -369,22 +391,22 @@ install(TARGETS
 install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredTargets.cmake DESTINATION lib/cmake/testLibRequired)
 
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest/installIncludesTest.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest/installIncludesTest.h" "/* No content */\n")
 
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2/installIncludesTest2.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2/installIncludesTest2.h" "/* No content */\n")
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest3/testLibRequired")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest3/testLibRequired/installIncludesTest3.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest3/testLibRequired/installIncludesTest3.h" "/* No content */\n")
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/testLibRequired/installIncludesTest4")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibRequired/installIncludesTest4/installIncludesTest4.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibRequired/installIncludesTest4/installIncludesTest4.h" "/* No content */\n")
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest5")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest5/installIncludesTest5.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest5/installIncludesTest5.h" "/* No content */\n")
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest6")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest6/installIncludesTest6.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest6/installIncludesTest6.h" "/* No content */\n")
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest7")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest7/installIncludesTest7.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest7/installIncludesTest7.h" "/* No content */\n")
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest8")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest8/installIncludesTest8.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest8/installIncludesTest8.h" "/* No content */\n")
 install(FILES
   "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest/installIncludesTest.h"
   DESTINATION installIncludesTest
@@ -444,10 +466,11 @@ install(FILES
 # Install and export from install tree.
 install(
   TARGETS
-  testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3
+  testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3 testExe4
   testExe2lib testLib4lib testLib4libdbg testLib4libopt
-  testLib6
+  testLib6 testLib7
   testLibCycleA testLibCycleB
+  testLibNoSONAME
   cmp0022NEW cmp0022OLD
   systemlib
   EXPORT exp
@@ -505,9 +528,10 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
   NAMESPACE bld_
   FILE ExportBuildTree.cmake
   )
-export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
+export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
   testLib4lib testLib4libdbg testLib4libopt
   testLibCycleA testLibCycleB
+  testLibNoSONAME
   testLibPerConfigDest
   NAMESPACE bld_
   APPEND FILE ExportBuildTree.cmake
@@ -527,5 +551,5 @@ install(
   ARCHIVE DESTINATION lib
   INCLUDES DESTINATION include/abs
   )
-install(DIRECTORY include/abs DESTINATION include)
+install(DIRECTORY include/abs DESTINATION $<1:include>$<0:/wrong>)
 install(EXPORT expAbs NAMESPACE expAbs_ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/expAbs)
diff --git a/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt
index 00a5375..fd55c42 100644
--- a/Tests/ExportImport/Export/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Export/Interface/CMakeLists.txt
@@ -39,7 +39,11 @@ install(FILES
   DESTINATION src
 )
 
+add_library(cmakeonly INTERFACE)
+set_property(TARGET cmakeonly PROPERTY INTERFACE_COMPILE_DEFINITIONS [[DEF="\"\$\B"]])
+
 install(TARGETS headeronly sharediface use_auto_type use_c_restrict source_target
+                cmakeonly
   EXPORT expInterface
 )
 install(TARGETS sharedlib
diff --git a/Tests/ExportImport/Export/testExe4.c b/Tests/ExportImport/Export/testExe4.c
new file mode 100644
index 0000000..731057e
--- /dev/null
+++ b/Tests/ExportImport/Export/testExe4.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main(int argc, const char* argv[])
+{
+  if(argc < 2)
+    {
+    fprintf(stderr, "Must specify output file.\n");
+    return 1;
+    }
+  {
+  FILE* f = fopen(argv[1], "w");
+  if(f)
+    {
+    fprintf(f, "int generated_by_testExe4() { return 0; }\n");
+    fclose(f);
+    }
+  else
+    {
+    fprintf(stderr, "Error writing to %s\n", argv[1]);
+    return 1;
+    }
+  }
+  return 0;
+}
diff --git a/Tests/ExportImport/Export/testLib7.c b/Tests/ExportImport/Export/testLib7.c
new file mode 100644
index 0000000..7acae9e
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib7.c
@@ -0,0 +1 @@
+int testLib7(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testLibNoSONAME.c b/Tests/ExportImport/Export/testLibNoSONAME.c
new file mode 100644
index 0000000..2193e1f
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibNoSONAME.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testLibNoSONAME_EXPORT __declspec(dllexport)
+#else
+# define testLibNoSONAME_EXPORT
+#endif
+
+testLibNoSONAME_EXPORT int testLibNoSONAME(void) { return 0; }
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index 17d983a..5ce9628 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -19,11 +19,17 @@ add_custom_command(
   COMMAND exp_testExe3 ${Import_BINARY_DIR}/exp_generated3.c
   DEPENDS exp_testExe3
   )
+add_custom_command(
+  OUTPUT ${Import_BINARY_DIR}/exp_generated4.c
+  COMMAND exp_testExe4 ${Import_BINARY_DIR}/exp_generated4.c
+  DEPENDS exp_testExe4
+  )
 
 add_executable(imp_testExe1
   imp_testExe1.c
   ${Import_BINARY_DIR}/exp_generated.c
   ${Import_BINARY_DIR}/exp_generated3.c
+  ${Import_BINARY_DIR}/exp_generated4.c
   )
 
 # Try linking to a library imported from the install tree.
@@ -33,6 +39,7 @@ target_link_libraries(imp_testExe1
   exp_testLib4
   exp_testLib5
   exp_testLib6
+  exp_testLib7
   exp_testLibCycleA
   exp_testLibPerConfigDest
   )
@@ -52,11 +59,17 @@ add_custom_command(
   COMMAND bld_testExe3 ${Import_BINARY_DIR}/bld_generated3.c
   DEPENDS bld_testExe3
   )
+add_custom_command(
+  OUTPUT ${Import_BINARY_DIR}/bld_generated4.c
+  COMMAND bld_testExe4 ${Import_BINARY_DIR}/bld_generated4.c
+  DEPENDS bld_testExe4
+  )
 
 add_executable(imp_testExe1b
   imp_testExe1.c
   ${Import_BINARY_DIR}/bld_generated.c
   ${Import_BINARY_DIR}/bld_generated3.c
+  ${Import_BINARY_DIR}/bld_generated4.c
   )
 
 # Try linking to a library imported from the build tree.
@@ -66,6 +79,7 @@ target_link_libraries(imp_testExe1b
   bld_testLib4
   bld_testLib5
   bld_testLib6
+  bld_testLib7
   bld_testLibCycleA
   bld_testLibPerConfigDest
   )
@@ -76,6 +90,50 @@ add_custom_target(check_testLib1_genex ALL
           -P ${CMAKE_CURRENT_SOURCE_DIR}/check_testLib1_genex.cmake
   )
 
+if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
+    "${CMAKE_C_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG")
+  foreach(ns exp bld)
+    get_property(configs TARGET ${ns}_testLib5 PROPERTY IMPORTED_CONFIGURATIONS)
+    foreach(c ${configs})
+      string(TOUPPER "${c}" CONFIG)
+      get_property(soname TARGET ${ns}_testLib5 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
+      if(soname)
+        message(SEND_ERROR "${ns}_testLib5 has IMPORTED_NO_SONAME_${CONFIG} but should:\n  ${soname}")
+      else()
+        message(STATUS "${ns}_testLib5 does not have IMPORTED_NO_SONAME_${CONFIG} as expected")
+      endif()
+    endforeach()
+
+    get_property(configs TARGET ${ns}_testLibNoSONAME PROPERTY IMPORTED_CONFIGURATIONS)
+    foreach(c ${configs})
+      string(TOUPPER "${c}" CONFIG)
+      get_property(soname TARGET ${ns}_testLibNoSONAME PROPERTY IMPORTED_NO_SONAME_${CONFIG})
+      if(soname)
+        message(STATUS "${ns}_testLibNoSONAME has IMPORTED_NO_SONAME_${CONFIG} as expected")
+      else()
+        message(SEND_ERROR "${ns}_testLibNoSONAME does not have IMPORTED_NO_SONAME_${CONFIG} but should")
+      endif()
+    endforeach()
+
+    # Parse the binary to check for SONAME if possible.
+    if("${CMAKE_EXECUTABLE_FORMAT}" MATCHES "ELF")
+      find_program(READELF_EXE readelf)
+      if(READELF_EXE)
+        add_custom_target(check_${ns}_testLib5_soname ALL COMMAND
+          ${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
+          -Dlib=$<TARGET_FILE:${ns}_testLib5>
+          -P ${CMAKE_CURRENT_SOURCE_DIR}/check_lib_soname.cmake
+          )
+        add_custom_target(check_${ns}_testLibNoSONAME_soname ALL COMMAND
+          ${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
+          -Dlib=$<TARGET_FILE:${ns}_testLibNoSONAME>
+          -P ${CMAKE_CURRENT_SOURCE_DIR}/check_lib_nosoname.cmake
+          )
+      endif()
+    endif()
+  endforeach()
+endif()
+
 add_executable(cmp0022OLD_test cmp0022OLD_test_vs6_1.cpp)
 target_link_libraries(cmp0022OLD_test bld_cmp0022OLD)
 add_executable(cmp0022NEW_test cmp0022NEW_test_vs6_1.cpp)
diff --git a/Tests/ExportImport/Import/A/check_lib_nosoname.cmake b/Tests/ExportImport/Import/A/check_lib_nosoname.cmake
new file mode 100644
index 0000000..613391e
--- /dev/null
+++ b/Tests/ExportImport/Import/A/check_lib_nosoname.cmake
@@ -0,0 +1,7 @@
+execute_process(COMMAND ${readelf} -d ${lib} OUTPUT_FILE ${lib}.readelf.txt)
+file(STRINGS ${lib}.readelf.txt soname REGEX "SONAME")
+if(soname)
+  message(FATAL_ERROR "${lib} has soname but should not:\n  ${soname}")
+else()
+  message(STATUS "${lib} has no soname as expected:\n  ${soname}")
+endif()
diff --git a/Tests/ExportImport/Import/A/check_lib_soname.cmake b/Tests/ExportImport/Import/A/check_lib_soname.cmake
new file mode 100644
index 0000000..a3c4b54
--- /dev/null
+++ b/Tests/ExportImport/Import/A/check_lib_soname.cmake
@@ -0,0 +1,7 @@
+execute_process(COMMAND ${readelf} -d ${lib} OUTPUT_FILE ${lib}.readelf.txt)
+file(STRINGS ${lib}.readelf.txt soname REGEX "SONAME")
+if(soname)
+  message(STATUS "${lib} has soname as expected:\n  ${soname}")
+else()
+  message(FATAL_ERROR "${lib} has no soname but should:\n  ${soname}")
+endif()
diff --git a/Tests/ExportImport/Import/A/imp_testExe1.c b/Tests/ExportImport/Import/A/imp_testExe1.c
index 150fcef..0a74309 100644
--- a/Tests/ExportImport/Import/A/imp_testExe1.c
+++ b/Tests/ExportImport/Import/A/imp_testExe1.c
@@ -1,11 +1,13 @@
 extern int generated_by_testExe1();
 extern int generated_by_testExe3();
+extern int generated_by_testExe4();
 extern int testLib2();
 extern int testLib3();
 extern int testLib4();
 extern int testLib4lib();
 extern int testLib5();
 extern int testLib6();
+extern int testLib7();
 extern int testLibCycleA1();
 extern int testLibPerConfigDest();
 
@@ -21,7 +23,7 @@ extern testLib4libcfg(void);
 int main()
 {
   return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
-          + testLib5() + testLib6() + testLibCycleA1()
+          + testLib5() + testLib6() + testLib7() + testLibCycleA1()
           + testLibPerConfigDest()
-          + generated_by_testExe3() + testLib4lib() + testLib4libcfg());
+          + generated_by_testExe3() + generated_by_testExe4() + testLib4lib() + testLib4libcfg());
 }
diff --git a/Tests/ExportImport/Import/Interface/CMakeLists.txt b/Tests/ExportImport/Import/Interface/CMakeLists.txt
index 51d518e..c850508 100644
--- a/Tests/ExportImport/Import/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Import/Interface/CMakeLists.txt
@@ -99,3 +99,14 @@ add_executable(interfacetest_exp interfacetest.cpp)
 target_link_libraries(interfacetest_exp exp::sharediface)
 
 do_try_compile(exp)
+
+foreach(ns exp bld)
+  get_property(defs TARGET ${ns}::cmakeonly PROPERTY INTERFACE_COMPILE_DEFINITIONS)
+  if(NOT defs STREQUAL [[DEF="\"\$\B"]])
+    message(SEND_ERROR
+      "${ns}::cmakeonly property INTERFACE_COMPILE_DEFINITIONS is:\n"
+      " ${defs}\n"
+      "not\n"
+      " " [[DEF="\"\$\B"]] "\n")
+  endif()
+endforeach()
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index de62ce7..b5041c7 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -364,6 +364,66 @@ if(do_git_tests)
   )
   set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
 
+  # Unzip/untar the git repository in our source folder so that other
+  # projects below may use it to test git args of ExternalProject_Add
+  #
+  set(proj SetupLocalGITRepositoryWithSubmodules)
+  ExternalProject_Add(${proj}
+    SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/GIT-with-submodules
+    URL ${CMAKE_CURRENT_SOURCE_DIR}/gitrepo-sub.tgz
+    BUILD_COMMAND ""
+    CONFIGURE_COMMAND "${GIT_EXECUTABLE}" --version
+    INSTALL_COMMAND ""
+  )
+  set_property(TARGET ${proj}
+    PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing")
+
+  set(local_git_repo "../../LocalRepositories/GIT-with-submodules")
+
+  set(proj TS1-GIT-no-GIT_SUBMODULES)
+  ExternalProject_Add(${proj}
+    GIT_REPOSITORY "${local_git_repo}"
+    CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+               -DWITH_m1:BOOL=ON
+               -DWITH_m2:BOOL=ON
+    BUILD_COMMAND ""
+    INSTALL_COMMAND ""
+    DEPENDS "SetupLocalGITRepository"
+            "SetupLocalGITRepositoryWithSubmodules"
+  )
+  set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+  set(proj TS1-GIT-empty-GIT_SUBMODULES)
+  ExternalProject_Add(${proj}
+    GIT_REPOSITORY "${local_git_repo}"
+    GIT_SUBMODULES ""
+    CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+               -DWITH_m1:BOOL=ON
+               -DWITH_m2:BOOL=ON
+    BUILD_COMMAND ""
+    INSTALL_COMMAND ""
+    DEPENDS "SetupLocalGITRepository"
+            "SetupLocalGITRepositoryWithSubmodules"
+  )
+  set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+  set(proj TS1-GIT-some-GIT_SUBMODULES)
+  ExternalProject_Add(${proj}
+    GIT_REPOSITORY "${local_git_repo}"
+    GIT_SUBMODULES "m/m1"
+    CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+               -DWITH_m1:BOOL=ON
+               -DWITH_m2:BOOL=OFF
+    BUILD_COMMAND ""
+    INSTALL_COMMAND ""
+    DEPENDS "SetupLocalGITRepository"
+            "SetupLocalGITRepositoryWithSubmodules"
+  )
+  set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
 endif()
 
 set(do_hg_tests 0)
diff --git a/Tests/ExternalProject/Example/CMakeLists.txt b/Tests/ExternalProject/Example/CMakeLists.txt
index 69ebaaf..4c12895 100644
--- a/Tests/ExternalProject/Example/CMakeLists.txt
+++ b/Tests/ExternalProject/Example/CMakeLists.txt
@@ -5,7 +5,7 @@ include(ExternalProject)
 
 ExternalProject_Add(
   cmake281
-  URL http://www.cmake.org/files/v2.8/cmake-2.8.1.tar.gz
+  URL https://cmake.org/files/v2.8/cmake-2.8.1.tar.gz
   CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
   BUILD_COMMAND ""
 )
diff --git a/Tests/ExternalProject/gitrepo-sub.tgz b/Tests/ExternalProject/gitrepo-sub.tgz
new file mode 100644
index 0000000..c0b5360
Binary files /dev/null and b/Tests/ExternalProject/gitrepo-sub.tgz differ
diff --git a/Tests/FindGTK2/CMakeLists.txt b/Tests/FindGTK2/CMakeLists.txt
index 1c5987c..0105fae 100644
--- a/Tests/FindGTK2/CMakeLists.txt
+++ b/Tests/FindGTK2/CMakeLists.txt
@@ -9,6 +9,7 @@ if(GTK2_GTK_FOUND)
     "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtk"
      ${build_generator_args}
     --build-target gtk-all-libs
+    --build-project gtk
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtk"
     --force-new-ctest-process
     --test-command ${CMAKE_CTEST_COMMAND} -V
@@ -22,6 +23,7 @@ if(GTK2_GTKMM_FOUND)
     "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtkmm"
      ${build_generator_args}
     --build-target gtkmm-all-libs
+    --build-project gtkmm
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtkmm"
     --force-new-ctest-process
     --test-command ${CMAKE_CTEST_COMMAND} -V
@@ -310,6 +312,7 @@ if(TARGET GTK2::gtkmm)
     "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtkmm"
      ${build_generator_args}
     --build-target gtkmm-target
+    --build-project gtkmm
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtkmm"
     --force-new-ctest-process
     --test-command ${CMAKE_CTEST_COMMAND} -V
diff --git a/Tests/FindOpenSSL/CMakeLists.txt b/Tests/FindOpenSSL/CMakeLists.txt
new file mode 100644
index 0000000..66b3fb2
--- /dev/null
+++ b/Tests/FindOpenSSL/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_test(NAME FindOpenSSL.rand COMMAND ${CMAKE_CTEST_COMMAND}
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindOpenSSL/rand"
+  "${CMake_BINARY_DIR}/Tests/FindOpenSSL/rand"
+  ${build_generator_args}
+  --build-project FindOpenSSL_rand
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V
+  )
diff --git a/Tests/FindOpenSSL/rand/CMakeLists.txt b/Tests/FindOpenSSL/rand/CMakeLists.txt
new file mode 100644
index 0000000..520d5d2
--- /dev/null
+++ b/Tests/FindOpenSSL/rand/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.0)
+project(FindOpenSSL_rand CXX)
+include(CTest)
+
+find_package(OpenSSL REQUIRED)
+
+add_executable(tstopensslrand_tgt main.cc)
+target_link_libraries(tstopensslrand_tgt OpenSSL::SSL)
+add_test(NAME tstopensslrand_tgt COMMAND tstopensslrand_tgt)
+
+add_executable(tstopensslrand_var main.cc)
+target_link_libraries(tstopensslrand_var ${OPENSSL_LIBRARIES})
+target_include_directories(tstopensslrand_var PRIVATE ${OPENSSL_INCLUDE_DIR})
+add_test(NAME tstopensslrand_var COMMAND tstopensslrand_var)
diff --git a/Tests/FindOpenSSL/rand/main.cc b/Tests/FindOpenSSL/rand/main.cc
new file mode 100644
index 0000000..a5d1ac0
--- /dev/null
+++ b/Tests/FindOpenSSL/rand/main.cc
@@ -0,0 +1,22 @@
+#include <openssl/rand.h>
+
+int main()
+{
+  // return value
+  int retval = 1;
+
+  // bytes buffer
+  unsigned char buf[1024];
+
+  // random bytes
+  int rezval = RAND_bytes(buf, sizeof(buf)); /* 1 succes, 0 otherwise */
+
+  // check result
+  if(rezval == 1)
+  {
+    retval = 0;
+  }
+
+  // return code
+  return retval;
+}
diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in
index e4df9d6..8e7ff72 100644
--- a/Tests/FindPackageModeMakefileTest/Makefile.in
+++ b/Tests/FindPackageModeMakefileTest/Makefile.in
@@ -4,6 +4,7 @@ include cmakeExecutable.mk
 CMAKE_CURRENT_BINARY_DIR = "@CMAKE_CURRENT_BINARY_DIR@"
 CMAKE_CXX_COMPILER = "@CMAKE_CXX_COMPILER@"
 CMAKE_CXX_COMPILER_ID = "@CMAKE_CXX_COMPILER_ID@"
+CMAKE_CXX_FLAGS = @CMAKE_CXX_FLAGS@
 
 CMAKE_FOO = $(CMAKE) --find-package -DCMAKE_MODULE_PATH=$(CMAKE_CURRENT_BINARY_DIR) -DNAME=Foo -DLANGUAGE=CXX -DCOMPILER_ID=$(CMAKE_CXX_COMPILER_ID)
 
@@ -14,7 +15,7 @@ all: pngtest
 main.o: clean main.cpp
 	@$(CMAKE_FOO) -DMODE=COMPILE >$(tmp)
 	@foo="`cat $(tmp)`"; \
-	 printf '"%s" %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CXXFLAGS)" "$$foo" >$(tmp)
+	 printf '"%s" %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$$foo" >$(tmp)
 	@cat $(tmp)
 	@sh $(tmp)
 	@rm -f $(tmp)
@@ -22,7 +23,7 @@ main.o: clean main.cpp
 pngtest: main.o
 	@$(CMAKE_FOO) -DMODE=LINK >$(tmp)
 	@foo="`cat $(tmp)`"; \
-	 printf '"%s" %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CXXFLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
+	 printf '"%s" %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
 	@cat $(tmp)
 	@sh $(tmp)
 	@rm -f $(tmp)
diff --git a/Tests/FindThreads/C-only/CMakeLists.txt b/Tests/FindThreads/C-only/CMakeLists.txt
new file mode 100644
index 0000000..ab4ca0d
--- /dev/null
+++ b/Tests/FindThreads/C-only/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
+project(FindThreads_C-only C)
+
+set(CMAKE_THREAD_PREFER_PTHREAD On)
+find_package(Threads REQUIRED)
+
+if (NOT WIN32)
+  add_executable(thr ${CMAKE_CURRENT_SOURCE_DIR}/../../../Modules/CheckForPthreads.c)
+  target_link_libraries(thr Threads::Threads)
+endif ()
diff --git a/Tests/FindThreads/CMakeLists.txt b/Tests/FindThreads/CMakeLists.txt
new file mode 100644
index 0000000..aa9499b
--- /dev/null
+++ b/Tests/FindThreads/CMakeLists.txt
@@ -0,0 +1,11 @@
+foreach (_lang IN ITEMS C CXX)
+  add_test(NAME FindThreads.${_lang}-only COMMAND ${CMAKE_CTEST_COMMAND}
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindThreads/${_lang}-only"
+    "${CMake_BINARY_DIR}/Tests/FindThreads/${_lang}-only"
+    ${build_generator_args}
+    --build-project FindThreads_${_lang}-only
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V
+    )
+endforeach ()
diff --git a/Tests/FindThreads/CXX-only/CMakeLists.txt b/Tests/FindThreads/CXX-only/CMakeLists.txt
new file mode 100644
index 0000000..9993123
--- /dev/null
+++ b/Tests/FindThreads/CXX-only/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
+project(FindThreads_CXX-only CXX)
+
+set(CMAKE_THREAD_PREFER_PTHREAD On)
+find_package(Threads REQUIRED)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../../Modules/CheckForPthreads.c
+               ${CMAKE_CURRENT_BINARY_DIR}/CheckForPthreads.cxx)
+
+if (NOT WIN32)
+  add_executable(thr ${CMAKE_CURRENT_BINARY_DIR}/CheckForPthreads.cxx)
+  target_link_libraries(thr Threads::Threads)
+endif ()
diff --git a/Tests/FortranC/Flags.cmake.in b/Tests/FortranC/Flags.cmake.in
index 2300fc6..cf361a5 100644
--- a/Tests/FortranC/Flags.cmake.in
+++ b/Tests/FortranC/Flags.cmake.in
@@ -12,11 +12,17 @@ configure_file("${src}/test_opt.sh.in" "${bld}/fc.sh" @ONLY)
 set(ID)
 set(COMMAND)
 
+set(make_program "@CMake_TEST_EXPLICIT_MAKE_PROGRAM@")
+if(make_program)
+  set(maybe_make_program "-DCMAKE_MAKE_PROGRAM=${make_program}")
+endif()
+
 execute_process(
   WORKING_DIRECTORY "${bld}"
   COMMAND ${CMAKE_COMMAND} "${src}" -G "@CMAKE_GENERATOR@"
                            -A "@CMAKE_GENERATOR_PLATFORM@"
                            -T "@CMAKE_GENERATOR_TOOLSET@"
+                           ${maybe_make_program}
                            "-DFortranC_TEST_FLAGS=1"
                            "-DCMAKE_C_COMPILER=${bld}/cc.sh"
                            "-DCMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@"
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 758165c..27f33a2 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -66,7 +66,7 @@ add_custom_target(check-part1 ALL
     -Dtest_colons_4=$<1:C:\\CMake>
     -Dtest_colons_5=$<1:C:/CMake>
     -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part1.cmake
-  COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 3)"
+  COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 4)"
   VERBATIM
   )
 
@@ -137,7 +137,7 @@ add_custom_target(check-part2 ALL
     -Dtest_arbitrary_content_comma_9=$<1:a,,b,,>
     -Dtest_arbitrary_content_comma_10=$<1:,,a,,b,,>
     -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake
-  COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 3)"
+  COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 4)"
   VERBATIM
 )
 
@@ -221,7 +221,27 @@ add_custom_target(check-part3 ALL
     -Dequal22=$<EQUAL:10,-012>
     -Dequal23=$<EQUAL:-10,-012>
     -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake
-  COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 3)"
+  COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 4)"
+  VERBATIM
+  )
+
+if(WIN32)
+  set(test_shell_path c:/shell/path)
+else()
+  set(test_shell_path /shell/path)
+endif()
+set(path_prefix BYPASS_FURTHER_CONVERSION)
+
+add_custom_target(check-part4 ALL
+  COMMAND ${CMAKE_COMMAND}
+    # Prefix path to bypass its further conversion when being processed by
+    # CMake as command-line argument
+    -Dtest_shell_path=${path_prefix}$<SHELL_PATH:${test_shell_path}>
+    -Dpath_prefix=${path_prefix}
+    -DWIN32=${WIN32}
+    -DCMAKE_GENERATOR=${CMAKE_GENERATOR}
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part4.cmake
+  COMMAND ${CMAKE_COMMAND} -E echo "check done (part 4 of 4)"
   VERBATIM
   )
 
diff --git a/Tests/GeneratorExpression/check-common.cmake b/Tests/GeneratorExpression/check-common.cmake
index 8ffebd7..faf5d4f 100644
--- a/Tests/GeneratorExpression/check-common.cmake
+++ b/Tests/GeneratorExpression/check-common.cmake
@@ -1,5 +1,5 @@
-macro(check var val)
+function(check var val)
   if(NOT "${${var}}" STREQUAL "${val}")
     message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"")
   endif()
-endmacro()
+endfunction()
diff --git a/Tests/GeneratorExpression/check-part1.cmake b/Tests/GeneratorExpression/check-part1.cmake
index 3207582..60b193f 100644
--- a/Tests/GeneratorExpression/check-part1.cmake
+++ b/Tests/GeneratorExpression/check-part1.cmake
@@ -55,5 +55,5 @@ check(test_semicolon ";")
 check(test_colons_1 ":")
 check(test_colons_2 "::")
 check(test_colons_3 "Qt5::Core")
-check(test_colons_4 "C:\\\\CMake")
+check(test_colons_4 [[C:\CMake]])
 check(test_colons_5 "C:/CMake")
diff --git a/Tests/GeneratorExpression/check-part4.cmake b/Tests/GeneratorExpression/check-part4.cmake
new file mode 100644
index 0000000..9e516d5
--- /dev/null
+++ b/Tests/GeneratorExpression/check-part4.cmake
@@ -0,0 +1,15 @@
+include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
+
+string(REPLACE ${path_prefix} "" test_shell_path ${test_shell_path})
+
+if(WIN32)
+  if(CMAKE_GENERATOR STREQUAL "MSYS Makefiles")
+    check(test_shell_path [[/c/shell/path]])
+  elseif(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
+    check(test_shell_path [[c:/shell/path]])
+  else()
+    check(test_shell_path [[c:\shell\path]])
+  endif()
+else()
+  check(test_shell_path [[/shell/path]])
+endif()
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
index 0215e93..dcee85e 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
@@ -35,6 +35,16 @@ add_library(imported_consumer2 imported_consumer.cpp)
 target_link_libraries(imported_consumer2 imported_consumer)
 target_compile_options(imported_consumer2 PRIVATE -Werror=unused-variable)
 
+# add a target which has a relative system include
+add_library(somelib imported_consumer.cpp)
+target_include_directories(somelib SYSTEM PUBLIC "systemlib_header_only")
+target_compile_options(somelib PRIVATE -Werror=unused-variable)
+
+# add a target which consumes a relative system include
+add_library(otherlib upstream.cpp)
+target_link_libraries(otherlib PUBLIC somelib)
+target_compile_options(somelib PRIVATE -Werror=unused-variable)
+
 macro(do_try_compile error_option)
   set(TC_ARGS
     IFACE_TRY_COMPILE_${error_option}
diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
index 8e2bd0a..5b99ea7 100644
--- a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
@@ -5,7 +5,7 @@ project(TargetIncludeDirectories)
 
 macro(create_header _name)
   file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_name}")
-  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" "//${_name}.h\n")
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" "/* ${_name}.h */\n")
 endmacro()
 
 create_header(bar)
@@ -88,7 +88,7 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/bad/common.h" "#error Should not be incl
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/good")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/good/common.h" "#include \"othergood.h\"\n")
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/othergood")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/othergood/othergood.h" "// No error\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/othergood/othergood.h" "/* No error */\n")
 
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp" "// No content \n")
 add_library(libothergood "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp")
@@ -149,7 +149,7 @@ target_include_directories(lib5
 )
 
 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat/prefix_foo_bar_bat.h" "// prefix_foo_bar_bat.h\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat/prefix_foo_bar_bat.h" "/* prefix_foo_bar_bat.h */\n")
 
 target_include_directories(TargetIncludeDirectories PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/prefix_$<JOIN:foo;bar;bat,/prefix_>")
 
diff --git a/Tests/Java/CMakeLists.txt b/Tests/Java/CMakeLists.txt
index 6a69a24..e1bcf3c 100644
--- a/Tests/Java/CMakeLists.txt
+++ b/Tests/Java/CMakeLists.txt
@@ -7,3 +7,7 @@ find_package(Java COMPONENTS Development)
 include (UseJava)
 
 add_jar(hello A.java HelloWorld.java)
+
+# use listing file to specify sources
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/java_fileslist "A.java\nHelloWorld.java\n")
+add_jar(hello2 @${CMAKE_CURRENT_BINARY_DIR}/java_fileslist)
diff --git a/Tests/JavaJavah/B.cpp b/Tests/JavaJavah/B.cpp
new file mode 100644
index 0000000..2666757
--- /dev/null
+++ b/Tests/JavaJavah/B.cpp
@@ -0,0 +1,10 @@
+
+#include <jni.h>
+#include <stdio.h>
+
+#include "B.h"
+
+JNIEXPORT void JNICALL Java_B_printName(JNIEnv *, jobject)
+{
+  printf("B\n");
+}
diff --git a/Tests/JavaJavah/B.java b/Tests/JavaJavah/B.java
new file mode 100644
index 0000000..d731f39
--- /dev/null
+++ b/Tests/JavaJavah/B.java
@@ -0,0 +1,19 @@
+class B
+{
+  public B()
+    {
+    }
+
+    public native void printName();
+
+    static {
+        try {
+
+            System.loadLibrary("B");
+
+        } catch (UnsatisfiedLinkError e) {
+            System.err.println("Native code library failed to load.\n" + e);
+            System.exit(1);
+        }
+    }
+}
diff --git a/Tests/JavaJavah/CMakeLists.txt b/Tests/JavaJavah/CMakeLists.txt
new file mode 100644
index 0000000..83b0ad0
--- /dev/null
+++ b/Tests/JavaJavah/CMakeLists.txt
@@ -0,0 +1,20 @@
+project(helloJavah Java CXX)
+
+cmake_minimum_required (VERSION 2.6)
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+find_package(Java COMPONENTS Development)
+include (UseJava)
+
+# JNI support
+find_package(JNI)
+
+add_jar(hello3 B.java HelloWorld2.java)
+create_javah(TARGET B_javah CLASSES B CLASSPATH hello3)
+
+add_library(B SHARED B.cpp)
+add_dependencies(B B_javah)
+
+target_include_directories(B PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                     ${JAVA_INCLUDE_PATH}
+                                     ${JAVA_INCLUDE_PATH2})
diff --git a/Tests/JavaJavah/HelloWorld2.java b/Tests/JavaJavah/HelloWorld2.java
new file mode 100644
index 0000000..faf7277
--- /dev/null
+++ b/Tests/JavaJavah/HelloWorld2.java
@@ -0,0 +1,10 @@
+class HelloWorld2
+{
+    public static void main(String args[])
+    {
+        B b;
+        b = new B();
+        b.printName();
+        System.out.println("Hello World!");
+    }
+}
diff --git a/Tests/MSManifest/CMakeLists.txt b/Tests/MSManifest/CMakeLists.txt
new file mode 100644
index 0000000..300cfa6
--- /dev/null
+++ b/Tests/MSManifest/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.3)
+project(MSManifest C)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+add_subdirectory(Subdir)
diff --git a/Tests/MSManifest/Subdir/CMakeLists.txt b/Tests/MSManifest/Subdir/CMakeLists.txt
new file mode 100644
index 0000000..a47cf00
--- /dev/null
+++ b/Tests/MSManifest/Subdir/CMakeLists.txt
@@ -0,0 +1,9 @@
+configure_file(test.manifest.in test.manifest)
+add_executable(MSManifest main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+  add_custom_command(TARGET MSManifest POST_BUILD VERBATIM
+    COMMAND ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
+            -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
+    )
+endif()
diff --git a/Tests/MSManifest/Subdir/check.cmake b/Tests/MSManifest/Subdir/check.cmake
new file mode 100644
index 0000000..b7b6841
--- /dev/null
+++ b/Tests/MSManifest/Subdir/check.cmake
@@ -0,0 +1,6 @@
+file(STRINGS "${exe}" content REGEX "name=\"Kitware.CMake.MSManifestTest\"")
+if(content)
+  message(STATUS "Expected manifest content found:\n ${content}")
+else()
+  message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
diff --git a/Tests/MSManifest/Subdir/main.c b/Tests/MSManifest/Subdir/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/Tests/MSManifest/Subdir/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/MSManifest/Subdir/test.manifest.in b/Tests/MSManifest/Subdir/test.manifest.in
new file mode 100644
index 0000000..540961a
--- /dev/null
+++ b/Tests/MSManifest/Subdir/test.manifest.in
@@ -0,0 +1,4 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <assemblyIdentity type="win32" version="1.0.0.0"
+                    name="Kitware.CMake.MSManifestTest"/>
+</assembly>
diff --git a/Tests/Module/GenerateExportHeader/CMakeLists.txt b/Tests/Module/GenerateExportHeader/CMakeLists.txt
index b52c44d..8cd25a4 100644
--- a/Tests/Module/GenerateExportHeader/CMakeLists.txt
+++ b/Tests/Module/GenerateExportHeader/CMakeLists.txt
@@ -106,10 +106,10 @@ endif()
 add_executable(GenerateExportHeader exportheader_test.cpp)
 
 target_link_libraries(GenerateExportHeader ${link_libraries})
-if (WIN32)
+if (WIN32 OR CYGWIN)
   if(MSVC AND COMPILER_HAS_DEPRECATED)
     set(_platform Win32)
-  elseif(MINGW AND COMPILER_HAS_DEPRECATED)
+  elseif((MINGW OR CYGWIN) AND COMPILER_HAS_DEPRECATED)
     set(_platform MinGW)
   else()
     set(_platform WinEmpty)
diff --git a/Tests/OutOfBinary/CMakeLists.txt b/Tests/OutOfBinary/CMakeLists.txt
index e327541..f50536e 100644
--- a/Tests/OutOfBinary/CMakeLists.txt
+++ b/Tests/OutOfBinary/CMakeLists.txt
@@ -1,2 +1,4 @@
 add_library(outlib outlib.c)
 
+add_executable(outexe outexe.c)
+target_link_libraries(outexe subdir)
diff --git a/Tests/OutOfBinary/outexe.c b/Tests/OutOfBinary/outexe.c
new file mode 100644
index 0000000..6f14043
--- /dev/null
+++ b/Tests/OutOfBinary/outexe.c
@@ -0,0 +1,2 @@
+extern int subdir(void);
+int main(void) { return subdir(); }
diff --git a/Tests/OutOfSource/SubDir/CMakeLists.txt b/Tests/OutOfSource/SubDir/CMakeLists.txt
index c5df36e..e18dbb9 100644
--- a/Tests/OutOfSource/SubDir/CMakeLists.txt
+++ b/Tests/OutOfSource/SubDir/CMakeLists.txt
@@ -6,3 +6,5 @@ add_subdirectory(${OutOfSource_SOURCE_DIR}/../OutOfBinary
 
 # subdir to a sibling dir
 add_subdirectory(${OutOfSource_SOURCE_DIR}/${KEN}OutOfSourceSubdir OutOfSourceSubdir )
+
+add_library(subdir subdir.c)
diff --git a/Tests/OutOfSource/SubDir/subdir.c b/Tests/OutOfSource/SubDir/subdir.c
new file mode 100644
index 0000000..0d0d827
--- /dev/null
+++ b/Tests/OutOfSource/SubDir/subdir.c
@@ -0,0 +1 @@
+int subdir(void) { return 0; }
diff --git a/Tests/Plugin/CMakeLists.txt b/Tests/Plugin/CMakeLists.txt
index ecdece8..2b7bac1 100644
--- a/Tests/Plugin/CMakeLists.txt
+++ b/Tests/Plugin/CMakeLists.txt
@@ -52,13 +52,8 @@ target_link_libraries(example_mod_1 example_exe)
 
 if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
     "${CMAKE_C_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG")
-  # Add a second plugin that should not have any soname.
-  add_library(example_mod_2 MODULE src/example_mod_1.c)
-  target_link_libraries(example_mod_2 example_exe)
-  set_property(TARGET example_mod_2 PROPERTY NO_SONAME 1)
-
   # Verify that targets export with proper IMPORTED SONAME properties.
-  export(TARGETS example_mod_1 example_mod_2 NAMESPACE exp_
+  export(TARGETS example_mod_1 NAMESPACE exp_
     FILE ${CMAKE_CURRENT_BINARY_DIR}/mods.cmake)
 
   include(ExternalProject)
@@ -68,7 +63,7 @@ if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
     DOWNLOAD_COMMAND ""
     INSTALL_COMMAND ""
   )
-  add_dependencies(PluginTest example_mod_1 example_mod_2)
+  add_dependencies(PluginTest example_mod_1)
 endif()
 
 # TODO:
diff --git a/Tests/Plugin/PluginTest/CMakeLists.txt b/Tests/Plugin/PluginTest/CMakeLists.txt
index 79ef8a9..5626dbc 100644
--- a/Tests/Plugin/PluginTest/CMakeLists.txt
+++ b/Tests/Plugin/PluginTest/CMakeLists.txt
@@ -6,17 +6,11 @@ include(${CMAKE_CURRENT_BINARY_DIR}/../mods.cmake)
 get_property(configs TARGET exp_example_mod_1 PROPERTY IMPORTED_CONFIGURATIONS)
 foreach(c ${configs})
   string(TOUPPER "${c}" CONFIG)
-  get_property(soname1 TARGET exp_example_mod_1 PROPERTY IMPORTED_SONAME_${CONFIG})
-  get_property(soname2 TARGET exp_example_mod_2 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
-  if(soname1)
-    message(STATUS "exp_example_mod_1 has IMPORTED_SONAME_${CONFIG} as expected: ${soname1}")
+  get_property(soname TARGET exp_example_mod_1 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
+  if(soname)
+    message(STATUS "exp_example_mod_1 has IMPORTED_NO_SONAME_${CONFIG} as expected: ${soname}")
   else()
-    message(SEND_ERROR "exp_example_mod_1 does not have IMPORTED_SONAME_${CONFIG} but should")
-  endif()
-  if(soname2)
-    message(STATUS "exp_example_mod_2 has IMPORTED_NO_SONAME_${CONFIG} as expected: ${soname2}")
-  else()
-    message(SEND_ERROR "exp_example_mod_2 does not have IMPORTED_NO_SONAME_${CONFIG} but should")
+    message(SEND_ERROR "exp_example_mod_1 does not have IMPORTED_NO_SONAME_${CONFIG} but should")
   endif()
 endforeach()
 
@@ -26,8 +20,7 @@ if("${CMAKE_EXECUTABLE_FORMAT}" MATCHES "ELF")
   if(READELF_EXE)
     add_custom_target(check_mod_soname ALL COMMAND
       ${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
-                        -Dmod1=$<TARGET_FILE:exp_example_mod_1>
-                        -Dmod2=$<TARGET_FILE:exp_example_mod_2>
+                       -Dmod=$<TARGET_FILE:exp_example_mod_1>
       -P ${CMAKE_CURRENT_SOURCE_DIR}/../check_mod_soname.cmake
       )
   endif()
diff --git a/Tests/Plugin/check_mod_soname.cmake b/Tests/Plugin/check_mod_soname.cmake
index 3737b45..eeededa 100644
--- a/Tests/Plugin/check_mod_soname.cmake
+++ b/Tests/Plugin/check_mod_soname.cmake
@@ -1,14 +1,7 @@
-execute_process(COMMAND ${readelf} -d ${mod1} OUTPUT_FILE ${mod1}.readelf.txt)
-execute_process(COMMAND ${readelf} -d ${mod2} OUTPUT_FILE ${mod2}.readelf.txt)
-file(STRINGS ${mod1}.readelf.txt soname1 REGEX "\\(SONAME\\)")
-file(STRINGS ${mod2}.readelf.txt soname2 REGEX "\\(SONAME\\)")
-if(soname1)
-  message(STATUS "${mod1} has soname as expected: ${soname1}")
+execute_process(COMMAND ${readelf} -d ${mod} OUTPUT_FILE ${mod}.readelf.txt)
+file(STRINGS ${mod}.readelf.txt soname REGEX "SONAME")
+if(soname)
+  message(FATAL_ERROR "${mod} has soname but should not:\n  ${soname}")
 else()
-  message(FATAL_ERROR "${mod1} has no soname but should:\n  ${soname1}")
-endif()
-if(soname2)
-  message(FATAL_ERROR "${mod2} has soname but should not:\n  ${soname2}")
-else()
-  message(STATUS "${mod2} has no soname as expected")
+  message(STATUS "${mod} has no soname as expected")
 endif()
diff --git a/Tests/Plugin/src/example_exe.cxx b/Tests/Plugin/src/example_exe.cxx
index 309302e..12d9204 100644
--- a/Tests/Plugin/src/example_exe.cxx
+++ b/Tests/Plugin/src/example_exe.cxx
@@ -3,15 +3,15 @@
 #include <example_exe.h>
 
 #include <kwsys/DynamicLoader.hxx>
-#include <kwsys/ios/iostream>
-#include <kwsys/stl/string>
+#include <iostream>
+#include <string>
 
 #include <stdio.h>
 
 // Implement the ABI used by plugins.
 extern "C" int example_exe_function()
 {
-  kwsys_ios::cout << "hello" << kwsys_ios::endl;
+  std::cout << "hello" << std::endl;
   return 123;
 }
 
@@ -23,7 +23,7 @@ extern "C" int example_exe_function()
 
 int main()
 {
-  kwsys_stl::string libName = EXAMPLE_EXE_PLUGIN_DIR CONFIG_DIR "/";
+  std::string libName = EXAMPLE_EXE_PLUGIN_DIR CONFIG_DIR "/";
   libName += kwsys::DynamicLoader::LibPrefix();
   libName += "example_mod_1";
   libName += kwsys::DynamicLoader::LibExtension();
@@ -31,17 +31,17 @@ int main()
     kwsys::DynamicLoader::OpenLibrary(libName.c_str());
   if(!handle)
     {
-    kwsys_ios::cerr << "Could not open plugin \""
-                    << libName << "\"!" << kwsys_ios::endl;
+    std::cerr << "Could not open plugin \""
+              << libName.c_str() << "\"!" << std::endl;
     return 1;
     }
   kwsys::DynamicLoader::SymbolPointer sym =
     kwsys::DynamicLoader::GetSymbolAddress(handle, "example_mod_1_function");
   if(!sym)
     {
-    kwsys_ios::cerr
+    std::cerr
       << "Could not get plugin symbol \"example_mod_1_function\"!"
-      << kwsys_ios::endl;
+      << std::endl;
     return 1;
     }
 #ifdef __WATCOMC__
@@ -51,8 +51,8 @@ int main()
 #endif
   if(f(456) != (123+456))
     {
-    kwsys_ios::cerr << "Incorrect return value from plugin!"
-                    << kwsys_ios::endl;
+    std::cerr << "Incorrect return value from plugin!"
+              << std::endl;
     return 1;
     }
   kwsys::DynamicLoader::CloseLibrary(handle);
diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt
index 60b44fd..d5aca55 100644
--- a/Tests/QtAutogen/CMakeLists.txt
+++ b/Tests/QtAutogen/CMakeLists.txt
@@ -34,8 +34,8 @@ else()
   include_directories(${Qt5Widgets_INCLUDE_DIRS})
   set(QT_LIBRARIES Qt5::Widgets)
 
-  if(Qt5_POSITION_INDEPENDENT_CODE)
-    set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+  if(Qt5_POSITION_INDEPENDENT_CODE AND CMAKE_CXX_COMPILE_OPTIONS_PIC)
+    add_definitions(${CMAKE_CXX_COMPILE_OPTIONS_PIC})
   endif()
 
   macro(qtx_wrap_cpp)
@@ -101,7 +101,14 @@ add_executable(QtAutogen main.cpp calwidget.cpp second_widget.cpp foo.cpp blub.c
 )
 set_property(TARGET QtAutogen APPEND PROPERTY AUTOGEN_TARGET_DEPENDS generate_moc_input "${CMAKE_CURRENT_BINARY_DIR}/myotherinterface.h")
 
-set_target_properties(QtAutogen codeeditorLib privateSlot PROPERTIES AUTOMOC TRUE)
+add_executable(targetObjectsTest targetObjectsTest.cpp $<TARGET_OBJECTS:privateSlot>)
+target_link_libraries(targetObjectsTest ${QT_LIBRARIES})
+
+set_target_properties(
+  QtAutogen codeeditorLib privateSlot targetObjectsTest
+  PROPERTIES
+  AUTOMOC TRUE
+)
 
 include(GenerateExportHeader)
 # The order is relevant here. B depends on A, and B headers depend on A
@@ -167,3 +174,26 @@ file(TIMESTAMP "${qrc_file1}" file1_step1 "${timeformat}")
 if (NOT file1_step1 GREATER file1_before)
   message(SEND_ERROR "file1 (${qrc_file1}) should have changed in the first step!")
 endif()
+
+#-----------------------------------------------------------------------------
+try_compile(MOC_RERUN
+  "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun"
+  "${CMAKE_CURRENT_SOURCE_DIR}/automoc_rerun"
+  automoc_rerun
+  CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+              "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
+  OUTPUT_VARIABLE output
+)
+if (NOT MOC_RERUN)
+  message(SEND_ERROR "Initial build of automoc_rerun failed. Output: ${output}")
+endif()
+
+configure_file(automoc_rerun/test1.h.in2 automoc_rerun/test1.h COPYONLY)
+
+execute_process(COMMAND "${CMAKE_COMMAND}" --build .
+  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun"
+  RESULT_VARIABLE automoc_rerun_result
+  )
+if (automoc_rerun_result)
+  message(SEND_ERROR "Second build of automoc_rerun failed.")
+endif()
diff --git a/Tests/QtAutogen/automoc_rerun/CMakeLists.txt b/Tests/QtAutogen/automoc_rerun/CMakeLists.txt
new file mode 100644
index 0000000..17bc332
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/CMakeLists.txt
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 3.1)
+project(automoc_rerun CXX)
+
+if (QT_TEST_VERSION STREQUAL 4)
+  find_package(Qt4 REQUIRED)
+  set(QT_CORE_TARGET Qt4::QtCore)
+else()
+  if (NOT QT_TEST_VERSION STREQUAL 5)
+    message(SEND_ERROR "Invalid Qt version specified.")
+  endif()
+
+  find_package(Qt5Core REQUIRED)
+  set(QT_CORE_TARGET Qt5::Core)
+endif()
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+configure_file(test1.h.in1 test1.h COPYONLY)
+
+add_executable(test1
+  ${CMAKE_CURRENT_BINARY_DIR}/test1.h
+  test1.cpp
+  res1.qrc
+  )
+target_include_directories(test1 PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_link_libraries(test1 ${QT_CORE_TARGET})
diff --git a/Tests/QtAutogen/automoc_rerun/input.txt b/Tests/QtAutogen/automoc_rerun/input.txt
new file mode 100644
index 0000000..da62762
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/input.txt
@@ -0,0 +1 @@
+Res1 input.
diff --git a/Tests/QtAutogen/automoc_rerun/res1.qrc b/Tests/QtAutogen/automoc_rerun/res1.qrc
new file mode 100644
index 0000000..fb804b5
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/res1.qrc
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/">
+        <file>input.txt</file>
+    </qresource>
+</RCC>
diff --git a/Tests/QtAutogen/automoc_rerun/test1.cpp b/Tests/QtAutogen/automoc_rerun/test1.cpp
new file mode 100644
index 0000000..4316a91
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/test1.cpp
@@ -0,0 +1,5 @@
+#include "test1.h"
+int main()
+{
+  return 0;
+}
diff --git a/Tests/QtAutogen/automoc_rerun/test1.h.in1 b/Tests/QtAutogen/automoc_rerun/test1.h.in1
new file mode 100644
index 0000000..fee2c09
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/test1.h.in1
@@ -0,0 +1,8 @@
+#include <QObject>
+class test1 : public QObject
+{
+  Q_OBJECT
+ public slots:
+   void onTst1() {}
+   void onTst2() {}
+};
diff --git a/Tests/QtAutogen/automoc_rerun/test1.h.in2 b/Tests/QtAutogen/automoc_rerun/test1.h.in2
new file mode 100644
index 0000000..6531d10
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/test1.h.in2
@@ -0,0 +1,7 @@
+#include <QObject>
+class test1 : public QObject
+{
+  Q_OBJECT
+ public slots:
+   void onTst1() {}
+};
diff --git a/Tests/QtAutogen/targetObjectsTest.cpp b/Tests/QtAutogen/targetObjectsTest.cpp
new file mode 100644
index 0000000..766b775
--- /dev/null
+++ b/Tests/QtAutogen/targetObjectsTest.cpp
@@ -0,0 +1,5 @@
+
+int main()
+{
+  return 0;
+}
diff --git a/Tests/RegexEscapeString.cmake b/Tests/RegexEscapeString.cmake
deleted file mode 100644
index 92aed17..0000000
--- a/Tests/RegexEscapeString.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-macro(REGEX_ESCAPE_STRING _OUT _IN)
-    # Escape special regex metacharacters with a backslash
-    string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" ${_OUT} "${_IN}")
-endmacro()
diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
new file mode 100644
index 0000000..3b2b2c5
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
@@ -0,0 +1,7 @@
+project(autoexport)
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${autoexport_BINARY_DIR}/bin)
+add_subdirectory(sub)
+add_library(autoexport SHARED hello.cxx world.cxx foo.c)
+add_executable(say say.cxx)
+target_link_libraries(say autoexport autoexport2)
diff --git a/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
new file mode 100644
index 0000000..d483c2c
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
@@ -0,0 +1 @@
+^.*$
diff --git a/Tests/RunCMake/AutoExportDll/CMakeLists.txt b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
new file mode 100644
index 0000000..18dfd26
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
new file mode 100644
index 0000000..3784a6a
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
@@ -0,0 +1,26 @@
+include(RunCMake)
+set(RunCMake_TEST_NO_CLEAN TRUE)
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/AutoExport-build")
+# start by cleaning up because we don't clean up along the way
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+# configure the AutoExport test
+run_cmake(AutoExport)
+unset(RunCMake_TEST_OPTIONS)
+# don't run this test on VS 6 as it is not supported
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 6|Watcom WMake|Borland Makefiles")
+  return()
+endif()
+# we build debug so the say.exe will be found in Debug/say.exe for
+# Visual Studio generators
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode")
+  set(INTDIR "Debug/")
+endif()
+# build AutoExport
+run_cmake_command(AutoExportBuild ${CMAKE_COMMAND} --build
+  ${RunCMake_TEST_BINARY_DIR} --config Debug --clean-first)
+# run the executable that uses symbols from the dll
+if(WIN32)
+  set(EXE_EXT ".exe")
+endif()
+run_cmake_command(AutoExportRun
+  ${RunCMake_BINARY_DIR}/AutoExport-build/bin/${INTDIR}say${EXE_EXT})
diff --git a/Tests/RunCMake/AutoExportDll/foo.c b/Tests/RunCMake/AutoExportDll/foo.c
new file mode 100644
index 0000000..4b1318b
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/foo.c
@@ -0,0 +1,15 @@
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+int WINAPI foo()
+{
+  return 10;
+}
+
+int bar()
+{
+  return 5;
+}
diff --git a/Tests/RunCMake/AutoExportDll/hello.cxx b/Tests/RunCMake/AutoExportDll/hello.cxx
new file mode 100644
index 0000000..3933fc1
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.cxx
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "hello.h"
+int Hello::Data = 0;
+void Hello::real()
+{
+  return;
+}
+void hello()
+{
+  printf("hello");
+}
+void Hello::operator delete[](void*) {};
+void Hello::operator delete(void*) {};
diff --git a/Tests/RunCMake/AutoExportDll/hello.h b/Tests/RunCMake/AutoExportDll/hello.h
new file mode 100644
index 0000000..3749b97
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.h
@@ -0,0 +1,18 @@
+#ifndef _MSC_VER
+#define winexport
+#else
+#ifdef autoexport_EXPORTS
+#define winexport
+#else
+#define winexport __declspec(dllimport)
+#endif
+#endif
+
+class Hello
+{
+public:
+  static winexport int Data;
+  void real();
+  static void operator delete[](void*);
+  static void operator delete(void*);
+};
diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx
new file mode 100644
index 0000000..655b3c2
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/say.cxx
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include "hello.h"
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+extern "C"
+{
+// test __cdecl stuff
+  int WINAPI foo();
+// test regular C
+  int bar();
+}
+
+// test c++ functions
+// forward declare hello and world
+void hello();
+void world();
+
+int main()
+{
+  // test static data (needs declspec to work)
+  Hello::Data = 120;
+  Hello h;
+  h.real();
+  hello();
+  printf(" ");
+  world();
+  printf("\n");
+  foo();
+  printf("\n");
+  bar();
+  printf("\n");
+  return 0;
+}
diff --git a/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt b/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt
new file mode 100644
index 0000000..8b70e7d
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_library(autoexport2 SHARED sub.cxx)
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+  # Try msvc "big" object format.
+  target_compile_options(autoexport2 PRIVATE /bigobj)
+endif()
diff --git a/Tests/RunCMake/AutoExportDll/sub/sub.cxx b/Tests/RunCMake/AutoExportDll/sub/sub.cxx
new file mode 100644
index 0000000..9766b41
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/sub/sub.cxx
@@ -0,0 +1,4 @@
+int sub()
+{
+  return 10;
+}
diff --git a/Tests/RunCMake/AutoExportDll/world.cxx b/Tests/RunCMake/AutoExportDll/world.cxx
new file mode 100644
index 0000000..3a54df3
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/world.cxx
@@ -0,0 +1,6 @@
+#include "stdio.h"
+
+void world()
+{
+  printf("world");
+}
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake
new file mode 100644
index 0000000..ef33012
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake
@@ -0,0 +1,19 @@
+enable_language(C)
+
+add_executable(main main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+  set(EXTRA_CHECK [[
+file(STRINGS "$<TARGET_FILE:main>" content REGEX "name=\"Kitware.CMake.C-Exe-Manifest-step[0-9]\"")
+if(NOT "${content}" MATCHES "name=\"Kitware.CMake.C-Exe-Manifest-step${check_step}\"")
+  set(RunCMake_TEST_FAILED "Binary has no manifest with name=\"Kitware.CMake.C-Exe-Manifest-step${check_step}\":\n ${content}")
+endif()
+]])
+endif()
+
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+  \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/test.manifest\"
+  )
+${EXTRA_CHECK}
+")
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake
new file mode 100644
index 0000000..c0b939d
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake
@@ -0,0 +1,6 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/test.manifest" [[
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <assemblyIdentity type="win32" version="1.0.0.0"
+                    name="Kitware.CMake.C-Exe-Manifest-step1"/>
+</assembly>
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake
new file mode 100644
index 0000000..a75bf21
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake
@@ -0,0 +1,6 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/test.manifest" [[
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <assemblyIdentity type="win32" version="1.0.0.0"
+                    name="Kitware.CMake.C-Exe-Manifest-step2"/>
+</assembly>
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.cmake b/Tests/RunCMake/BuildDepends/C-Exe.cmake
new file mode 100644
index 0000000..5057ca9
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c)
+
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+  \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\"
+  )
+set(check_exes
+  \"$<TARGET_FILE:main>\"
+  )
+")
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake b/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake
new file mode 100644
index 0000000..08e2949
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c" [[
+int main(void) { return 1; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake b/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake
new file mode 100644
index 0000000..ee4530c
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c" [[
+int main(void) { return 2; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/CMakeLists.txt b/Tests/RunCMake/BuildDepends/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
new file mode 100644
index 0000000..a578408
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -0,0 +1,40 @@
+include(RunCMake)
+
+if(RunCMake_GENERATOR STREQUAL "Borland Makefiles")
+  set(fs_delay 3)
+else()
+  set(fs_delay 1.125)
+endif()
+
+function(run_BuildDepends CASE)
+  # Use a single build tree for a few tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  include(${RunCMake_SOURCE_DIR}/${CASE}.step1.cmake OPTIONAL)
+  run_cmake(${CASE})
+  set(RunCMake-check-file check.cmake)
+  set(check_step 1)
+  run_cmake_command(${CASE}-build1 ${CMAKE_COMMAND} --build . --config Debug)
+  if(run_BuildDepends_skip_step_2)
+    return()
+  endif()
+  execute_process(COMMAND ${CMAKE_COMMAND} -E sleep ${fs_delay}) # handle 1s resolution
+  include(${RunCMake_SOURCE_DIR}/${CASE}.step2.cmake OPTIONAL)
+  set(check_step 2)
+  run_cmake_command(${CASE}-build2 ${CMAKE_COMMAND} --build . --config Debug)
+endfunction()
+
+run_BuildDepends(C-Exe)
+if(NOT RunCMake_GENERATOR MATCHES "Visual Studio [67]|Xcode")
+  if(RunCMake_GENERATOR MATCHES "Visual Studio 10")
+    # VS 10 forgets to re-link when a manifest changes
+    set(run_BuildDepends_skip_step_2 1)
+  endif()
+  run_BuildDepends(C-Exe-Manifest)
+  unset(run_BuildDepends_skip_step_2)
+endif()
diff --git a/Tests/RunCMake/BuildDepends/check.cmake b/Tests/RunCMake/BuildDepends/check.cmake
new file mode 100644
index 0000000..26a9eb6
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/check.cmake
@@ -0,0 +1,37 @@
+if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
+  include(${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
+  if(RunCMake_TEST_FAILED)
+    return()
+  endif()
+  foreach(exe IN LISTS check_exes)
+    execute_process(COMMAND ${exe} RESULT_VARIABLE res)
+    if(NOT res EQUAL ${check_step})
+      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${exe}' returned '${res}' but expected '${check_step}'
+")
+    endif()
+  endforeach()
+  foreach(p IN LISTS check_pairs)
+    if("${p}" MATCHES "^(.*)\\|(.*)$")
+      set(lhs "${CMAKE_MATCH_1}")
+      set(rhs "${CMAKE_MATCH_2}")
+      if(NOT EXISTS "${lhs}")
+        set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${lhs}' missing
+")
+      elseif(NOT EXISTS "${rhs}")
+        set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${rhs}' missing
+")
+      elseif(NOT "${lhs}" IS_NEWER_THAN "${rhs}")
+        set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${lhs}' is not newer than '${rhs}'
+")
+      endif()
+    endif()
+  endforeach()
+else()
+  set(RunCMake_TEST_FAILED "
+ '${RunCMake_TEST_BINARY_DIR}/check-debug.cmake' missing
+")
+endif()
diff --git a/Tests/RunCMake/BuildDepends/main.c b/Tests/RunCMake/BuildDepends/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
index 03faef9..1e4b47d 100644
--- a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
@@ -21,13 +21,13 @@ CMake Warning \(dev\) in CMakeLists.txt:
 
     /usr/include/VAL_INCLUDE;/usr/include/normal
 
-  Evaluated link directory
+  Evaluated link directories
 
-    /usr/lib/\${VAR_LINK_DIRS}
+    /usr/lib/\${VAR_LINK_DIRS};/usr/lib/normal
 
   as
 
-    /usr/lib/VAL_LINK_DIRS
+    /usr/lib/VAL_LINK_DIRS;/usr/lib/normal
 
   Evaluated link library
 
diff --git a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake
index fc58ea5..6331717 100644
--- a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake
@@ -11,3 +11,4 @@ run_cmake(CMP0026-LOCATION-CONFIG-OLD)
 run_cmake(CMP0026-LOCATION-CONFIG-WARN)
 run_cmake(ObjlibNotDefined)
 run_cmake(LOCATION-and-TARGET_OBJECTS)
+run_cmake(clear-cached-information)
diff --git a/Tests/RunCMake/CMP0026/clear-cached-information-dir/CMakeLists.txt b/Tests/RunCMake/CMP0026/clear-cached-information-dir/CMakeLists.txt
new file mode 100644
index 0000000..c51e883
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/clear-cached-information-dir/CMakeLists.txt
@@ -0,0 +1,2 @@
+
+add_executable(Hello ${CMAKE_CURRENT_BINARY_DIR}/main.c)
diff --git a/Tests/RunCMake/CMP0026/clear-cached-information.cmake b/Tests/RunCMake/CMP0026/clear-cached-information.cmake
new file mode 100644
index 0000000..dd2dd72
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/clear-cached-information.cmake
@@ -0,0 +1,14 @@
+
+enable_language(C)
+
+cmake_policy(SET CMP0026 OLD)
+
+add_subdirectory(clear-cached-information-dir)
+
+# Critical: this needs to happen in root CMakeLists.txt and not inside
+# the subdir.
+get_target_property(mypath Hello LOCATION)
+# Now we create the file later, so you can see, ultimately no error should
+# happen e.g. during generate phase:
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/clear-cached-information-dir/main.c)
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/clear-cached-information-dir/main.c PROPERTIES GENERATED TRUE)
diff --git a/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt
index 3d875ae..3cfa5d2 100644
--- a/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt
@@ -9,3 +9,15 @@ CMake Warning \(dev\) at CMP0054-WARN.cmake:3 \(if\):
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0054-WARN.cmake:5 \(elseif\):
+  Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+  keywords when unquoted.  Run "cmake --help-policy CMP0054" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
+
+  Quoted variables like "FOO" will no longer be dereferenced when the policy
+  is set to NEW.  Since the policy is not set the OLD behavior will be used.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake b/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake
index 37855fc..a608929 100644
--- a/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake
+++ b/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake
@@ -2,4 +2,6 @@ set(FOO "BAR")
 
 if(NOT "FOO" STREQUAL "BAR")
   message(FATAL_ERROR "The given literals should match")
+elseif("FOO" STREQUAL "BING")
+  message(FATAL_ERROR "The given literals should not match")
 endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt
index b1ebd49..5a8c263 100644
--- a/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt
@@ -10,3 +10,16 @@ CMake Warning \(dev\) at CMP0054-keywords-WARN.cmake:1 \(if\):
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0054-keywords-WARN.cmake:3 \(elseif\):
+  Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+  keywords when unquoted.  Run "cmake --help-policy CMP0054" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
+
+  Quoted keywords like "DEFINED" will no longer be interpreted as keywords
+  when the policy is set to NEW.  Since the policy is not set the OLD
+  behavior will be used.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake
index ee0a623..118ab3d 100644
--- a/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake
@@ -1,3 +1,5 @@
 if("NOT" 1)
   message(FATAL_ERROR "[\"NOT\" 1] evaluated true")
+elseif("DEFINED" NotDefined)
+  message(FATAL_ERROR "[\"DEFINED\" NotDefined] evaluated true")
 endif()
diff --git a/Tests/RunCMake/CMP0064/CMP0064-NEW.cmake b/Tests/RunCMake/CMP0064/CMP0064-NEW.cmake
new file mode 100644
index 0000000..cdf50e9
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMP0064-NEW.cmake
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0064 NEW)
+
+if(NOT TEST TestThatDoesNotExist)
+  message(STATUS "if NOT TestThatDoesNotExist is true")
+endif()
diff --git a/Tests/RunCMake/CMP0064/CMP0064-OLD.cmake b/Tests/RunCMake/CMP0064/CMP0064-OLD.cmake
new file mode 100644
index 0000000..bffd3f3
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMP0064-OLD.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0064 OLD)
+
+if(TEST)
+  message(FATAL_ERROR "TEST was not recognized to be undefined")
+else()
+  message(STATUS "TEST was treated as a variable")
+endif()
diff --git a/Tests/RunCMake/CMP0064/CMP0064-WARN-stderr.txt b/Tests/RunCMake/CMP0064/CMP0064-WARN-stderr.txt
new file mode 100644
index 0000000..71f1ab7
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMP0064-WARN-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0064-WARN.cmake:3 \(if\):
+  Policy CMP0064 is not set: Support new TEST if\(\) operator.  Run "cmake
+  --help-policy CMP0064" for policy details.  Use the cmake_policy command to
+  set the policy and suppress this warning.
+
+  TEST will be interpreted as an operator when the policy is set to NEW.
+  Since the policy is not set the OLD behavior will be used.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0064/CMP0064-WARN.cmake b/Tests/RunCMake/CMP0064/CMP0064-WARN.cmake
new file mode 100644
index 0000000..8f26ec6
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMP0064-WARN.cmake
@@ -0,0 +1,7 @@
+
+
+if(TEST)
+  message(FATAL_ERROR "TEST was not recognized to be undefined")
+else()
+  message(STATUS "TEST was treated as a variable")
+endif()
diff --git a/Tests/RunCMake/CMP0064/CMakeLists.txt b/Tests/RunCMake/CMP0064/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0064/RunCMakeTest.cmake b/Tests/RunCMake/CMP0064/RunCMakeTest.cmake
new file mode 100644
index 0000000..26e0a91
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0064-OLD)
+run_cmake(CMP0064-WARN)
+run_cmake(CMP0064-NEW)
diff --git a/Tests/RunCMake/CMP0065/BuildTargetInSubProject.cmake b/Tests/RunCMake/CMP0065/BuildTargetInSubProject.cmake
new file mode 100644
index 0000000..9339e46
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/BuildTargetInSubProject.cmake
@@ -0,0 +1,15 @@
+function(BuildTargetInSubProject P T E)
+  try_compile(RESULTVAR
+    ${CMAKE_CURRENT_BINARY_DIR}/subproject
+    ${CMAKE_CURRENT_SOURCE_DIR}/subproject
+    ${P} ${T} OUTPUT_VARIABLE O)
+  if(E AND RESULTVAR)
+    message(STATUS "${P} target ${T} succeeded as expected")
+  elseif(E AND NOT RESULTVAR)
+    message(FATAL_ERROR "${P} target ${T} failed but should have succeeded.  Output:${O}")
+  elseif(NOT E AND NOT RESULTVAR)
+    message(STATUS "${P} target ${T} failed as expected")
+  elseif(NOT E AND RESULTVAR)
+    message(FATAL_ERROR "${P} target ${T} succeeded but should have failed.  Output:${O}")
+  endif()
+endfunction()
diff --git a/Tests/RunCMake/CMP0065/CMakeLists.txt b/Tests/RunCMake/CMP0065/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0065/NEWBad.cmake b/Tests/RunCMake/CMP0065/NEWBad.cmake
new file mode 100644
index 0000000..79d9adb
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/NEWBad.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+include(BuildTargetInSubProject.cmake)
+
+BuildTargetInSubProject(TestPolicyCMP0065 FooNEWBad FALSE)
diff --git a/Tests/RunCMake/CMP0065/NEWGood.cmake b/Tests/RunCMake/CMP0065/NEWGood.cmake
new file mode 100644
index 0000000..a5b5d04
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/NEWGood.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+include(BuildTargetInSubProject.cmake)
+
+BuildTargetInSubProject(TestPolicyCMP0065 FooNEWGood TRUE)
diff --git a/Tests/RunCMake/CMP0065/OLDBad1.cmake b/Tests/RunCMake/CMP0065/OLDBad1.cmake
new file mode 100644
index 0000000..6d780b4
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/OLDBad1.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+include(BuildTargetInSubProject.cmake)
+
+BuildTargetInSubProject(TestPolicyCMP0065 FooOLDBad1 FALSE)
diff --git a/Tests/RunCMake/CMP0065/OLDBad2.cmake b/Tests/RunCMake/CMP0065/OLDBad2.cmake
new file mode 100644
index 0000000..7196473
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/OLDBad2.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+include(BuildTargetInSubProject.cmake)
+
+BuildTargetInSubProject(TestPolicyCMP0065 FooOLDBad2 FALSE)
diff --git a/Tests/RunCMake/CMP0065/RunCMakeTest.cmake b/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
new file mode 100644
index 0000000..254a4ec
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
@@ -0,0 +1,8 @@
+include(RunCMake)
+
+run_cmake(OLDBad1)
+run_cmake(OLDBad2)
+run_cmake(NEWBad)
+run_cmake(NEWGood)
+run_cmake(WARN-OFF)
+run_cmake(WARN-ON)
diff --git a/Tests/RunCMake/CMP0065/WARN-OFF.cmake b/Tests/RunCMake/CMP0065/WARN-OFF.cmake
new file mode 100644
index 0000000..dbc9562
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/WARN-OFF.cmake
@@ -0,0 +1,3 @@
+
+enable_language(C)
+add_executable(main subproject/main.c)
diff --git a/Tests/RunCMake/CMP0065/WARN-ON-stderr.txt b/Tests/RunCMake/CMP0065/WARN-ON-stderr.txt
new file mode 100644
index 0000000..dda4fe5
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/WARN-ON-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0065 is not set: Do not add flags to export symbols from
+  executables without the ENABLE_EXPORTS target property.  Run "cmake
+  --help-policy CMP0065" for policy details.  Use the cmake_policy command to
+  set the policy and suppress this warning.
+
+  For compatibility with older versions of CMake, additional flags may be
+  added to export symbols on all executables regardless of thier
+  ENABLE_EXPORTS property.
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0065/WARN-ON.cmake b/Tests/RunCMake/CMP0065/WARN-ON.cmake
new file mode 100644
index 0000000..6ed4a41
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/WARN-ON.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_POLICY_WARNING_CMP0065 1)
+enable_language(C)
+add_executable(main subproject/main.c)
diff --git a/Tests/RunCMake/CMP0065/subproject/CMakeLists.txt b/Tests/RunCMake/CMP0065/subproject/CMakeLists.txt
new file mode 100644
index 0000000..bed5960
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/subproject/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.3)
+
+project(TestPolicyCMP0065 C)
+set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS BADFLAGS)
+
+#----------------------------------------------------------------------
+cmake_policy(SET CMP0065 OLD)
+add_executable(FooOLDBad1 main.c)
+
+#----------------------------------------------------------------------
+cmake_policy(SET CMP0065 OLD)
+add_executable(FooOLDBad2 main.c)
+set_target_properties(FooOLDBad2 PROPERTIES ENABLE_EXPORTS ON)
+
+#----------------------------------------------------------------------
+cmake_policy(SET CMP0065 NEW)
+add_executable(FooNEWGood main.c)
+
+#----------------------------------------------------------------------
+cmake_policy(SET CMP0065 NEW)
+add_executable(FooNEWBad main.c)
+set_target_properties(FooNEWBad PROPERTIES ENABLE_EXPORTS ON)
diff --git a/Tests/RunCMake/CMP0065/subproject/main.c b/Tests/RunCMake/CMP0065/subproject/main.c
new file mode 100644
index 0000000..98725db
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/subproject/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+  printf("Hello World\n");
+  return 0;
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 4e7c7b3..1a0019f 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -26,6 +26,43 @@ macro(add_RunCMake_test test)
     )
 endmacro()
 
+function(add_RunCMake_test_group test types)
+  # create directory for common content
+  set(TEST_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/${test}/conf")
+  file(REMOVE_RECURSE "${TEST_CONFIG_DIR}")
+  file(MAKE_DIRECTORY "${TEST_CONFIG_DIR}")
+
+  foreach(type IN LISTS types)
+    # generate prerequirements config file in cmake as ctest doesn't have as
+    # much system information so it is easier to set programs and environment
+    # values here
+    unset(${test}_${type}_FOUND_PREREQUIREMENTS)
+    include("${CMAKE_CURRENT_SOURCE_DIR}/${test}/${type}/Prerequirements.cmake")
+    get_test_prerequirements("${test}_${type}_FOUND_PREREQUIREMENTS"
+        "${TEST_CONFIG_DIR}/${type}_config.cmake")
+
+    # only add the test if prerequirements are met
+    if(${test}_${type}_FOUND_PREREQUIREMENTS)
+      add_test(NAME RunCMake.${test}_${type} COMMAND ${CMAKE_CMAKE_COMMAND}
+        -DTEST_TYPE=${type}
+        -DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}
+        -DRunCMake_GENERATOR=${CMAKE_GENERATOR}
+        -DRunCMake_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}
+        -DRunCMake_GENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET}
+        -DRunCMake_MAKE_PROGRAM=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
+        -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${test}
+        -DRunCMake_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/${type}/${test}
+        -Dconfig_file=${TEST_CONFIG_DIR}/${type}_config.cmake
+        -P "${CMAKE_CURRENT_SOURCE_DIR}/${test}/RunCMakeTest.cmake"
+        )
+    endif()
+  endforeach()
+endfunction()
+
+if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 6.1)
+  set(Swift_ARGS -DXCODE_BELOW_6_1=1)
+endif()
+
 if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 3)
   set(GeneratorToolset_ARGS -DXCODE_BELOW_3=1)
 endif()
@@ -66,6 +103,17 @@ add_RunCMake_test(CMP0055)
 add_RunCMake_test(CMP0057)
 add_RunCMake_test(CMP0059)
 add_RunCMake_test(CMP0060)
+add_RunCMake_test(CMP0064)
+
+# The test for Policy 65 requires the use of the
+# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
+# generators ignore.  The policy will have no effect on those generators.
+if(NOT CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
+  add_RunCMake_test(CMP0065)
+endif()
+if(CMAKE_GENERATOR MATCHES "Make")
+  add_RunCMake_test(Make)
+endif()
 if(CMAKE_GENERATOR STREQUAL "Ninja")
   add_RunCMake_test(Ninja)
 endif()
@@ -83,6 +131,7 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
     )
 endif()
 
+add_RunCMake_test(BuildDepends)
 if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
   add_RunCMake_test(CompilerChange)
 endif()
@@ -95,13 +144,18 @@ add_RunCMake_test(FPHSA)
 add_RunCMake_test(GeneratorExpression)
 add_RunCMake_test(GeneratorPlatform)
 add_RunCMake_test(GeneratorToolset)
+add_RunCMake_test(GNUInstallDirs)
 add_RunCMake_test(TargetPropertyGeneratorExpressions)
 add_RunCMake_test(Languages)
+add_RunCMake_test(LinkStatic)
 add_RunCMake_test(ObjectLibrary)
+add_RunCMake_test(Swift)
 add_RunCMake_test(TargetObjects)
 add_RunCMake_test(TargetSources)
 add_RunCMake_test(find_dependency)
+add_RunCMake_test(CompileDefinitions)
 add_RunCMake_test(CompileFeatures)
+add_RunCMake_test(PolicyScope)
 add_RunCMake_test(WriteCompilerDetectionHeader)
 if(NOT WIN32)
   add_RunCMake_test(PositionIndependentCode)
@@ -138,6 +192,7 @@ add_RunCMake_test(find_file)
 add_RunCMake_test(find_library)
 add_RunCMake_test(find_package)
 add_RunCMake_test(find_path)
+add_RunCMake_test(find_program -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
 add_RunCMake_test(get_filename_component)
 add_RunCMake_test(get_property)
 add_RunCMake_test(if)
@@ -153,6 +208,7 @@ add_RunCMake_test(try_compile)
 add_RunCMake_test(try_run)
 add_RunCMake_test(set)
 add_RunCMake_test(variable_watch)
+add_RunCMake_test(while)
 add_RunCMake_test(CMP0004)
 add_RunCMake_test(TargetPolicies)
 add_RunCMake_test(alias_targets)
@@ -193,6 +249,7 @@ add_RunCMake_test(CommandLine)
 add_RunCMake_test(CommandLineTar)
 
 add_RunCMake_test(install)
+add_RunCMake_test(CPackConfig)
 add_RunCMake_test(CPackInstallProperties)
 add_RunCMake_test(ExternalProject)
 add_RunCMake_test(CTestCommandLine)
@@ -208,10 +265,6 @@ add_RunCMake_test(IfacePaths_INCLUDE_DIRECTORIES TEST_DIR IfacePaths)
 set(IfacePaths_SOURCES_ARGS -DTEST_PROP=SOURCES)
 add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths)
 
-if(RPMBUILD_EXECUTABLE)
-  add_RunCMake_test(CPackRPM)
-endif()
-
 add_RunCMake_test(COMPILE_LANGUAGE-genex)
 
 # Matlab module related tests
@@ -234,4 +287,10 @@ endif()
 if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
   add_executable(pseudo_iwyu pseudo_iwyu.c)
   add_RunCMake_test(IncludeWhatYouUse -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>)
+  add_RunCMake_test(CompilerLauncher)
 endif()
+
+add_RunCMake_test_group(CPack "DEB;RPM;TGZ")
+# add a test to make sure symbols are exported from a shared library
+# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
+add_RunCMake_test(AutoExportDll)
diff --git a/Tests/RunCMake/CPack/CMakeLists.txt b/Tests/RunCMake/CPack/CMakeLists.txt
new file mode 100644
index 0000000..46f1367
--- /dev/null
+++ b/Tests/RunCMake/CPack/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
+
+# include test generator specifics
+if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${GENERATOR_TYPE}/${RunCMake_TEST}-specifics.cmake")
+  include("${GENERATOR_TYPE}/${RunCMake_TEST}-specifics.cmake")
+endif()
+
+set(CPACK_GENERATOR "${GENERATOR_TYPE}")
+include(CPack)
diff --git a/Tests/RunCMake/CPack/COMPONENTS_EMPTY_DIR.cmake b/Tests/RunCMake/CPack/COMPONENTS_EMPTY_DIR.cmake
new file mode 100644
index 0000000..7210e7d
--- /dev/null
+++ b/Tests/RunCMake/CPack/COMPONENTS_EMPTY_DIR.cmake
@@ -0,0 +1,5 @@
+set(CPACK_COMPONENTS_ALL test)
+install(DIRECTORY DESTINATION empty
+        COMPONENT test)
+
+set(CPACK_PACKAGE_NAME "components_empty_dir")
diff --git a/Tests/RunCMake/CPack/CPackTestHelpers.cmake b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
new file mode 100644
index 0000000..aef1086
--- /dev/null
+++ b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
@@ -0,0 +1,41 @@
+cmake_policy(SET CMP0057 NEW)
+
+function(run_cpack_test TEST_NAME types build)
+  if(TEST_TYPE IN_LIST types)
+    set(RunCMake_TEST_NO_CLEAN TRUE)
+    set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${TEST_NAME}-build")
+
+     # TODO this should be executed only once per ctest run (not per generator)
+    file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+    file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+    # execute cmake
+    set(RunCMake_TEST_OPTIONS "-DGENERATOR_TYPE=${TEST_TYPE}")
+    run_cmake(${TEST_NAME})
+
+    # execute optional build step
+    if(build)
+      run_cmake_command(${TEST_NAME}-Build "${CMAKE_COMMAND}" --build "${RunCMake_TEST_BINARY_DIR}")
+    endif()
+
+    # execute cpack
+    execute_process(
+      COMMAND "${CMAKE_CPACK_COMMAND}"
+      WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
+      OUTPUT_FILE "${RunCMake_TEST_BINARY_DIR}/test_output.txt"
+      ERROR_FILE "${RunCMake_TEST_BINARY_DIR}/test_error.txt"
+      )
+
+    # verify result
+    run_cmake_command(
+      ${TEST_TYPE}/${TEST_NAME}
+      "${CMAKE_COMMAND}"
+        -DRunCMake_TEST=${TEST_NAME}
+        -DGENERATOR_TYPE=${TEST_TYPE}
+        "-Dsrc_dir=${RunCMake_SOURCE_DIR}"
+        "-Dbin_dir=${RunCMake_TEST_BINARY_DIR}"
+        "-Dconfig_file=${config_file}"
+        -P "${RunCMake_SOURCE_DIR}/VerifyResult.cmake"
+      )
+  endif()
+endfunction()
diff --git a/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 0000000..5adca68
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "components_empty_dir*.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/${whitespaces_}.*/usr/empty/$")
diff --git a/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-specifics.cmake b/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-specifics.cmake
new file mode 100644
index 0000000..2720fe9
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-specifics.cmake
@@ -0,0 +1,2 @@
+set(CPACK_PACKAGE_CONTACT "someone")
+set(CPACK_DEB_COMPONENT_INSTALL "ON")
diff --git a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-ExpectedFiles.cmake
new file mode 100644
index 0000000..2ff679a
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-ExpectedFiles.cmake
@@ -0,0 +1,9 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "3")
+set(EXPECTED_FILE_1 "deb_extra-*-foo.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/${whitespaces_}.*/usr/foo/${whitespaces_}.*/usr/foo/CMakeLists.txt$")
+set(EXPECTED_FILE_2 "deb_extra-*-bar.deb")
+set(EXPECTED_FILE_CONTENT_2 "^.*/usr/${whitespaces_}.*/usr/bar/${whitespaces_}.*/usr/bar/CMakeLists.txt$")
+set(EXPECTED_FILE_3 "deb_extra-*-bas.deb")
+set(EXPECTED_FILE_CONTENT_3 "^.*/usr/${whitespaces_}.*/usr/bas/${whitespaces_}.*/usr/bas/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
new file mode 100644
index 0000000..5f929ff
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
@@ -0,0 +1,17 @@
+set(foo_preinst "^echo default_preinst$")
+set(foo_preinst_permissions_regex "-rwxr-xr-x .*")
+set(foo_prerm "^echo default_prerm$")
+set(foo_prerm_permissions_regex "-rwxr-xr-x .*")
+verifyDebControl("${FOUND_FILE_1}" "foo" "preinst;prerm")
+
+set(bar_preinst "^echo bar_preinst$")
+set(bar_prerm_permissions_regex "-rwx------ .*")
+set(bar_prerm "^echo bar_prerm$")
+set(bar_prerm_permissions_regex "-rwx------ .*")
+verifyDebControl("${FOUND_FILE_2}" "bar" "preinst;prerm")
+
+set(bas_preinst "^echo default_preinst$")
+set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
+set(bas_prerm "^echo default_prerm$")
+set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
+verifyDebControl("${FOUND_FILE_3}" "bas" "preinst;prerm")
diff --git a/Tests/RunCMake/CPack/DEB/DEPENDENCIES-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-ExpectedFiles.cmake
new file mode 100644
index 0000000..c56c670
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-ExpectedFiles.cmake
@@ -0,0 +1,14 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "5")
+set(EXPECTED_FILE_1 "dependencies*-applications.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/foo${whitespaces_}.*/usr/foo/test_prog$")
+set(EXPECTED_FILE_2 "dependencies*-applications_auto.deb")
+set(EXPECTED_FILE_CONTENT_2 "^.*/usr/foo_auto${whitespaces_}.*/usr/foo_auto/test_prog$")
+set(EXPECTED_FILE_3 "dependencies*-headers.deb")
+set(EXPECTED_FILE_CONTENT_3 "^.*/usr/bar${whitespaces_}.*/usr/bar/CMakeLists.txt$")
+set(EXPECTED_FILE_4 "dependencies*-libs.deb")
+# dynamic lib extension is .so on Linux and .dylib on Mac so we will use a wildcard .* for it
+set(EXPECTED_FILE_CONTENT_4 "^.*/usr/bas${whitespaces_}.*/usr/bas/libtest_lib\\..*$")
+set(EXPECTED_FILE_5 "dependencies*-libs_auto.deb")
+set(EXPECTED_FILE_CONTENT_5 "^.*/usr/bas_auto${whitespaces_}.*/usr/bas_auto/libtest_lib\\..*$")
diff --git a/Tests/RunCMake/CPack/DEB/DEPENDENCIES-VerifyResult.cmake b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-VerifyResult.cmake
new file mode 100644
index 0000000..ba39f2e
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-VerifyResult.cmake
@@ -0,0 +1,34 @@
+function(checkDependencies_ FILE REGEX)
+  set(whitespaces_ "[\t\n\r ]*")
+
+  getPackageInfo("${FILE}" "FILE_INFO_")
+  if(NOT FILE_INFO_ MATCHES "${REGEX}")
+    message(FATAL_ERROR "Unexpected dependencies in '${FILE}'; file info: '${FILE_INFO_}'")
+  endif()
+endfunction()
+
+foreach(dependency_type_ DEPENDS CONFLICTS ENHANCES BREAKS REPLACES RECOMMENDS SUGGESTS)
+  string(TOLOWER "${dependency_type_}" lower_dependency_type_)
+  string(SUBSTRING ${lower_dependency_type_} 1 -1 lower_dependency_type_tail_)
+  string(SUBSTRING ${dependency_type_} 0 1 dependency_type_head_)
+  set(dependency_type_name_ "${dependency_type_head_}${lower_dependency_type_tail_}")
+
+  checkDependencies_("${FOUND_FILE_1}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}${lower_dependency_type_}-application, ${lower_dependency_type_}-application-b.*")
+  checkDependencies_("${FOUND_FILE_2}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}.*${lower_dependency_type_}-application, ${lower_dependency_type_}-application-b.*")
+  checkDependencies_("${FOUND_FILE_3}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}${lower_dependency_type_}-headers.*")
+  checkDependencies_("${FOUND_FILE_4}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}${lower_dependency_type_}-default, ${lower_dependency_type_}-default-b.*")
+  checkDependencies_("${FOUND_FILE_5}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}${lower_dependency_type_}-default, ${lower_dependency_type_}-default-b.*")
+endforeach()
+
+checkDependencies_("${FOUND_FILE_1}" ".*Provides${whitespaces_}:${whitespaces_}provided-default, provided-default-b")
+checkDependencies_("${FOUND_FILE_2}" ".*Provides${whitespaces_}:${whitespaces_}provided-default, provided-default-b")
+checkDependencies_("${FOUND_FILE_3}" ".*Provides${whitespaces_}:${whitespaces_}provided-default, provided-default-b")
+checkDependencies_("${FOUND_FILE_4}" ".*Provides${whitespaces_}:${whitespaces_}provided-lib.*")
+checkDependencies_("${FOUND_FILE_5}" ".*Provides${whitespaces_}:${whitespaces_}provided-lib_auto.*, provided-lib_auto-b.*")
+
+# PREDEPENDS
+checkDependencies_("${FOUND_FILE_1}" ".*Pre-Depends${whitespaces_}:${whitespaces_}predepends-application, predepends-application-b.*")
+checkDependencies_("${FOUND_FILE_2}" ".*Pre-Depends${whitespaces_}:${whitespaces_}.*predepends-application, predepends-application-b.*")
+checkDependencies_("${FOUND_FILE_3}" ".*Pre-Depends${whitespaces_}:${whitespaces_}predepends-headers.*")
+checkDependencies_("${FOUND_FILE_4}" ".*Pre-Depends${whitespaces_}:${whitespaces_}predepends-default, predepends-default-b.*")
+checkDependencies_("${FOUND_FILE_5}" ".*Pre-Depends${whitespaces_}:${whitespaces_}predepends-default, predepends-default-b.*")
diff --git a/Tests/RunCMake/CPack/DEB/DEPENDENCIES-specifics.cmake b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-specifics.cmake
new file mode 100644
index 0000000..96a9f14
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-specifics.cmake
@@ -0,0 +1,21 @@
+set(CPACK_PACKAGE_CONTACT "someone")
+set(CPACK_DEB_COMPONENT_INSTALL "ON")
+
+# false by default
+set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS FALSE)
+# FIXME can not be tested as libraries first have to be part of a package in order
+# to determine their dependencies and we can not be certain if there will be any
+set(CPACK_DEBIAN_APPLICATIONS_AUTO_PACKAGE_SHLIBDEPS TRUE)
+
+foreach(dependency_type_ DEPENDS CONFLICTS PREDEPENDS ENHANCES BREAKS REPLACES RECOMMENDS SUGGESTS)
+  string(TOLOWER "${dependency_type_}" lower_dependency_type_)
+
+  set(CPACK_DEBIAN_PACKAGE_${dependency_type_} "${lower_dependency_type_}-default, ${lower_dependency_type_}-default-b")
+  set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_${dependency_type_} "${lower_dependency_type_}-application, ${lower_dependency_type_}-application-b")
+  set(CPACK_DEBIAN_APPLICATIONS_AUTO_PACKAGE_${dependency_type_} "${lower_dependency_type_}-application, ${lower_dependency_type_}-application-b")
+  set(CPACK_DEBIAN_HEADERS_PACKAGE_${dependency_type_} "${lower_dependency_type_}-headers")
+endforeach()
+
+set(CPACK_DEBIAN_PACKAGE_PROVIDES "provided-default, provided-default-b")
+set(CPACK_DEBIAN_LIBS_PACKAGE_PROVIDES "provided-lib")
+set(CPACK_DEBIAN_LIBS_AUTO_PACKAGE_PROVIDES "provided-lib_auto, provided-lib_auto-b")
diff --git a/Tests/RunCMake/CPack/DEB/EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 0000000..1552a36
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "empty_dir*.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/${whitespaces_}.*/usr/empty/$")
diff --git a/Tests/RunCMake/CPack/DEB/EMPTY_DIR-specifics.cmake b/Tests/RunCMake/CPack/DEB/EMPTY_DIR-specifics.cmake
new file mode 100644
index 0000000..8821ab9
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/EMPTY_DIR-specifics.cmake
@@ -0,0 +1 @@
+set(CPACK_PACKAGE_CONTACT "someone")
diff --git a/Tests/RunCMake/CPack/DEB/Helpers.cmake b/Tests/RunCMake/CPack/DEB/Helpers.cmake
new file mode 100644
index 0000000..f490130
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/Helpers.cmake
@@ -0,0 +1,51 @@
+set(ALL_FILES_GLOB "*.deb")
+
+function(getPackageContent FILE RESULT_VAR)
+  execute_process(COMMAND ${DPKG_EXECUTABLE} -c ${FILE}
+          OUTPUT_VARIABLE package_content_
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  set(${RESULT_VAR} "${package_content_}" PARENT_SCOPE)
+endfunction()
+
+function(verifyDebControl FILE PREFIX VERIFY_FILES)
+  execute_process(COMMAND ${DPKG_EXECUTABLE} --control ${FILE} control_${PREFIX}
+          ERROR_VARIABLE err_)
+
+  if(err_)
+    message(FATAL_ERROR "Debian control verification failed for file: "
+        "'${FILE}'; error output: '${err_}'")
+  endif()
+
+  foreach(FILE_ IN LISTS VERIFY_FILES)
+    file(READ "${CMAKE_CURRENT_BINARY_DIR}/control_${PREFIX}/${FILE_}" content_)
+    if(NOT content_ MATCHES "${${PREFIX}_${FILE_}}")
+      message(FATAL_ERROR "Unexpected content in for '${PREFIX}_${FILE_}'!"
+          " Content: '${content_}'")
+    endif()
+
+    execute_process(COMMAND ls -l "${CMAKE_CURRENT_BINARY_DIR}/control_${PREFIX}/${FILE_}"
+          OUTPUT_VARIABLE package_permissions_
+          ERROR_VARIABLE package_permissions_error_
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    if(NOT package_permissions_error_)
+      if(NOT package_permissions_ MATCHES "${${PREFIX}_${FILE_}_permissions_regex}")
+        message(FATAL_ERROR "Unexpected file permissions for ${PREFIX}_${FILE_}: '${package_permissions_}'!")
+      endif()
+    else()
+      message(FATAL_ERROR "Listing file permissions failed (${package_permissions_error_})!")
+    endif()
+  endforeach()
+endfunction()
+
+function(getPackageInfo FILE RESULT_VAR)
+  execute_process(COMMAND ${DPKG_EXECUTABLE} -I ${FILE}
+          WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+          OUTPUT_VARIABLE package_info_
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  set(${RESULT_VAR} "${package_info_}" PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/CPack/DEB/MINIMAL-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/MINIMAL-ExpectedFiles.cmake
new file mode 100644
index 0000000..9e4aa7c
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/MINIMAL-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "minimal*.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/${whitespaces_}.*/usr/foo/${whitespaces_}.*/usr/foo/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/DEB/MINIMAL-specifics.cmake b/Tests/RunCMake/CPack/DEB/MINIMAL-specifics.cmake
new file mode 100644
index 0000000..8821ab9
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/MINIMAL-specifics.cmake
@@ -0,0 +1 @@
+set(CPACK_PACKAGE_CONTACT "someone")
diff --git a/Tests/RunCMake/CPack/DEB/Prerequirements.cmake b/Tests/RunCMake/CPack/DEB/Prerequirements.cmake
new file mode 100644
index 0000000..197b99d
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/Prerequirements.cmake
@@ -0,0 +1,8 @@
+function(get_test_prerequirements found_var config_file)
+  find_program(DPKG_EXECUTABLE dpkg)
+
+  if(DPKG_EXECUTABLE)
+    file(WRITE "${config_file}" "set(DPKG_EXECUTABLE \"${DPKG_EXECUTABLE}\")")
+    set(${found_var} true PARENT_SCOPE)
+  endif()
+endfunction()
diff --git a/Tests/RunCMake/CPack/DEB_EXTRA.cmake b/Tests/RunCMake/CPack/DEB_EXTRA.cmake
new file mode 100644
index 0000000..3c291d5
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB_EXTRA.cmake
@@ -0,0 +1,38 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT foo)
+install(FILES CMakeLists.txt DESTINATION bar COMPONENT bar)
+install(FILES CMakeLists.txt DESTINATION bas COMPONENT bas)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/preinst "echo default_preinst")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/prerm "echo default_prerm")
+
+foreach(file_ preinst prerm)
+  file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/${file_}
+    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
+    FILE_PERMISSIONS
+      OWNER_READ OWNER_WRITE OWNER_EXECUTE
+      GROUP_READ GROUP_EXECUTE
+      WORLD_READ WORLD_EXECUTE)
+endforeach()
+
+set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
+    "${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm;${CMAKE_CURRENT_BINARY_DIR}/conffiles")
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/preinst "echo bar_preinst")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/prerm "echo bar_prerm")
+
+foreach(file_ preinst prerm)
+  # not acceptable permissions for lintian but we need to check that
+  # permissions are preserved
+  file(COPY ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/${file_}
+    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bar
+    FILE_PERMISSIONS
+      OWNER_READ OWNER_WRITE OWNER_EXECUTE)
+endforeach()
+
+set(CPACK_DEBIAN_BAR_PACKAGE_CONTROL_EXTRA
+    "${CMAKE_CURRENT_BINARY_DIR}/bar/preinst;${CMAKE_CURRENT_BINARY_DIR}/bar/prerm")
+
+set(CPACK_PACKAGE_NAME "deb_extra")
+set(CPACK_PACKAGE_CONTACT "someone")
+
+set(CPACK_DEB_COMPONENT_INSTALL ON)
diff --git a/Tests/RunCMake/CPack/DEPENDENCIES.cmake b/Tests/RunCMake/CPack/DEPENDENCIES.cmake
new file mode 100644
index 0000000..4f6d65f
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEPENDENCIES.cmake
@@ -0,0 +1,20 @@
+set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.hpp"
+    "int test_lib();\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp"
+    "#include \"test_lib.hpp\"\nint test_lib() {return 0;}\n")
+add_library(test_lib SHARED "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
+    "#include \"test_lib.hpp\"\nint main() {return test_lib();}\n")
+add_executable(test_prog "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
+target_link_libraries(test_prog test_lib)
+
+install(TARGETS test_prog DESTINATION foo COMPONENT applications)
+install(TARGETS test_prog DESTINATION foo_auto COMPONENT applications_auto)
+install(FILES CMakeLists.txt DESTINATION bar COMPONENT headers)
+install(TARGETS test_lib DESTINATION bas COMPONENT libs)
+install(TARGETS test_lib DESTINATION bas_auto COMPONENT libs_auto)
+
+set(CPACK_PACKAGE_NAME "dependencies")
diff --git a/Tests/RunCMake/CPack/EMPTY_DIR.cmake b/Tests/RunCMake/CPack/EMPTY_DIR.cmake
new file mode 100644
index 0000000..023ba17
--- /dev/null
+++ b/Tests/RunCMake/CPack/EMPTY_DIR.cmake
@@ -0,0 +1,4 @@
+install(DIRECTORY DESTINATION empty
+        COMPONENT test)
+
+set(CPACK_PACKAGE_NAME "empty_dir")
diff --git a/Tests/RunCMake/CPack/MINIMAL.cmake b/Tests/RunCMake/CPack/MINIMAL.cmake
new file mode 100644
index 0000000..f29ad2a
--- /dev/null
+++ b/Tests/RunCMake/CPack/MINIMAL.cmake
@@ -0,0 +1,3 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+set(CPACK_PACKAGE_NAME "minimal")
diff --git a/Tests/RunCMake/CPackRPM/CPackRPM_PARTIALLY_RELOCATABLE_WARNING.cmake b/Tests/RunCMake/CPack/PARTIALLY_RELOCATABLE_WARNING.cmake
similarity index 100%
rename from Tests/RunCMake/CPackRPM/CPackRPM_PARTIALLY_RELOCATABLE_WARNING.cmake
rename to Tests/RunCMake/CPack/PARTIALLY_RELOCATABLE_WARNING.cmake
diff --git a/Tests/RunCMake/CPack/README.txt b/Tests/RunCMake/CPack/README.txt
new file mode 100644
index 0000000..ea68304
--- /dev/null
+++ b/Tests/RunCMake/CPack/README.txt
@@ -0,0 +1,99 @@
+RunCMake.CPack is a test module that is intended for testing of package
+generators that can be validated from command line.
+
+-------------
+Adding a test
+-------------
+
+CPack test root directory: 'Tests/RunCMake/CPack'.
+
+All phases are executed separately for each generator that is bound to a test.
+Tests for each generator are subtests of test 'RunCMake.CPack_<generator_name>'.
+
+Each test must also be added to 'RunCMakeTest.cmake' script located in CPack
+test root directory.
+Line that adds a test is:
+run_cpack_test(<test_name> "<generator_name>")
+
+<generator_name> may be one generator e.g. "RPM" or multiple e.g. "RPM;DEB" and
+will be run for all listed generators.
+
+Test consists of
+- CMake execution phase
+- CPack execution phase
+- verification of generated files
+
+CMake execution phase:
+----------------------
+
+To add a new CPack test we first create a <test_name>.cmake script that contains
+CMake commands that should be used as a preparation script for generation of
+different types of packages. This script is placed into CPack test root
+directory even if it will be used for only one of the generators.
+
+If test will be used for multiple generators but some of them require some
+generator specific commands then those commands should be added to a separate
+file that should be located in '<generator_name>/<test_name>-specifics.cmake'
+in CPack test root directory.
+
+CPack execution phase:
+----------------------
+
+Only executes CPack for content that was generated during CMake execution
+phase.
+
+Verification of generated files:
+--------------------------------
+
+Verification of generated files consists of two phases
+- mandatory verification phase
+- optional verification phase
+
+Mandatory verification phase checks that expected files were generated and
+contain expected files.
+Mandatory verification phase also checks that no other unexpected package files
+were generated (this is executed even if EXPECTED_FILES_COUNT contains 0 in
+order to verify that no files were generated).
+CMake script '<generator_name>/<test_name>-ExpectedFiles.cmake' is required by
+this step and must contain
+- EXPECTED_FILES_COUNT variable that contains the number of expected files that
+  will be generated (0 or more)
+- EXPECTED_FILE_<file_number_starting_with_1> that contains globing expression
+  that uniquely defines expected file name (will be used to find expected file)
+  and should be present once for each expected file
+- EXPECTED_FILE_CONTENT_<file_number_starting_with_1> that contains regular
+  expression of files that should be present in generated file and should be
+  present once for each expected file
+
+Optional verification phase is generator specific and is optionaly executed.
+This phase is executed if '<generator_name>/<test_name>-VerifyResult.cmake'
+script exists.
+In case that the script doesn't exist VerifyResult.cmake script automatically
+prints out standard output and standard error from CPack execution phase that
+is compared with '<generator_name>/<test_name>-stdout.txt' regular expression
+and '<generator_name>/<test_name>-stderr.txt' regular expresson respectively.
+
+----------------------
+Adding a new generator
+----------------------
+
+To add a new generator we must
+- add new generator directory (e.g. RPM for RPM generator) to CPack test root
+  directory that contains 'Helpers.cmake' script. In this script a function
+  named 'getPackageContent' must exist. This function should list files that
+  are contained in a package. Function should accept two parameters
+  + FILE variable that will contain path to file for which the content should be
+    listed
+  + RESULT_VAR that will tell the function which variable in parent scope should
+    contain the result (list of files inside package file)
+- add 'Prerequirements.cmake' script to generator directory. In this script a
+  function named 'get_test_prerequirements' must exist. This function should
+  set a variable in parent scope (name of the variable is the first parameter)
+  that tells if prerequirements for test execution are met (certain programs,
+  OS specifics, ...) and create a config file (name of the variable which
+  contains file name and path is provided with the second parameter) that
+  should contain 'set' commands for variables that will later be used in tests
+  (e.g. location of dpkg program for DEB packages)
+- add tests the same way as described above
+- add generator to 'add_RunCMake_test_group' function call that is located in
+  RunCMake CMakeLists.txt file
diff --git a/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 0000000..d396276
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "components_empty_dir*.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/usr/empty$")
diff --git a/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-stderr.txt b/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-stderr.txt
new file mode 100644
index 0000000..6ddca12
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/COMPONENTS_EMPTY_DIR-build/_CPack_Packages/.*/RPM/SPECS/components_empty_dir.spec$
diff --git a/Tests/RunCMake/CPack/RPM/DEPENDENCIES-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-ExpectedFiles.cmake
new file mode 100644
index 0000000..cf85dab
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-ExpectedFiles.cmake
@@ -0,0 +1,13 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "5")
+set(EXPECTED_FILE_1 "dependencies*-applications.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/test_prog$")
+set(EXPECTED_FILE_2 "dependencies*-applications_auto.rpm")
+set(EXPECTED_FILE_CONTENT_2 "^/usr/foo_auto${whitespaces_}/usr/foo_auto/test_prog$")
+set(EXPECTED_FILE_3 "dependencies*-headers.rpm")
+set(EXPECTED_FILE_CONTENT_3 "^/usr/bar${whitespaces_}/usr/bar/CMakeLists.txt$")
+set(EXPECTED_FILE_4 "dependencies*-libs.rpm")
+set(EXPECTED_FILE_CONTENT_4 "^/usr/bas${whitespaces_}/usr/bas/libtest_lib.so$")
+set(EXPECTED_FILE_5 "dependencies*-libs_auto.rpm")
+set(EXPECTED_FILE_CONTENT_5 "^/usr/bas_auto${whitespaces_}/usr/bas_auto/libtest_lib.so$")
diff --git a/Tests/RunCMake/CPack/RPM/DEPENDENCIES-VerifyResult.cmake b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-VerifyResult.cmake
new file mode 100644
index 0000000..fec8889
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-VerifyResult.cmake
@@ -0,0 +1,45 @@
+function(checkDependencies_ FILE TYPE COMPARE_LIST)
+  set(whitespaces_ "[\t\n\r ]*")
+
+  execute_process(COMMAND ${RPM_EXECUTABLE} -qp --${TYPE} ${FILE}
+          WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+          OUTPUT_VARIABLE FILE_DEPENDENCIES_
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  string(REPLACE "\n" ";" FILE_DEPENDENCIES_LIST_ "${FILE_DEPENDENCIES_}")
+
+  foreach(COMPARE_REGEX_ IN LISTS COMPARE_LIST)
+    unset(FOUND_)
+
+    foreach(COMPARE_ IN LISTS FILE_DEPENDENCIES_LIST_)
+      if(COMPARE_ MATCHES "${COMPARE_REGEX_}")
+        set(FOUND_ true)
+        break()
+      endif()
+    endforeach()
+
+    if(NOT FOUND_)
+      message(FATAL_ERROR "Missing dependencies in '${FILE}'; check type: '${TYPE}'; file info: '${FILE_DEPENDENCIES_}'; missing: '${COMPARE_REGEX_}'")
+    endif()
+  endforeach()
+endfunction()
+
+# TODO add tests for what should not be present in lists
+checkDependencies_("${FOUND_FILE_1}" "requires" "depend-application;depend-application-b")
+checkDependencies_("${FOUND_FILE_2}" "requires" "depend-application;depend-application-b;libtest_lib\\.so.*")
+checkDependencies_("${FOUND_FILE_3}" "requires" "depend-headers")
+checkDependencies_("${FOUND_FILE_4}" "requires" "depend-default;depend-default-b")
+checkDependencies_("${FOUND_FILE_5}" "requires" "depend-default;depend-default-b")
+
+checkDependencies_("${FOUND_FILE_1}" "conflicts" "conflict-application;conflict-application-b")
+checkDependencies_("${FOUND_FILE_2}" "conflicts" "conflict-application;conflict-application-b")
+checkDependencies_("${FOUND_FILE_3}" "conflicts" "conflict-headers")
+checkDependencies_("${FOUND_FILE_4}" "conflicts" "conflict-default;conflict-default-b")
+checkDependencies_("${FOUND_FILE_5}" "conflicts" "conflict-default;conflict-default-b")
+
+checkDependencies_("${FOUND_FILE_1}" "provides" "provided-default;provided-default-b")
+checkDependencies_("${FOUND_FILE_2}" "provides" "provided-default;provided-default-b")
+checkDependencies_("${FOUND_FILE_3}" "provides" "provided-default;provided-default-b")
+checkDependencies_("${FOUND_FILE_4}" "provides" "provided-lib")
+checkDependencies_("${FOUND_FILE_5}" "provides" "provided-lib_auto;provided-lib_auto-b")
diff --git a/Tests/RunCMake/CPack/RPM/DEPENDENCIES-specifics.cmake b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-specifics.cmake
new file mode 100644
index 0000000..2cdfece
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-specifics.cmake
@@ -0,0 +1,22 @@
+set(CPACK_RPM_COMPONENT_INSTALL "ON")
+
+# FIXME auto autoprov is not tested at the moment as Ubuntu 15.04 rpmbuild
+# does not use them correctly: https://bugs.launchpad.net/rpm/+bug/1475755
+set(CPACK_RPM_PACKAGE_AUTOREQ "no")
+set(CPACK_RPM_PACKAGE_AUTOPROV "no")
+set(CPACK_RPM_applications_auto_PACKAGE_AUTOREQPROV "yes")
+set(CPACK_RPM_libs_auto_PACKAGE_AUTOREQPROV "yes")
+
+set(CPACK_RPM_PACKAGE_REQUIRES "depend-default, depend-default-b")
+set(CPACK_RPM_applications_PACKAGE_REQUIRES "depend-application, depend-application-b")
+set(CPACK_RPM_applications_auto_PACKAGE_REQUIRES "depend-application, depend-application-b")
+set(CPACK_RPM_headers_PACKAGE_REQUIRES "depend-headers")
+
+set(CPACK_RPM_PACKAGE_CONFLICTS "conflict-default, conflict-default-b")
+set(CPACK_RPM_applications_PACKAGE_CONFLICTS "conflict-application, conflict-application-b")
+set(CPACK_RPM_applications_auto_PACKAGE_CONFLICTS "conflict-application, conflict-application-b")
+set(CPACK_RPM_headers_PACKAGE_CONFLICTS "conflict-headers")
+
+set(CPACK_RPM_PACKAGE_PROVIDES "provided-default, provided-default-b")
+set(CPACK_RPM_libs_PACKAGE_PROVIDES "provided-lib")
+set(CPACK_RPM_libs_auto_PACKAGE_PROVIDES "provided-lib_auto, provided-lib_auto-b")
diff --git a/Tests/RunCMake/CPack/RPM/EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 0000000..0c2977f
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "empty_dir*.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/usr/empty$")
diff --git a/Tests/RunCMake/CPack/RPM/EMPTY_DIR-stderr.txt b/Tests/RunCMake/CPack/RPM/EMPTY_DIR-stderr.txt
new file mode 100644
index 0000000..1777aa0
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/EMPTY_DIR-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/EMPTY_DIR-build/_CPack_Packages/.*/RPM/SPECS/empty_dir.spec$
diff --git a/Tests/RunCMake/CPack/RPM/Helpers.cmake b/Tests/RunCMake/CPack/RPM/Helpers.cmake
new file mode 100644
index 0000000..98cdad8
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/Helpers.cmake
@@ -0,0 +1,10 @@
+set(ALL_FILES_GLOB "*.rpm")
+
+function(getPackageContent FILE RESULT_VAR)
+  execute_process(COMMAND ${RPM_EXECUTABLE} -pql ${FILE}
+          OUTPUT_VARIABLE package_content_
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  set(${RESULT_VAR} "${package_content_}" PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/CPack/RPM/MINIMAL-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/MINIMAL-ExpectedFiles.cmake
new file mode 100644
index 0000000..800b78e
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MINIMAL-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "minimal*.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/RPM/MINIMAL-stderr.txt b/Tests/RunCMake/CPack/RPM/MINIMAL-stderr.txt
new file mode 100644
index 0000000..7c5fb46
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MINIMAL-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/MINIMAL-build/_CPack_Packages/.*/RPM/SPECS/minimal.spec$
diff --git a/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-ExpectedFiles.cmake
new file mode 100644
index 0000000..4e01f7b
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "PARTIALLY_RELOCATABLE_WARNING-0.1.1-*.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/not_relocatable${whitespaces_}/not_relocatable/CMakeLists.txt${whitespaces_}/opt$")
diff --git a/Tests/RunCMake/CPackRPM/CPackRPM_PARTIALLY_RELOCATABLE_WARNING-stderr.txt b/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-stderr.txt
similarity index 100%
rename from Tests/RunCMake/CPackRPM/CPackRPM_PARTIALLY_RELOCATABLE_WARNING-stderr.txt
rename to Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-stderr.txt
diff --git a/Tests/RunCMake/CPack/RPM/Prerequirements.cmake b/Tests/RunCMake/CPack/RPM/Prerequirements.cmake
new file mode 100644
index 0000000..3416205
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/Prerequirements.cmake
@@ -0,0 +1,16 @@
+function(get_test_prerequirements found_var config_file)
+  if(CMAKE_CURRENT_BINARY_DIR MATCHES " ")
+    # rpmbuild can't handle spaces in path
+    return()
+  endif()
+
+  find_program(RPM_EXECUTABLE rpm)
+  find_program(RPMBUILD_EXECUTABLE rpmbuild)
+
+  if(RPM_EXECUTABLE AND RPMBUILD_EXECUTABLE)
+    file(WRITE "${config_file}" "set(RPM_EXECUTABLE \"${RPM_EXECUTABLE}\")")
+    file(APPEND "${config_file}"
+        "\nset(RPMBUILD_EXECUTABLE \"${RPMBUILD_EXECUTABLE}\")")
+    set(${found_var} true PARENT_SCOPE)
+  endif()
+endfunction()
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
new file mode 100644
index 0000000..b7295f4
--- /dev/null
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+
+include(RunCMake)
+include("${RunCMake_SOURCE_DIR}/CPackTestHelpers.cmake")
+
+# args: TEST_NAME "GENERATORS" RUN_CMAKE_BUILD_STEP
+run_cpack_test(MINIMAL "RPM;DEB;TGZ" false)
+run_cpack_test(PARTIALLY_RELOCATABLE_WARNING "RPM" false)
+run_cpack_test(DEB_EXTRA "DEB" false)
+run_cpack_test(DEPENDENCIES "RPM;DEB" true)
+run_cpack_test(EMPTY_DIR "RPM;DEB;TGZ" true)
+run_cpack_test(COMPONENTS_EMPTY_DIR "RPM;DEB;TGZ" true)
diff --git a/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 0000000..26e2ab0
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,3 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "components_empty_dir*.tar.gz")
+set(EXPECTED_FILE_CONTENT_1 "^[^\n]*empty/$")
diff --git a/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-specifics.cmake b/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-specifics.cmake
new file mode 100644
index 0000000..81a5035
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-specifics.cmake
@@ -0,0 +1 @@
+set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON")
diff --git a/Tests/RunCMake/CPack/TGZ/EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/TGZ/EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 0000000..a75514a
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,3 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "empty_dir*.tar.gz")
+set(EXPECTED_FILE_CONTENT_1 "^[^\n]*empty_dir-0.1.1-[^\n]*/empty/$")
diff --git a/Tests/RunCMake/CPack/TGZ/Helpers.cmake b/Tests/RunCMake/CPack/TGZ/Helpers.cmake
new file mode 100644
index 0000000..f14d532
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/Helpers.cmake
@@ -0,0 +1,10 @@
+set(ALL_FILES_GLOB "*.tar.gz")
+
+function(getPackageContent FILE RESULT_VAR)
+  execute_process(COMMAND ${CMAKE_COMMAND} -E tar -ztvf ${FILE}
+          OUTPUT_VARIABLE package_content_
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  set(${RESULT_VAR} "${package_content_}" PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/CPack/TGZ/MINIMAL-ExpectedFiles.cmake b/Tests/RunCMake/CPack/TGZ/MINIMAL-ExpectedFiles.cmake
new file mode 100644
index 0000000..5c31f27
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/MINIMAL-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "minimal*.tar.gz")
+set(EXPECTED_FILE_CONTENT_1 "^[^\n]*minimal-0.1.1-[^\n]*/foo/\n[^\n]*minimal-0.1.1-[^\n]*/foo/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/TGZ/Prerequirements.cmake b/Tests/RunCMake/CPack/TGZ/Prerequirements.cmake
new file mode 100644
index 0000000..dbaf682
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/Prerequirements.cmake
@@ -0,0 +1,4 @@
+function(get_test_prerequirements found_var config_file)
+  file(WRITE "${config_file}" "")
+  set(${found_var} true PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/CPack/VerifyResult.cmake b/Tests/RunCMake/CPack/VerifyResult.cmake
new file mode 100644
index 0000000..6eab531
--- /dev/null
+++ b/Tests/RunCMake/CPack/VerifyResult.cmake
@@ -0,0 +1,92 @@
+cmake_minimum_required(VERSION ${CMAKE_VERSION} FATAL_ERROR)
+
+include("${config_file}")
+include("${src_dir}/${GENERATOR_TYPE}/Helpers.cmake")
+
+file(READ "${bin_dir}/test_output.txt" output)
+file(READ "${bin_dir}/test_error.txt" error)
+file(READ "${config_file}" config_file_content)
+
+set(output_error_message
+    "\nCPack output: '${output}'\nCPack error: '${error}';\nconfig file: '${config_file_content}'")
+
+# check that expected generated files exist and contain expected content
+include("${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST}-ExpectedFiles.cmake")
+
+if(NOT EXPECTED_FILES_COUNT EQUAL 0)
+  foreach(file_no_ RANGE 1 ${EXPECTED_FILES_COUNT})
+    file(GLOB FOUND_FILE_${file_no_} RELATIVE "${bin_dir}" "${EXPECTED_FILE_${file_no_}}")
+    set(foundFiles_ "${foundFiles_};${FOUND_FILE_${file_no_}}")
+    list(LENGTH FOUND_FILE_${file_no_} foundFilesCount_)
+
+    if(foundFilesCount_ EQUAL 1)
+      unset(PACKAGE_CONTENT)
+      getPackageContent("${bin_dir}/${FOUND_FILE_${file_no_}}" "PACKAGE_CONTENT")
+
+      string(REGEX MATCH "${EXPECTED_FILE_CONTENT_${file_no_}}"
+          expected_content_list "${PACKAGE_CONTENT}")
+
+      if(NOT expected_content_list)
+        message(FATAL_ERROR
+          "Unexpected file content for file No. '${file_no_}'!\n"
+          " Content: '${PACKAGE_CONTENT}'\n\n"
+          " Expected: '${EXPECTED_FILE_CONTENT_${file_no_}}'"
+          "${output_error_message}")
+      endif()
+    else()
+      message(FATAL_ERROR
+        "Found more than one file for file No. '${file_no_}'!"
+        " Found files count '${foundFilesCount_}'."
+        " Files: '${FOUND_FILE_${file_no_}}'"
+        "${output_error_message}")
+    endif()
+  endforeach()
+
+  # check that there were no extra files generated
+  foreach(all_files_glob_ IN LISTS ALL_FILES_GLOB)
+    file(GLOB foundAll_ RELATIVE "${bin_dir}" "${all_files_glob_}")
+    set(allFoundFiles_ "${allFoundFiles_};${foundAll_}")
+  endforeach()
+
+  list(LENGTH foundFiles_ foundFilesCount_)
+  list(LENGTH allFoundFiles_ allFoundFilesCount_)
+
+  if(NOT foundFilesCount_ EQUAL allFoundFilesCount_)
+    message(FATAL_ERROR
+        "Found more files than expected! Found files: '${allFoundFiles_}'"
+        "${output_error_message}")
+  endif()
+
+  # sanity check that we didn't accidentally list wrong files with our regular
+  # expressions
+  foreach(expected_ IN LISTS allFoundFiles_)
+    list(FIND foundFiles_ "${expected_}" found_)
+
+    if(found_ EQUAL -1)
+      message(FATAL_ERROR
+          "Expected files don't match found files! Found files:"
+          " '${allFoundFiles_}'"
+          "${output_error_message}")
+    endif()
+  endforeach()
+else()
+  # there should be no generated files present
+  foreach(missing_file_glob_ IN LISTS ALL_FILES_GLOB)
+    file(GLOB checkMissingFiles_ RELATIVE "${bin_dir}" "${missing_file_glob_}")
+
+    if(checkMissingFiles_)
+      message(FATAL_ERROR "Unexpected files found: '${checkMissingFiles_}'"
+          "${output_error_message}")
+    endif()
+  endforeach()
+endif()
+
+# handle additional result verifications
+if(EXISTS "${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST}-VerifyResult.cmake")
+  include("${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST}-VerifyResult.cmake")
+else()
+  # by default only print out output and error so that they can be compared by
+  # regex
+  message(STATUS "${output}")
+  message("${error}")
+endif()
diff --git a/Tests/RunCMake/CPackConfig/CMakeLists.txt b/Tests/RunCMake/CPackConfig/CMakeLists.txt
new file mode 100644
index 0000000..9a9e7b4
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.3)
+
+project(${RunCMake_TEST})
+include(${RunCMake_TEST}.cmake)
+
+include(CPack)
diff --git a/Tests/RunCMake/CPackConfig/Default-check.cmake b/Tests/RunCMake/CPackConfig/Default-check.cmake
new file mode 100644
index 0000000..b67fe81
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Default-check.cmake
@@ -0,0 +1,7 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_variable(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "Foo\\Bar")
+test_variable(CPACK_NSIS_PACKAGE_NAME "Bar\\Foo")
+
+test_variable(CPACK_SOURCE_IGNORE_FILES
+  "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#")
diff --git a/Tests/RunCMake/CPackConfig/Default.cmake b/Tests/RunCMake/CPackConfig/Default.cmake
new file mode 100644
index 0000000..3b3beb3
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Default.cmake
@@ -0,0 +1,3 @@
+# two levels of escaping to pass through CPackConfig.cmake
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "Foo\\\\Bar")
+set(CPACK_NSIS_DISPLAY_NAME "Bar\\\\Foo")
diff --git a/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake b/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake
new file mode 100644
index 0000000..16d2cf3
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(Simple)
+run_cmake(Default)
+run_cmake(Special)
+run_cmake(Verbatim)
diff --git a/Tests/RunCMake/CPackConfig/Simple-check.cmake b/Tests/RunCMake/CPackConfig/Simple-check.cmake
new file mode 100644
index 0000000..6e0cf6f
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Simple-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_variable(CPACK_FOO "bar baz;quux")
diff --git a/Tests/RunCMake/CPackConfig/Simple.cmake b/Tests/RunCMake/CPackConfig/Simple.cmake
new file mode 100644
index 0000000..c9f6541
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Simple.cmake
@@ -0,0 +1 @@
+set(CPACK_FOO "bar baz;quux")
diff --git a/Tests/RunCMake/CPackConfig/Special-check.cmake b/Tests/RunCMake/CPackConfig/Special-check.cmake
new file mode 100644
index 0000000..0624b79
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Special-check.cmake
@@ -0,0 +1,5 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_variable(CPACK_BACKSLASH "\\")
+test_variable(CPACK_QUOTE "a;b;c")
+test_variable(CPACK_DOLLAR "ab")
diff --git a/Tests/RunCMake/CPackConfig/Special.cmake b/Tests/RunCMake/CPackConfig/Special.cmake
new file mode 100644
index 0000000..9442c93
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Special.cmake
@@ -0,0 +1,3 @@
+set(CPACK_BACKSLASH "\\\\")
+set(CPACK_QUOTE "a\" b \"c")
+set(CPACK_DOLLAR "a\${NOTHING}b")
diff --git a/Tests/RunCMake/CPackConfig/Verbatim-check.cmake b/Tests/RunCMake/CPackConfig/Verbatim-check.cmake
new file mode 100644
index 0000000..958547d
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Verbatim-check.cmake
@@ -0,0 +1,10 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_variable(CPACK_BACKSLASH "\\\\")
+test_variable(CPACK_QUOTE "a\" b \"c")
+test_variable(CPACK_DOLLAR "a\${NOTHING}b")
+
+# make sure the default for this is still set correctly with
+# CPACK_VERBATIM_VARIABLES on
+test_variable(CPACK_SOURCE_IGNORE_FILES
+  "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#")
diff --git a/Tests/RunCMake/CPackConfig/Verbatim.cmake b/Tests/RunCMake/CPackConfig/Verbatim.cmake
new file mode 100644
index 0000000..4d271c3
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Verbatim.cmake
@@ -0,0 +1,5 @@
+set(CPACK_VERBATIM_VARIABLES YES)
+
+set(CPACK_BACKSLASH "\\\\")
+set(CPACK_QUOTE "a\" b \"c")
+set(CPACK_DOLLAR "a\${NOTHING}b")
diff --git a/Tests/RunCMake/CPackConfig/check.cmake b/Tests/RunCMake/CPackConfig/check.cmake
new file mode 100644
index 0000000..ca6229e
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/check.cmake
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION ${CMAKE_VERSION} FATAL_ERROR)
+
+function(test_variable NAME EXPECTED_VALUE)
+  if(NOT "${${NAME}}" STREQUAL "${EXPECTED_VALUE}")
+    message(FATAL_ERROR "${NAME}: variable mismatch; expected [${EXPECTED_VALUE}] actual [${${NAME}}]")
+  endif()
+endfunction()
+
+include(${RunCMake_TEST_BINARY_DIR}/CPackConfig.cmake)
+include(${RunCMake_TEST_BINARY_DIR}/CPackSourceConfig.cmake)
diff --git a/Tests/RunCMake/CPackRPM/CMakeLists.txt b/Tests/RunCMake/CPackRPM/CMakeLists.txt
deleted file mode 100644
index b7d170b..0000000
--- a/Tests/RunCMake/CPackRPM/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
-
-project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
-
-set(CPACK_GENERATOR "RPM")
-include(CPack)
diff --git a/Tests/RunCMake/CPackRPM/RunCMakeTest.cmake b/Tests/RunCMake/CPackRPM/RunCMakeTest.cmake
deleted file mode 100644
index 1935e32..0000000
--- a/Tests/RunCMake/CPackRPM/RunCMakeTest.cmake
+++ /dev/null
@@ -1,17 +0,0 @@
-include(RunCMake)
-
-function(run_cpack_rpm_test TEST_NAME)
-  set(RunCMake_TEST_NO_CLEAN TRUE)
-  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${TEST_NAME}-build")
-  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
-  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
-  execute_process(
-    COMMAND "${CMAKE_COMMAND}" -D RunCMake_TEST=${TEST_NAME} "${RunCMake_SOURCE_DIR}"
-    WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
-    OUTPUT_QUIET
-    ERROR_QUIET
-    )
-  run_cmake_command(${TEST_NAME} ${CMAKE_CPACK_COMMAND})
-endfunction()
-
-run_cpack_rpm_test(CPackRPM_PARTIALLY_RELOCATABLE_WARNING)
diff --git a/Tests/RunCMake/CTestCommandLine/LabelCount-stdout.txt b/Tests/RunCMake/CTestCommandLine/LabelCount-stdout.txt
new file mode 100644
index 0000000..7fe04eb
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/LabelCount-stdout.txt
@@ -0,0 +1,7 @@
+100% tests passed, 0 tests failed out of 4
++
++Label Time Summary:
++'bar'    = +[0-9.]+ sec \(3 tests\)
++'foo'    = +[0-9.]+ sec \(1 test\)
++
+Total Test time \(real\) = +[0-9.]+ sec
diff --git a/Tests/RunCMake/CTestCommandLine/MergeOutput-stdout.txt b/Tests/RunCMake/CTestCommandLine/MergeOutput-stdout.txt
new file mode 100644
index 0000000..af7cdc5
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/MergeOutput-stdout.txt
@@ -0,0 +1,13 @@
+Test timeout computed to be: [^
+]+
+1: -- Output on stdout
+1: Output on stderr
+1: -- Output on stdout
+1: Output on stderr
+1: -- Output on stdout
+1: Output on stderr
+1: -- Output on stdout
+1: Output on stderr
+1: -- Output on stdout
+1: Output on stderr
+1/1 Test #1: MergeOutput
diff --git a/Tests/RunCMake/CTestCommandLine/MergeOutput.cmake b/Tests/RunCMake/CTestCommandLine/MergeOutput.cmake
new file mode 100644
index 0000000..528ac90
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/MergeOutput.cmake
@@ -0,0 +1,4 @@
+foreach(i RANGE 1 5)
+  message(STATUS "Output on stdout")
+  message("Output on stderr")
+endforeach()
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index 0cb11ac..2bc3693 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -1,4 +1,5 @@
 include(RunCMake)
+set(RunCMake_TEST_TIMEOUT 60)
 
 unset(ENV{CTEST_PARALLEL_LEVEL})
 unset(ENV{CTEST_OUTPUT_ON_FAILURE})
@@ -39,3 +40,103 @@ subdirs()
   run_cmake_command(BadCTestTestfile ${CMAKE_CTEST_COMMAND})
 endfunction()
 run_BadCTestTestfile()
+
+function(run_MergeOutput)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/MergeOutput)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+add_test(MergeOutput \"${CMAKE_COMMAND}\" -P \"${RunCMake_SOURCE_DIR}/MergeOutput.cmake\")
+")
+
+  run_cmake_command(MergeOutput ${CMAKE_CTEST_COMMAND} -V)
+endfunction()
+run_MergeOutput()
+
+function(run_LabelCount)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LabelCount)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+add_test(test1 \"${CMAKE_COMMAND}\" -E echo \"test1\")
+set_tests_properties(test1 PROPERTIES LABELS 'bar')
+
+add_test(test2 \"${CMAKE_COMMAND}\" -E echo \"test2\")
+set_tests_properties(test2 PROPERTIES LABELS 'bar')
+
+add_test(test3 \"${CMAKE_COMMAND}\" -E echo \"test3\")
+set_tests_properties(test3 PROPERTIES LABELS 'foo')
+
+add_test(test4 \"${CMAKE_COMMAND}\" -E echo \"test4\")
+set_tests_properties(test4 PROPERTIES LABELS 'bar')
+")
+
+  run_cmake_command(LabelCount ${CMAKE_CTEST_COMMAND} -V)
+endfunction()
+
+run_LabelCount()
+
+function(run_SerialFailed)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SerialFailed)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+add_test(NoSuchCommand no_such_command)
+set_tests_properties(NoSuchCommand PROPERTIES RUN_SERIAL ON)
+add_test(Echo \"${CMAKE_COMMAND}\" -E echo \"EchoTest\")
+")
+
+  run_cmake_command(SerialFailed ${CMAKE_CTEST_COMMAND} -V)
+endfunction()
+run_SerialFailed()
+
+function(run_TestLoad name load)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TestLoad)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+  add_test(TestLoad1 \"${CMAKE_COMMAND}\" -E echo \"test of --test-load\")
+  add_test(TestLoad2 \"${CMAKE_COMMAND}\" -E echo \"test of --test-load\")
+")
+  run_cmake_command(${name} ${CMAKE_CTEST_COMMAND} -j2 --test-load ${load} --test-timeout 5)
+endfunction()
+
+# Tests for the --test-load feature of ctest
+#
+# Spoof a load average value to make these tests more reliable.
+set(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING} 5)
+
+# Verify that new tests are not started when the load average exceeds
+# our threshold.
+run_TestLoad(test-load-fail 2)
+
+# Verify that warning message is displayed but tests still start when
+# an invalid argument is given.
+run_TestLoad(test-load-invalid 'two')
+
+# Verify that new tests are started when the load average falls below
+# our threshold.
+run_TestLoad(test-load-pass 10)
+
+unset(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING})
+
+function(run_TestOutputSize)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TestOutputSize)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+  add_test(PassingTest \"${CMAKE_COMMAND}\" -E echo PassingTestOutput)
+  add_test(FailingTest \"${CMAKE_COMMAND}\" -E no_such_command)
+")
+  run_cmake_command(TestOutputSize
+    ${CMAKE_CTEST_COMMAND} -M Experimental -T Test
+                           --test-output-size-passed 10
+                           --test-output-size-failed 12
+    )
+endfunction()
+run_TestOutputSize()
diff --git a/Tests/RunCMake/CTestCommandLine/SerialFailed-result.txt b/Tests/RunCMake/CTestCommandLine/SerialFailed-result.txt
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/SerialFailed-result.txt
@@ -0,0 +1 @@
+8
diff --git a/Tests/RunCMake/CTestCommandLine/SerialFailed-stderr.txt b/Tests/RunCMake/CTestCommandLine/SerialFailed-stderr.txt
new file mode 100644
index 0000000..cafe565
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/SerialFailed-stderr.txt
@@ -0,0 +1 @@
+Unable to find executable: no_such_command
diff --git a/Tests/RunCMake/CTestCommandLine/SerialFailed-stdout.txt b/Tests/RunCMake/CTestCommandLine/SerialFailed-stdout.txt
new file mode 100644
index 0000000..d7144f7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/SerialFailed-stdout.txt
@@ -0,0 +1,10 @@
+Could not find executable no_such_command
+.*
+2/2 Test #2: Echo .............................   Passed +[0-9.]+ sec
++
+50% tests passed, 1 tests failed out of 2
++
+Total Test time \(real\) = +[0-9.]+ sec
++
+The following tests FAILED:
+[	 ]+1 - NoSuchCommand \(Not Run\)$
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputSize-check.cmake b/Tests/RunCMake/CTestCommandLine/TestOutputSize-check.cmake
new file mode 100644
index 0000000..918d242
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/TestOutputSize-check.cmake
@@ -0,0 +1,17 @@
+file(GLOB test_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Test.xml")
+if(test_xml_file)
+  file(READ "${test_xml_file}" test_xml LIMIT 4096)
+  if("${test_xml}" MATCHES [[(<Test Status="passed">.*</Test>).*(<Test Status="failed">.*</Test>)]])
+    set(test_passed "${CMAKE_MATCH_1}")
+    set(test_failed "${CMAKE_MATCH_2}")
+  else()
+    set(RunCMake_TEST_FAILED "Test.xml does not contain a passed then failed test:\n ${test_xml}")
+  endif()
+  if(NOT "${test_passed}" MATCHES [[<Value>PassingTes\.\.\..*10 bytes]])
+    set(RunCMake_TEST_FAILED "Test.xml passed test output not truncated at 10 bytes:\n ${test_passed}")
+  elseif(NOT "${test_failed}" MATCHES [[<Value>CMake Error:\.\.\..*12 bytes]])
+    set(RunCMake_TEST_FAILED "Test.xml failed test output not truncated at 12 bytes:\n ${test_failed}")
+  endif()
+else()
+  set(RunCMake_TEST_FAILED "Test.xml not found")
+endif()
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputSize-result.txt b/Tests/RunCMake/CTestCommandLine/TestOutputSize-result.txt
new file mode 100644
index 0000000..9c558e3
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/TestOutputSize-result.txt
@@ -0,0 +1 @@
+.
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt
new file mode 100644
index 0000000..ba4235d
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt
@@ -0,0 +1 @@
+Errors while running CTest
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt
new file mode 100644
index 0000000..eafba1c
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt
@@ -0,0 +1 @@
+No tests were found!!!
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt
new file mode 100644
index 0000000..153da09
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt
@@ -0,0 +1,2 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad
+\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 2, Smallest test TestLoad[1-2] requires 1\*\*\*\*\*
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-invalid-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stderr.txt
new file mode 100644
index 0000000..caab3b9
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stderr.txt
@@ -0,0 +1 @@
+Invalid value for 'Test Load' : 'two'
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt
new file mode 100644
index 0000000..7ee3dae
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt
@@ -0,0 +1,7 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad
+    Start 1: TestLoad1
+    Start 2: TestLoad2
+1/2 Test #[1-2]: TestLoad[1-2] ........................   Passed +[0-9.]+ sec
+2/2 Test #[1-2]: TestLoad[1-2] ........................   Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 2
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-pass-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-load-pass-stderr.txt
new file mode 100644
index 0000000..10f3293
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-pass-stderr.txt
@@ -0,0 +1 @@
+^$
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt
new file mode 100644
index 0000000..7ee3dae
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt
@@ -0,0 +1,7 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad
+    Start 1: TestLoad1
+    Start 2: TestLoad2
+1/2 Test #[1-2]: TestLoad[1-2] ........................   Passed +[0-9.]+ sec
+2/2 Test #[1-2]: TestLoad[1-2] ........................   Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 2
diff --git a/Tests/RunCMake/CommandLine/BuildDir.cmake b/Tests/RunCMake/CommandLine/BuildDir.cmake
new file mode 100644
index 0000000..30030a7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/BuildDir.cmake
@@ -0,0 +1 @@
+add_subdirectory(BuildDir)
diff --git a/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
new file mode 100644
index 0000000..20df108
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_custom_command(
+  OUTPUT output.txt
+  COMMAND ${CMAKE_COMMAND} -E echo CustomCommand > output.txt
+  )
+add_custom_target(CustomTarget ALL DEPENDS output.txt)
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 69beed9..cef6368 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -22,13 +22,30 @@ run_cmake_command(G_bad-arg ${CMAKE_COMMAND} -G NoSuchGenerator)
 run_cmake_command(P_no-arg ${CMAKE_COMMAND} -P)
 run_cmake_command(P_no-file ${CMAKE_COMMAND} -P nosuchscriptfile.cmake)
 
+run_cmake_command(build-no-dir
+  ${CMAKE_COMMAND} --build)
 run_cmake_command(build-no-cache
   ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR})
 run_cmake_command(build-no-generator
   ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-no-generator)
+run_cmake_command(build-bad-dir
+  ${CMAKE_COMMAND} --build dir-does-not-exist)
 run_cmake_command(build-bad-generator
   ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-generator)
 
+function(run_BuildDir)
+  # Use a single build tree for a few tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BuildDir-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(BuildDir)
+  run_cmake_command(BuildDir--build ${CMAKE_COMMAND} -E chdir ..
+    ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget)
+endfunction()
+run_BuildDir()
+
 if(RunCMake_GENERATOR STREQUAL "Ninja")
   # Use a single build tree for a few tests without cleaning.
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Build-build)
@@ -123,6 +140,10 @@ set(RunCMake_TEST_OPTIONS --trace)
 run_cmake(trace)
 unset(RunCMake_TEST_OPTIONS)
 
+set(RunCMake_TEST_OPTIONS --trace-expand)
+run_cmake(trace-expand)
+unset(RunCMake_TEST_OPTIONS)
+
 set(RunCMake_TEST_OPTIONS --debug-trycompile)
 run_cmake(debug-trycompile)
 unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/CommandLine/Wdev-stderr.txt b/Tests/RunCMake/CommandLine/Wdev-stderr.txt
index f427303..92c1d23 100644
--- a/Tests/RunCMake/CommandLine/Wdev-stderr.txt
+++ b/Tests/RunCMake/CommandLine/Wdev-stderr.txt
@@ -2,4 +2,10 @@
   Some Author Warning
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at Wdev.cmake:6 \(include\):
+  include\(\) given empty file name \(ignored\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/CommandLine/Wdev.cmake b/Tests/RunCMake/CommandLine/Wdev.cmake
index 0242086..e5026ef 100644
--- a/Tests/RunCMake/CommandLine/Wdev.cmake
+++ b/Tests/RunCMake/CommandLine/Wdev.cmake
@@ -1 +1,6 @@
 message(AUTHOR_WARNING "Some Author Warning")
+
+# with -Wdev this will also cause an AUTHOR_WARNING message, checks that
+# messages issued outside of the message command, by other CMake commands, also
+# are affected by -Wdev
+include("")
diff --git a/Tests/RunCMake/CommandLine/Wno-dev.cmake b/Tests/RunCMake/CommandLine/Wno-dev.cmake
index 0242086..d81b858 100644
--- a/Tests/RunCMake/CommandLine/Wno-dev.cmake
+++ b/Tests/RunCMake/CommandLine/Wno-dev.cmake
@@ -1 +1,6 @@
 message(AUTHOR_WARNING "Some Author Warning")
+
+# without -Wno-dev this will also cause an AUTHOR_WARNING message, checks that
+# messages issued outside of the message command, by other CMake commands, also
+# are affected by -Wno-dev
+include("")
diff --git a/Tests/RunCMake/CommandLine/build-bad-dir-result.txt b/Tests/RunCMake/CommandLine/build-bad-dir-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-bad-dir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/build-bad-dir-stderr.txt b/Tests/RunCMake/CommandLine/build-bad-dir-stderr.txt
new file mode 100644
index 0000000..d3f3d9c
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-bad-dir-stderr.txt
@@ -0,0 +1,2 @@
+^Error: [^
+]+/Tests/RunCMake/CommandLine/build-bad-dir-build/dir-does-not-exist is not a directory$
diff --git a/Tests/RunCMake/CommandLine/build-no-dir-result.txt b/Tests/RunCMake/CommandLine/build-no-dir-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-dir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/build-no-dir-stderr.txt b/Tests/RunCMake/CommandLine/build-no-dir-stderr.txt
new file mode 100644
index 0000000..8d518f6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-dir-stderr.txt
@@ -0,0 +1 @@
+^Usage: cmake --build <dir> \[options\] \[-- \[native-options\]\]
diff --git a/Tests/RunCMake/CommandLine/trace-expand-stderr.txt b/Tests/RunCMake/CommandLine/trace-expand-stderr.txt
new file mode 100644
index 0000000..4fee9bc
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-expand-stderr.txt
@@ -0,0 +1,2 @@
+^.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(1\):  cmake_minimum_required\(VERSION 3.0 \)
+.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(2\):  project\(trace-expand NONE \)
diff --git a/Tests/RunCMake/CommandLine/trace-expand.cmake b/Tests/RunCMake/CommandLine/trace-expand.cmake
new file mode 100644
index 0000000..e69de29
diff --git a/Tests/RunCMake/CompileDefinitions/CMakeLists.txt b/Tests/RunCMake/CompileDefinitions/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompileDefinitions/RunCMakeTest.cmake b/Tests/RunCMake/CompileDefinitions/RunCMakeTest.cmake
new file mode 100644
index 0000000..233fe34
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(SetEmpty)
diff --git a/Tests/RunCMake/CompileDefinitions/SetEmpty-result.txt b/Tests/RunCMake/CompileDefinitions/SetEmpty-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/SetEmpty-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CompileDefinitions/SetEmpty-stderr.txt b/Tests/RunCMake/CompileDefinitions/SetEmpty-stderr.txt
new file mode 100644
index 0000000..ace6656
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/SetEmpty-stderr.txt
@@ -0,0 +1,3 @@
+RESULT1=A;;B
+RESULT2=
+RESULT3=-DBAR
diff --git a/Tests/RunCMake/CompileDefinitions/SetEmpty.cmake b/Tests/RunCMake/CompileDefinitions/SetEmpty.cmake
new file mode 100644
index 0000000..15cb4e9
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/SetEmpty.cmake
@@ -0,0 +1,12 @@
+
+set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS A "" B)
+get_property(result DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+message("RESULT1=${result}")
+
+set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+get_property(result DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+message("RESULT2=${result}")
+
+set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS -DBAR)
+get_property(result DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+message("RESULT3=${result}")
diff --git a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
index c1b2227..8dc627d 100644
--- a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
@@ -29,7 +29,7 @@ if (NOT CXX_FEATURES)
   run_cmake(NoSupportedCxxFeatures)
   run_cmake(NoSupportedCxxFeaturesGenex)
 else()
-  if(CXX_STANDARD_DEFAULT)
+  if(CXX_STANDARD_DEFAULT EQUAL 98)
     run_cmake(LinkImplementationFeatureCycle)
   endif()
   run_cmake(LinkImplementationFeatureCycleSolved)
diff --git a/Tests/RunCMake/CompilerLauncher/C-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/C-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/C-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/C-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/C-launch.cmake b/Tests/RunCMake/CompilerLauncher/C-launch.cmake
new file mode 100644
index 0000000..e66ca20
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(C.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/C.cmake b/Tests/RunCMake/CompilerLauncher/C.cmake
new file mode 100644
index 0000000..67bf7c4
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/CompilerLauncher/CMakeLists.txt b/Tests/RunCMake/CompilerLauncher/CMakeLists.txt
new file mode 100644
index 0000000..18dfd26
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CXX-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CXX-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-launch.cmake b/Tests/RunCMake/CompilerLauncher/CXX-launch.cmake
new file mode 100644
index 0000000..3002c9d
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CXX.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CXX.cmake b/Tests/RunCMake/CompilerLauncher/CXX.cmake
new file mode 100644
index 0000000..cdd3478
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX.cmake
@@ -0,0 +1,4 @@
+enable_language(CXX)
+set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.cxx)
diff --git a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
new file mode 100644
index 0000000..5884d5c
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
@@ -0,0 +1,23 @@
+include(RunCMake)
+
+function(run_compiler_launcher lang)
+  # Use a single build tree for tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  run_cmake(${lang})
+
+  set(RunCMake_TEST_OUTPUT_MERGE 1)
+  if("${RunCMake_GENERATOR}" STREQUAL "Ninja")
+    set(verbose_args -- -v)
+  endif()
+  run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
+endfunction()
+
+run_compiler_launcher(C)
+run_compiler_launcher(CXX)
+if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
+  run_compiler_launcher(C-launch)
+  run_compiler_launcher(CXX-launch)
+endif()
diff --git a/Tests/RunCMake/CompilerLauncher/main.c b/Tests/RunCMake/CompilerLauncher/main.c
new file mode 100644
index 0000000..03b2213
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+  return 0;
+}
diff --git a/Tests/RunCMake/CompilerLauncher/main.cxx b/Tests/RunCMake/CompilerLauncher/main.cxx
new file mode 100644
index 0000000..76e8197
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/main.cxx
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-JOM.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-JOM.txt
new file mode 100644
index 0000000..b7db7eb
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-JOM.txt
@@ -0,0 +1,17 @@
+CMake Error at BadCompilerC.cmake:2 \(enable_language\):
+  The CMAKE_C_COMPILER:
+
+    no-C-compiler
+
+  is not a full path and was not found in the PATH.
+
+  To use the JOM generator with Visual C\+\+, cmake must be run from a shell
+  that can use the compiler cl from the command line.  This environment is
+  unable to invoke the cl compiler.  To fix this problem, run cmake from the
+  Visual Studio Command Prompt \(vcvarsall.bat\).
+
+  Tell CMake where to find the compiler by setting either the environment
+  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+  the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-NMake.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-NMake.txt
new file mode 100644
index 0000000..03c5933
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-NMake.txt
@@ -0,0 +1,17 @@
+CMake Error at BadCompilerC.cmake:2 \(enable_language\):
+  The CMAKE_C_COMPILER:
+
+    no-C-compiler
+
+  is not a full path and was not found in the PATH.
+
+  To use the NMake generator with Visual C\+\+, cmake must be run from a shell
+  that can use the compiler cl from the command line.  This environment is
+  unable to invoke the cl compiler.  To fix this problem, run cmake from the
+  Visual Studio Command Prompt \(vcvarsall.bat\).
+
+  Tell CMake where to find the compiler by setting either the environment
+  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+  the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-JOM.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-JOM.txt
new file mode 100644
index 0000000..4b42ea6
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-JOM.txt
@@ -0,0 +1,17 @@
+CMake Error at BadCompilerCXX.cmake:2 \(enable_language\):
+  The CMAKE_CXX_COMPILER:
+
+    no-CXX-compiler
+
+  is not a full path and was not found in the PATH.
+
+  To use the JOM generator with Visual C\+\+, cmake must be run from a shell
+  that can use the compiler cl from the command line.  This environment is
+  unable to invoke the cl compiler.  To fix this problem, run cmake from the
+  Visual Studio Command Prompt \(vcvarsall.bat\).
+
+  Tell CMake where to find the compiler by setting either the environment
+  variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+  to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-NMake.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-NMake.txt
new file mode 100644
index 0000000..1bfcdcc
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-NMake.txt
@@ -0,0 +1,17 @@
+CMake Error at BadCompilerCXX.cmake:2 \(enable_language\):
+  The CMAKE_CXX_COMPILER:
+
+    no-CXX-compiler
+
+  is not a full path and was not found in the PATH.
+
+  To use the NMake generator with Visual C\+\+, cmake must be run from a shell
+  that can use the compiler cl from the command line.  This environment is
+  unable to invoke the cl compiler.  To fix this problem, run cmake from the
+  Visual Studio Command Prompt \(vcvarsall.bat\).
+
+  Tell CMake where to find the compiler by setting either the environment
+  variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+  to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-JOM.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-JOM.txt
new file mode 100644
index 0000000..f25a267
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-JOM.txt
@@ -0,0 +1,35 @@
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+  The CMAKE_C_COMPILER:
+
+    no-C-compiler
+
+  is not a full path and was not found in the PATH.
+
+  To use the JOM generator with Visual C\+\+, cmake must be run from a shell
+  that can use the compiler cl from the command line.  This environment is
+  unable to invoke the cl compiler.  To fix this problem, run cmake from the
+  Visual Studio Command Prompt \(vcvarsall.bat\).
+
+  Tell CMake where to find the compiler by setting either the environment
+  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+  the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+  The CMAKE_CXX_COMPILER:
+
+    no-CXX-compiler
+
+  is not a full path and was not found in the PATH.
+
+  To use the JOM generator with Visual C\+\+, cmake must be run from a shell
+  that can use the compiler cl from the command line.  This environment is
+  unable to invoke the cl compiler.  To fix this problem, run cmake from the
+  Visual Studio Command Prompt \(vcvarsall.bat\).
+
+  Tell CMake where to find the compiler by setting either the environment
+  variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+  to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-NMake.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-NMake.txt
new file mode 100644
index 0000000..ffcdce8
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-NMake.txt
@@ -0,0 +1,35 @@
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+  The CMAKE_C_COMPILER:
+
+    no-C-compiler
+
+  is not a full path and was not found in the PATH.
+
+  To use the NMake generator with Visual C\+\+, cmake must be run from a shell
+  that can use the compiler cl from the command line.  This environment is
+  unable to invoke the cl compiler.  To fix this problem, run cmake from the
+  Visual Studio Command Prompt \(vcvarsall.bat\).
+
+  Tell CMake where to find the compiler by setting either the environment
+  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+  the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+  The CMAKE_CXX_COMPILER:
+
+    no-CXX-compiler
+
+  is not a full path and was not found in the PATH.
+
+  To use the NMake generator with Visual C\+\+, cmake must be run from a shell
+  that can use the compiler cl from the command line.  This environment is
+  unable to invoke the cl compiler.  To fix this problem, run cmake from the
+  Visual Studio Command Prompt \(vcvarsall.bat\).
+
+  Tell CMake where to find the compiler by setting either the environment
+  variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+  to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake b/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake
index 8b84f39..19d149c 100644
--- a/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake
@@ -4,6 +4,20 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode")
   run_cmake(NoCompilerC-IDE)
   run_cmake(NoCompilerCXX-IDE)
   run_cmake(NoCompilerCandCXX-IDE)
+elseif(RunCMake_GENERATOR STREQUAL "NMake Makefiles")
+  set(RunCMake-stderr-file BadCompilerC-stderr-NMake.txt)
+  run_cmake(BadCompilerC)
+  set(RunCMake-stderr-file BadCompilerCXX-stderr-NMake.txt)
+  run_cmake(BadCompilerCXX)
+  set(RunCMake-stderr-file BadCompilerCandCXX-stderr-NMake.txt)
+  run_cmake(BadCompilerCandCXX)
+elseif(RunCMake_GENERATOR STREQUAL "NMake Makefiles JOM")
+  set(RunCMake-stderr-file BadCompilerC-stderr-JOM.txt)
+  run_cmake(BadCompilerC)
+  set(RunCMake-stderr-file BadCompilerCXX-stderr-JOM.txt)
+  run_cmake(BadCompilerCXX)
+  set(RunCMake-stderr-file BadCompilerCandCXX-stderr-JOM.txt)
+  run_cmake(BadCompilerCandCXX)
 else()
   run_cmake(BadCompilerC)
   run_cmake(BadCompilerCXX)
diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
index e038409..47d6129 100644
--- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
@@ -11,3 +11,4 @@ run_cmake(Add_StepDependencies)
 run_cmake(Add_StepDependencies_iface)
 run_cmake(Add_StepDependencies_iface_step)
 run_cmake(Add_StepDependencies_no_target)
+run_cmake(UsesTerminal)
diff --git a/Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake b/Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake
new file mode 100644
index 0000000..201d822
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake
@@ -0,0 +1,97 @@
+cmake_minimum_required(VERSION 3.3)
+
+# If we are using the Ninja generator, we can check and verify that the
+# USES_TERMINAL option actually works by examining the Ninja build file.
+# This is the only way, since CMake doesn't offer a way to examine the
+# options on a custom command after it has been added.  Furthermore,
+# there isn't an easy way to test for this by actually running Ninja.
+#
+# Other generators don't currently support USES_TERMINAL at this time.
+# This file can be improved to support them if they do.  Until then, we
+# simply assume success for new generator types.
+#
+# For Ninja, there is a complication.  If the Ninja generator detects a
+# version of Ninja < 1.5, it won't actually emit the console pool command,
+# because those Ninja versions don't yet support the console pool.  In
+# that case, we also have to assume success.
+
+# Check Ninja build output to verify whether or not a target step is in the
+# console pool.
+macro(CheckNinjaStep _target _step _require)
+  if("${_build}" MATCHES
+"  DESC = Performing ${_step} step for '${_target}'
+  pool = console"
+  )
+    if(NOT ${_require})
+      set(RunCMake_TEST_FAILED "${_target} ${_step} step is in console pool")
+      return()
+    endif()
+  else()
+    if(${_require})
+      set(RunCMake_TEST_FAILED "${_target} ${_step} step not in console pool")
+      return()
+    endif()
+  endif()
+endmacro()
+
+# Check Ninja build output to verify whether each target step is in the
+# console pool.
+macro(CheckNinjaTarget _target
+  _download _update _configure _build _test _install
+  )
+  CheckNinjaStep(${_target} download ${_download})
+  CheckNinjaStep(${_target} update ${_update})
+  CheckNinjaStep(${_target} configure ${_configure})
+  CheckNinjaStep(${_target} build ${_build})
+  CheckNinjaStep(${_target} test ${_test})
+  CheckNinjaStep(${_target} install ${_install})
+endmacro()
+
+# Load build/make file, depending on generator
+if(RunCMake_GENERATOR STREQUAL Ninja)
+  # Check the Ninja version.  If < 1.5, console pool isn't supported and
+  # so the generator would not emit console pool usage.  That would cause
+  # this test to fail.
+  execute_process(COMMAND ${RunCMake_MAKE_PROGRAM} --version
+    RESULT_VARIABLE _version_result
+    OUTPUT_VARIABLE _version
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  if(_version_result OR _version VERSION_EQUAL "0")
+    set(RunCMake_TEST_FAILED "Failed to get Ninja version")
+    return()
+  endif()
+  if(_version VERSION_LESS "1.5")
+    return() # console pool not supported on Ninja < 1.5
+  endif()
+
+  # Read the Ninja build file
+  set(_build_file "${RunCMake_TEST_BINARY_DIR}/build.ninja")
+
+  if(NOT EXISTS "${_build_file}")
+    set(RunCMake_TEST_FAILED "Ninja build file not created")
+    return()
+  endif()
+
+  file(READ "${_build_file}" _build)
+
+  set(_target_check_macro CheckNinjaTarget)
+elseif((RunCMake_GENERATOR STREQUAL "") OR NOT DEFINED RunCMake_GENERATOR)
+  # protection in case somebody renamed RunCMake_GENERATOR
+  set(RunCMake_TEST_FAILED "Unknown generator")
+  return()
+else()
+  # We don't yet know how to test USES_TERMINAL on this generator.
+  return()
+endif()
+
+# Actual tests:
+CheckNinjaTarget(TerminalTest1
+  true  true  true  true  true  true )
+CheckNinjaTarget(TerminalTest2
+  true  false true  false true  false)
+CheckNinjaTarget(TerminalTest3
+  false true  false true  false true )
+CheckNinjaTarget(TerminalTest4
+  false false false false false false)
diff --git a/Tests/RunCMake/ExternalProject/UsesTerminal.cmake b/Tests/RunCMake/ExternalProject/UsesTerminal.cmake
new file mode 100644
index 0000000..cd87403
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/UsesTerminal.cmake
@@ -0,0 +1,45 @@
+if(NOT CMAKE_CONFIGURATION_TYPES)
+  set(CMAKE_BUILD_TYPE Debug)
+endif()
+include(ExternalProject)
+
+# Test various combinations of USES_TERMINAL with ExternalProject_Add.
+
+macro(DoTerminalTest _target)
+  ExternalProject_Add(${_target}
+    DOWNLOAD_COMMAND "${CMAKE_COMMAND}" -E echo "download"
+    UPDATE_COMMAND "${CMAKE_COMMAND}" -E echo "update"
+    CONFIGURE_COMMAND "${CMAKE_COMMAND}" -E echo "configure"
+    BUILD_COMMAND "${CMAKE_COMMAND}" -E echo "build"
+    TEST_COMMAND "${CMAKE_COMMAND}" -E echo "test"
+    INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "install"
+    ${ARGN}
+    )
+endmacro()
+
+# USES_TERMINAL on all steps
+DoTerminalTest(TerminalTest1
+  USES_TERMINAL_DOWNLOAD 1
+  USES_TERMINAL_UPDATE 1
+  USES_TERMINAL_CONFIGURE 1
+  USES_TERMINAL_BUILD 1
+  USES_TERMINAL_TEST 1
+  USES_TERMINAL_INSTALL 1
+  )
+
+# USES_TERMINAL on every other step, starting with download
+DoTerminalTest(TerminalTest2
+  USES_TERMINAL_DOWNLOAD 1
+  USES_TERMINAL_CONFIGURE 1
+  USES_TERMINAL_TEST 1
+  )
+
+# USES_TERMINAL on every other step, starting with update
+DoTerminalTest(TerminalTest3
+  USES_TERMINAL_UPDATE 1
+  USES_TERMINAL_BUILD 1
+  USES_TERMINAL_INSTALL 1
+  )
+
+# USES_TERMINAL on no step
+DoTerminalTest(TerminalTest4)
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE-stdout.txt b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE-stdout.txt
new file mode 100644
index 0000000..5f211eb
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE-stdout.txt
@@ -0,0 +1 @@
+-- g_ir_scanner: .*/g-ir-scanner
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE.cmake
new file mode 100644
index 0000000..c85efaa
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE.cmake
@@ -0,0 +1,9 @@
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GOBJECT_INTROSPECTION QUIET gobject-introspection-1.0)
+
+if (GOBJECT_INTROSPECTION_FOUND)
+  pkg_get_variable(g_ir_scanner gobject-introspection-1.0 g_ir_scanner)
+  message(STATUS "g_ir_scanner: ${g_ir_scanner}")
+else ()
+  message(STATUS "g_ir_scanner: skipping test; gobject-introspection-1.0 not found /g-ir-scanner")
+endif ()
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
index 29301d7..bb04aa2 100644
--- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -9,3 +9,9 @@ if(APPLE)
   run_cmake(FindPkgConfig_CMAKE_FRAMEWORK_PATH)
   run_cmake(FindPkgConfig_CMAKE_APPBUNDLE_PATH)
 endif()
+
+# We need a real pkg-config to run the test for get_variable.
+find_package(PkgConfig)
+if (PKG_CONFIG_FOUND)
+  run_cmake(FindPkgConfig_GET_VARIABLE)
+endif ()
diff --git a/Tests/RunCMake/GNUInstallDirs/CMakeLists.txt b/Tests/RunCMake/GNUInstallDirs/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GNUInstallDirs/Common.cmake b/Tests/RunCMake/GNUInstallDirs/Common.cmake
new file mode 100644
index 0000000..eff2d54
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Common.cmake
@@ -0,0 +1,28 @@
+set(CMAKE_SIZEOF_VOID_P 8)
+set(CMAKE_LIBRARY_ARCHITECTURE "arch")
+if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+  set(CMAKE_SYSTEM_NAME "OpenBSD-Fake")
+endif()
+include(GNUInstallDirs)
+set(dirs
+  BINDIR
+  DATADIR
+  DATAROOTDIR
+  DOCDIR
+  INCLUDEDIR
+  INFODIR
+  LIBDIR
+  LIBEXECDIR
+  LOCALEDIR
+  LOCALSTATEDIR
+  MANDIR
+  SBINDIR
+  SHAREDSTATEDIR
+  SYSCONFDIR
+  )
+foreach(dir ${dirs})
+  message("CMAKE_INSTALL_${dir}='${CMAKE_INSTALL_${dir}}'")
+endforeach()
+foreach(dir ${dirs})
+  message("CMAKE_INSTALL_FULL_${dir}='${CMAKE_INSTALL_FULL_${dir}}'")
+endforeach()
diff --git a/Tests/RunCMake/GNUInstallDirs/Opt-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Opt-stderr.txt
new file mode 100644
index 0000000..aee8552
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Opt-stderr.txt
@@ -0,0 +1,28 @@
+^CMAKE_INSTALL_BINDIR='bin'
+CMAKE_INSTALL_DATADIR='share'
+CMAKE_INSTALL_DATAROOTDIR='share'
+CMAKE_INSTALL_DOCDIR='share/doc/Opt'
+CMAKE_INSTALL_INCLUDEDIR='include'
+CMAKE_INSTALL_INFODIR='share/info'
+CMAKE_INSTALL_LIBDIR='(lib|lib64)'
+CMAKE_INSTALL_LIBEXECDIR='libexec'
+CMAKE_INSTALL_LOCALEDIR='share/locale'
+CMAKE_INSTALL_LOCALSTATEDIR='var'
+CMAKE_INSTALL_MANDIR='share/man'
+CMAKE_INSTALL_SBINDIR='sbin'
+CMAKE_INSTALL_SHAREDSTATEDIR='com'
+CMAKE_INSTALL_SYSCONFDIR='etc'
+CMAKE_INSTALL_FULL_BINDIR='/opt/Opt/bin'
+CMAKE_INSTALL_FULL_DATADIR='/opt/Opt/share'
+CMAKE_INSTALL_FULL_DATAROOTDIR='/opt/Opt/share'
+CMAKE_INSTALL_FULL_DOCDIR='/opt/Opt/share/doc/Opt'
+CMAKE_INSTALL_FULL_INCLUDEDIR='/opt/Opt/include'
+CMAKE_INSTALL_FULL_INFODIR='/opt/Opt/share/info'
+CMAKE_INSTALL_FULL_LIBDIR='/opt/Opt/(lib|lib64)'
+CMAKE_INSTALL_FULL_LIBEXECDIR='/opt/Opt/libexec'
+CMAKE_INSTALL_FULL_LOCALEDIR='/opt/Opt/share/locale'
+CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var/opt/Opt'
+CMAKE_INSTALL_FULL_MANDIR='/opt/Opt/share/man'
+CMAKE_INSTALL_FULL_SBINDIR='/opt/Opt/sbin'
+CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/opt/Opt/com'
+CMAKE_INSTALL_FULL_SYSCONFDIR='/etc/opt/Opt'$
diff --git a/Tests/RunCMake/GNUInstallDirs/Opt.cmake b/Tests/RunCMake/GNUInstallDirs/Opt.cmake
new file mode 100644
index 0000000..49eab0e
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Opt.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_PREFIX "/opt/${PROJECT_NAME}")
+include(Common.cmake)
diff --git a/Tests/RunCMake/GNUInstallDirs/Root-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Root-stderr.txt
new file mode 100644
index 0000000..a95400e
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Root-stderr.txt
@@ -0,0 +1,28 @@
+^CMAKE_INSTALL_BINDIR='usr/bin'
+CMAKE_INSTALL_DATADIR='usr/share'
+CMAKE_INSTALL_DATAROOTDIR='usr/share'
+CMAKE_INSTALL_DOCDIR='usr/share/doc/Root'
+CMAKE_INSTALL_INCLUDEDIR='usr/include'
+CMAKE_INSTALL_INFODIR='usr/share/info'
+CMAKE_INSTALL_LIBDIR='usr/(lib|lib64)'
+CMAKE_INSTALL_LIBEXECDIR='usr/libexec'
+CMAKE_INSTALL_LOCALEDIR='usr/share/locale'
+CMAKE_INSTALL_LOCALSTATEDIR='var'
+CMAKE_INSTALL_MANDIR='usr/share/man'
+CMAKE_INSTALL_SBINDIR='usr/sbin'
+CMAKE_INSTALL_SHAREDSTATEDIR='usr/com'
+CMAKE_INSTALL_SYSCONFDIR='etc'
+CMAKE_INSTALL_FULL_BINDIR='/usr/bin'
+CMAKE_INSTALL_FULL_DATADIR='/usr/share'
+CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/share'
+CMAKE_INSTALL_FULL_DOCDIR='/usr/share/doc/Root'
+CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/include'
+CMAKE_INSTALL_FULL_INFODIR='/usr/share/info'
+CMAKE_INSTALL_FULL_LIBDIR='/usr/(lib|lib64)'
+CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/libexec'
+CMAKE_INSTALL_FULL_LOCALEDIR='/usr/share/locale'
+CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var'
+CMAKE_INSTALL_FULL_MANDIR='/usr/share/man'
+CMAKE_INSTALL_FULL_SBINDIR='/usr/sbin'
+CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/usr/com'
+CMAKE_INSTALL_FULL_SYSCONFDIR='/etc'$
diff --git a/Tests/RunCMake/GNUInstallDirs/Root.cmake b/Tests/RunCMake/GNUInstallDirs/Root.cmake
new file mode 100644
index 0000000..f8cc641
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Root.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_PREFIX "/")
+include(Common.cmake)
diff --git a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
new file mode 100644
index 0000000..f88569a
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(Opt)
+run_cmake(Root)
+run_cmake(Usr)
+run_cmake(UsrLocal)
diff --git a/Tests/RunCMake/GNUInstallDirs/Usr-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Usr-stderr.txt
new file mode 100644
index 0000000..e10c4c5
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Usr-stderr.txt
@@ -0,0 +1,28 @@
+^CMAKE_INSTALL_BINDIR='bin'
+CMAKE_INSTALL_DATADIR='share'
+CMAKE_INSTALL_DATAROOTDIR='share'
+CMAKE_INSTALL_DOCDIR='share/doc/Usr'
+CMAKE_INSTALL_INCLUDEDIR='include'
+CMAKE_INSTALL_INFODIR='share/info'
+CMAKE_INSTALL_LIBDIR='(lib|lib64|lib/arch)'
+CMAKE_INSTALL_LIBEXECDIR='libexec'
+CMAKE_INSTALL_LOCALEDIR='share/locale'
+CMAKE_INSTALL_LOCALSTATEDIR='var'
+CMAKE_INSTALL_MANDIR='share/man'
+CMAKE_INSTALL_SBINDIR='sbin'
+CMAKE_INSTALL_SHAREDSTATEDIR='com'
+CMAKE_INSTALL_SYSCONFDIR='etc'
+CMAKE_INSTALL_FULL_BINDIR='/usr/bin'
+CMAKE_INSTALL_FULL_DATADIR='/usr/share'
+CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/share'
+CMAKE_INSTALL_FULL_DOCDIR='/usr/share/doc/Usr'
+CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/include'
+CMAKE_INSTALL_FULL_INFODIR='/usr/share/info'
+CMAKE_INSTALL_FULL_LIBDIR='/usr/(lib|lib64|lib/arch)'
+CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/libexec'
+CMAKE_INSTALL_FULL_LOCALEDIR='/usr/share/locale'
+CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var'
+CMAKE_INSTALL_FULL_MANDIR='/usr/share/man'
+CMAKE_INSTALL_FULL_SBINDIR='/usr/sbin'
+CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/usr/com'
+CMAKE_INSTALL_FULL_SYSCONFDIR='/etc'$
diff --git a/Tests/RunCMake/GNUInstallDirs/Usr.cmake b/Tests/RunCMake/GNUInstallDirs/Usr.cmake
new file mode 100644
index 0000000..62b7288
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Usr.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_PREFIX "/usr")
+include(Common.cmake)
diff --git a/Tests/RunCMake/GNUInstallDirs/UsrLocal-stderr.txt b/Tests/RunCMake/GNUInstallDirs/UsrLocal-stderr.txt
new file mode 100644
index 0000000..8dcf25b
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/UsrLocal-stderr.txt
@@ -0,0 +1,28 @@
+^CMAKE_INSTALL_BINDIR='bin'
+CMAKE_INSTALL_DATADIR='share'
+CMAKE_INSTALL_DATAROOTDIR='share'
+CMAKE_INSTALL_DOCDIR='share/doc/UsrLocal'
+CMAKE_INSTALL_INCLUDEDIR='include'
+CMAKE_INSTALL_INFODIR='share/info'
+CMAKE_INSTALL_LIBDIR='(lib|lib64)'
+CMAKE_INSTALL_LIBEXECDIR='libexec'
+CMAKE_INSTALL_LOCALEDIR='share/locale'
+CMAKE_INSTALL_LOCALSTATEDIR='var'
+CMAKE_INSTALL_MANDIR='share/man'
+CMAKE_INSTALL_SBINDIR='sbin'
+CMAKE_INSTALL_SHAREDSTATEDIR='com'
+CMAKE_INSTALL_SYSCONFDIR='etc'
+CMAKE_INSTALL_FULL_BINDIR='/usr/local/bin'
+CMAKE_INSTALL_FULL_DATADIR='/usr/local/share'
+CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/local/share'
+CMAKE_INSTALL_FULL_DOCDIR='/usr/local/share/doc/UsrLocal'
+CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/local/include'
+CMAKE_INSTALL_FULL_INFODIR='/usr/local/share/info'
+CMAKE_INSTALL_FULL_LIBDIR='/usr/local/(lib|lib64)'
+CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/local/libexec'
+CMAKE_INSTALL_FULL_LOCALEDIR='/usr/local/share/locale'
+CMAKE_INSTALL_FULL_LOCALSTATEDIR='/usr/local/var'
+CMAKE_INSTALL_FULL_MANDIR='/usr/local/share/man'
+CMAKE_INSTALL_FULL_SBINDIR='/usr/local/sbin'
+CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/usr/local/com'
+CMAKE_INSTALL_FULL_SYSCONFDIR='/usr/local/etc'$
diff --git a/Tests/RunCMake/GNUInstallDirs/UsrLocal.cmake b/Tests/RunCMake/GNUInstallDirs/UsrLocal.cmake
new file mode 100644
index 0000000..59d9331
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/UsrLocal.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_PREFIX "/usr/local")
+include(Common.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-result.txt b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-stderr.txt
new file mode 100644
index 0000000..8d3c4cc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-stderr.txt
@@ -0,0 +1,17 @@
+CMake Error at BadSHELL_PATH.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<SHELL_PATH:>
+
+  "" is not an absolute path.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at BadSHELL_PATH.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<SHELL_PATH:Relative/Path>
+
+  "Relative/Path" is not an absolute path.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH.cmake b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH.cmake
new file mode 100644
index 0000000..5eff7bc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH.cmake
@@ -0,0 +1,4 @@
+add_custom_target(check ALL COMMAND check
+  $<SHELL_PATH:>
+  $<SHELL_PATH:Relative/Path>
+  VERBATIM)
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-result.txt b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-stderr.txt b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-stderr.txt
new file mode 100644
index 0000000..d915ecb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at ImportedTarget-TARGET_PDB_FILE.cmake:2 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<TARGET_PDB_FILE:empty>
+
+  TARGET_PDB_FILE not allowed for IMPORTED targets.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE.cmake b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE.cmake
new file mode 100644
index 0000000..c55c5d5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE.cmake
@@ -0,0 +1,2 @@
+add_library(empty UNKNOWN IMPORTED)
+add_custom_target(custom COMMAND echo $<TARGET_PDB_FILE:empty>)
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt
new file mode 100644
index 0000000..bf592e7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at OUTPUT_NAME-recursion.cmake:[0-9]+ \(add_executable\):
+  Target 'empty1' OUTPUT_NAME depends on itself.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake
new file mode 100644
index 0000000..5cb8050
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_executable(empty1 empty.c)
+set_property(TARGET empty1 PROPERTY OUTPUT_NAME $<TARGET_FILE_NAME:empty1>)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 1c8fab5..45175d8 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -10,6 +10,7 @@ run_cmake(BadTargetName)
 run_cmake(BadTargetTypeInterface)
 run_cmake(BadTargetTypeObject)
 run_cmake(BadInstallPrefix)
+run_cmake(BadSHELL_PATH)
 run_cmake(CMP0044-WARN)
 run_cmake(NonValidTarget-C_COMPILER_ID)
 run_cmake(NonValidTarget-CXX_COMPILER_ID)
@@ -25,7 +26,10 @@ run_cmake(COMPILE_LANGUAGE-add_executable)
 run_cmake(COMPILE_LANGUAGE-add_library)
 run_cmake(COMPILE_LANGUAGE-add_test)
 run_cmake(COMPILE_LANGUAGE-unknown-lang)
+run_cmake(TARGET_FILE-recursion)
+run_cmake(OUTPUT_NAME-recursion)
 
+run_cmake(ImportedTarget-TARGET_PDB_FILE)
 if(LINKER_SUPPORTS_PDB)
   run_cmake(NonValidTarget-TARGET_PDB_FILE)
   run_cmake(ValidTarget-TARGET_PDB_FILE)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-stderr.txt
new file mode 100644
index 0000000..5b15526
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at TARGET_FILE-recursion.cmake:[0-9]+ \(add_executable\):
+  Target 'empty1' OUTPUT_DIRECTORY depends on itself.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake
new file mode 100644
index 0000000..e780103
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+add_executable(empty1 empty.c)
+set_property(TARGET empty1 PROPERTY OUTPUT_NAME $<TARGET_FILE_NAME:empty1>)
+set_property(TARGET empty1 PROPERTY RUNTIME_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:empty1>)
diff --git a/Tests/RunCMake/Languages/DetermineFail-result.txt b/Tests/RunCMake/Languages/DetermineFail-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Languages/DetermineFail-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Languages/DetermineFail-stderr.txt b/Tests/RunCMake/Languages/DetermineFail-stderr.txt
new file mode 100644
index 0000000..3b4743e
--- /dev/null
+++ b/Tests/RunCMake/Languages/DetermineFail-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at Modules/CMakeDetermineFailCompiler.cmake:[0-9]+ \(message\):
+  This language is not supported.
+Call Stack \(most recent call first\):
+  DetermineFail.cmake:[0-9]+ \(enable_language\)
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Languages/DetermineFail.cmake b/Tests/RunCMake/Languages/DetermineFail.cmake
new file mode 100644
index 0000000..3c8d17d
--- /dev/null
+++ b/Tests/RunCMake/Languages/DetermineFail.cmake
@@ -0,0 +1,2 @@
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Modules)
+enable_language(Fail)
diff --git a/Tests/RunCMake/Languages/Modules/CMakeDetermineFailCompiler.cmake b/Tests/RunCMake/Languages/Modules/CMakeDetermineFailCompiler.cmake
new file mode 100644
index 0000000..3b2d50a
--- /dev/null
+++ b/Tests/RunCMake/Languages/Modules/CMakeDetermineFailCompiler.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This language is not supported.")
diff --git a/Tests/RunCMake/Languages/RunCMakeTest.cmake b/Tests/RunCMake/Languages/RunCMakeTest.cmake
index 6517a81..732baae 100644
--- a/Tests/RunCMake/Languages/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Languages/RunCMakeTest.cmake
@@ -4,3 +4,5 @@ run_cmake(NoLangSHARED)
 run_cmake(LINK_LANGUAGE-genex)
 run_cmake(link-libraries-TARGET_FILE-genex)
 run_cmake(link-libraries-TARGET_FILE-genex-ok)
+
+run_cmake(DetermineFail)
diff --git a/Tests/RunCMake/LinkStatic/CMakeLists.txt b/Tests/RunCMake/LinkStatic/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/LinkStatic/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/LinkStatic/LINK_SEARCH_STATIC.cmake b/Tests/RunCMake/LinkStatic/LINK_SEARCH_STATIC.cmake
new file mode 100644
index 0000000..6db5c85
--- /dev/null
+++ b/Tests/RunCMake/LinkStatic/LINK_SEARCH_STATIC.cmake
@@ -0,0 +1,73 @@
+enable_language(C)
+
+set(CMAKE_LINK_SEARCH_START_STATIC ON)
+add_executable(LinkSearchStartStaticInit1 LinkStatic.c)
+get_target_property(LSSS LinkSearchStartStaticInit1
+  LINK_SEARCH_START_STATIC)
+if(NOT LSSS)
+  message(FATAL_ERROR "Failed to correctly initialize LINK_SEARCH_START_STATIC")
+endif()
+unset(CMAKE_LINK_SEARCH_START_STATIC)
+
+add_executable(LinkSearchStartStaticSet1 LinkStatic.c)
+set_target_properties(LinkSearchStartStaticSet1 PROPERTIES
+  LINK_SEARCH_START_STATIC ON)
+get_target_property(LSSS LinkSearchStartStaticSet1
+  LINK_SEARCH_START_STATIC)
+if(NOT LSSS)
+  message(FATAL_ERROR "Failed to correctly set LINK_SEARCH_START_STATIC")
+endif()
+
+set(CMAKE_LINK_SEARCH_START_STATIC OFF)
+add_executable(LinkSearchStartStaticInit2 LinkStatic.c)
+get_target_property(LSSS LinkSearchStartStaticInit2
+  LINK_SEARCH_START_STATIC)
+if(LSSS)
+  message(FATAL_ERROR "Failed to correctly initialize LINK_SEARCH_START_STATIC")
+endif()
+unset(CMAKE_LINK_SEARCH_START_STATIC)
+
+add_executable(LinkSearchStartStaticSet2 LinkStatic.c)
+set_target_properties(LinkSearchStartStaticSet2 PROPERTIES
+  LINK_SEARCH_START_STATIC OFF)
+get_target_property(LSSS LinkSearchStartStaticSet2
+  LINK_SEARCH_START_STATIC)
+if(LSSS)
+  message(FATAL_ERROR "Failed to correctly set LINK_SEARCH_START_STATIC")
+endif()
+
+set(CMAKE_LINK_SEARCH_END_STATIC ON)
+add_executable(LinkSearchEndStaticInit1 LinkStatic.c)
+get_target_property(LSES LinkSearchEndStaticInit1
+  LINK_SEARCH_END_STATIC)
+if(NOT LSES)
+  message(FATAL_ERROR "Failed to correctly initialize LINK_SEARCH_END_STATIC")
+endif()
+unset(CMAKE_LINK_SEARCH_END_STATIC)
+
+add_executable(LinkSearchEndStaticSet1 LinkStatic.c)
+set_target_properties(LinkSearchEndStaticSet1 PROPERTIES
+  LINK_SEARCH_END_STATIC ON)
+get_target_property(LSSS LinkSearchEndStaticSet1
+  LINK_SEARCH_END_STATIC)
+if(NOT LSSS)
+  message(FATAL_ERROR "Failed to correctly set LINK_SEARCH_END_STATIC")
+endif()
+
+set(CMAKE_LINK_SEARCH_END_STATIC OFF)
+add_executable(LinkSearchEndStaticInit2 LinkStatic.c)
+get_target_property(LSES LinkSearchEndStaticInit2
+  LINK_SEARCH_END_STATIC)
+if(LSES)
+  message(FATAL_ERROR "Failed to correctly initialize LINK_SEARCH_END_STATIC")
+endif()
+unset(CMAKE_LINK_SEARCH_END_STATIC)
+
+add_executable(LinkSearchEndStaticSet2 LinkStatic.c)
+set_target_properties(LinkSearchEndStaticSet2 PROPERTIES
+  LINK_SEARCH_END_STATIC ON)
+get_target_property(LSSS LinkSearchEndStaticSet2
+  LINK_SEARCH_END_STATIC)
+if(NOT LSSS)
+  message(FATAL_ERROR "Failed to correctly set LINK_SEARCH_END_STATIC")
+endif()
diff --git a/Tests/RunCMake/LinkStatic/LinkStatic.c b/Tests/RunCMake/LinkStatic/LinkStatic.c
new file mode 100644
index 0000000..3600977
--- /dev/null
+++ b/Tests/RunCMake/LinkStatic/LinkStatic.c
@@ -0,0 +1,5 @@
+#include <math.h>
+int main(void)
+{
+  return (int)sin(0);
+}
diff --git a/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake b/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake
new file mode 100644
index 0000000..0d29492
--- /dev/null
+++ b/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(LINK_SEARCH_STATIC)
diff --git a/Tests/RunCMake/Make/CMakeLists.txt b/Tests/RunCMake/Make/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/Make/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake
new file mode 100644
index 0000000..c6bbd03
--- /dev/null
+++ b/Tests/RunCMake/Make/RunCMakeTest.cmake
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+function(run_TargetMessages case)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TargetMessages-${case}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  set(RunCMake_TEST_OPTIONS "${ARGN}")
+  run_cmake(TargetMessages-${case})
+  run_cmake_command(TargetMessages-${case}-build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+run_TargetMessages(ON)
+run_TargetMessages(OFF)
+
+run_TargetMessages(VAR-ON -DCMAKE_TARGET_MESSAGES=ON)
+run_TargetMessages(VAR-OFF -DCMAKE_TARGET_MESSAGES=OFF)
diff --git a/Tests/RunCMake/Make/TargetMessages-OFF-build-stdout.txt b/Tests/RunCMake/Make/TargetMessages-OFF-build-stdout.txt
new file mode 100644
index 0000000..77a582a
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-OFF-build-stdout.txt
@@ -0,0 +1,5 @@
+^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*
+)*Scanning dependencies of target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*$
diff --git a/Tests/RunCMake/Make/TargetMessages-OFF.cmake b/Tests/RunCMake/Make/TargetMessages-OFF.cmake
new file mode 100644
index 0000000..8f5d52c
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-OFF.cmake
@@ -0,0 +1,2 @@
+set_property(GLOBAL PROPERTY TARGET_MESSAGES OFF)
+add_custom_target(CustomTarget ALL)
diff --git a/Tests/RunCMake/Make/TargetMessages-ON-build-stdout.txt b/Tests/RunCMake/Make/TargetMessages-ON-build-stdout.txt
new file mode 100644
index 0000000..a827624
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-ON-build-stdout.txt
@@ -0,0 +1,8 @@
+^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*
+)*Scanning dependencies of target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*
+Built target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*$
diff --git a/Tests/RunCMake/Make/TargetMessages-ON.cmake b/Tests/RunCMake/Make/TargetMessages-ON.cmake
new file mode 100644
index 0000000..e0a5f2b
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-ON.cmake
@@ -0,0 +1,2 @@
+set_property(GLOBAL PROPERTY TARGET_MESSAGES ON)
+add_custom_target(CustomTarget ALL)
diff --git a/Tests/RunCMake/Make/TargetMessages-VAR-OFF-build-stdout.txt b/Tests/RunCMake/Make/TargetMessages-VAR-OFF-build-stdout.txt
new file mode 100644
index 0000000..77a582a
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-VAR-OFF-build-stdout.txt
@@ -0,0 +1,5 @@
+^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*
+)*Scanning dependencies of target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*$
diff --git a/Tests/RunCMake/Make/TargetMessages-VAR-OFF.cmake b/Tests/RunCMake/Make/TargetMessages-VAR-OFF.cmake
new file mode 100644
index 0000000..f278132
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-VAR-OFF.cmake
@@ -0,0 +1 @@
+add_custom_target(CustomTarget ALL)
diff --git a/Tests/RunCMake/Make/TargetMessages-VAR-ON-build-stdout.txt b/Tests/RunCMake/Make/TargetMessages-VAR-ON-build-stdout.txt
new file mode 100644
index 0000000..a827624
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-VAR-ON-build-stdout.txt
@@ -0,0 +1,8 @@
+^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*
+)*Scanning dependencies of target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*
+Built target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*$
diff --git a/Tests/RunCMake/Make/TargetMessages-VAR-ON.cmake b/Tests/RunCMake/Make/TargetMessages-VAR-ON.cmake
new file mode 100644
index 0000000..f278132
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-VAR-ON.cmake
@@ -0,0 +1 @@
+add_custom_target(CustomTarget ALL)
diff --git a/Tests/RunCMake/PolicyScope/CMakeLists.txt b/Tests/RunCMake/PolicyScope/CMakeLists.txt
new file mode 100644
index 0000000..667561e
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/PolicyScope/RunCMakeTest.cmake b/Tests/RunCMake/PolicyScope/RunCMakeTest.cmake
new file mode 100644
index 0000000..d6c021f
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/RunCMakeTest.cmake
@@ -0,0 +1,4 @@
+include(RunCMake)
+
+run_cmake(parent-dir-generate-time)
+run_cmake(dir-in-macro-generate-time)
diff --git a/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-result.txt b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-stderr.txt b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-stderr.txt
new file mode 100644
index 0000000..d223f42
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at dir1/CMakeLists.txt:5 \(target_compile_definitions\):
+  Policy CMP0044 is not set: Case sensitive <LANG>_COMPILER_ID generator
+  expressions.  Run "cmake --help-policy CMP0044" for policy details.  Use
+  the cmake_policy command to set the policy and suppress this warning.
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time.cmake b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time.cmake
new file mode 100644
index 0000000..04a7c2c
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time.cmake
@@ -0,0 +1,2 @@
+
+include(dir-in-macro-include.cmake)
diff --git a/Tests/RunCMake/PolicyScope/dir-in-macro-include.cmake b/Tests/RunCMake/PolicyScope/dir-in-macro-include.cmake
new file mode 100644
index 0000000..fd326f1
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir-in-macro-include.cmake
@@ -0,0 +1,6 @@
+
+enable_language(CXX)
+
+# This does not affect dir1 despite being set before the add_subdirectory.
+cmake_policy(SET CMP0044 NEW)
+add_subdirectory(dir1)
diff --git a/Tests/RunCMake/PolicyScope/dir1/CMakeLists.txt b/Tests/RunCMake/PolicyScope/dir1/CMakeLists.txt
new file mode 100644
index 0000000..16bcb36
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir1/CMakeLists.txt
@@ -0,0 +1,5 @@
+
+
+add_library(foo STATIC foo.cpp)
+string(TOLOWER ${CMAKE_CXX_COMPILER_ID} compiler_id)
+target_compile_definitions(foo PRIVATE Foo=$<CXX_COMPILER_ID:${compiler_id}>)
diff --git a/Tests/RunCMake/PolicyScope/dir1/foo.cpp b/Tests/RunCMake/PolicyScope/dir1/foo.cpp
new file mode 100644
index 0000000..766b775
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir1/foo.cpp
@@ -0,0 +1,5 @@
+
+int main()
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/PolicyScope/parent-dir-generate-time-result.txt b/Tests/RunCMake/PolicyScope/parent-dir-generate-time-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/parent-dir-generate-time-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/PolicyScope/parent-dir-generate-time.cmake b/Tests/RunCMake/PolicyScope/parent-dir-generate-time.cmake
new file mode 100644
index 0000000..a0842f7
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/parent-dir-generate-time.cmake
@@ -0,0 +1,7 @@
+
+enable_language(CXX)
+
+add_subdirectory(dir1)
+
+# This affects dir1 despite being set after the add_subdirectory.
+cmake_policy(SET CMP0044 NEW)
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index 70c0d6c..db9911d 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -66,6 +66,11 @@ function(run_cmake test)
   else()
     set(actual_stderr_var actual_stderr)
   endif()
+  if(DEFINED RunCMake_TEST_TIMEOUT)
+    set(maybe_timeout TIMEOUT ${RunCMake_TEST_TIMEOUT})
+  else()
+    set(maybe_timeout "")
+  endif()
   if(RunCMake_TEST_COMMAND)
     execute_process(
       COMMAND ${RunCMake_TEST_COMMAND}
@@ -73,6 +78,7 @@ function(run_cmake test)
       OUTPUT_VARIABLE actual_stdout
       ERROR_VARIABLE ${actual_stderr_var}
       RESULT_VARIABLE actual_result
+      ${maybe_timeout}
       )
   else()
     execute_process(
@@ -87,6 +93,7 @@ function(run_cmake test)
       OUTPUT_VARIABLE actual_stdout
       ERROR_VARIABLE ${actual_stderr_var}
       RESULT_VARIABLE actual_result
+      ${maybe_timeout}
       )
   endif()
   set(msg "")
@@ -95,7 +102,7 @@ function(run_cmake test)
   endif()
   foreach(o out err)
     string(REGEX REPLACE "\r\n" "\n" actual_std${o} "${actual_std${o}}")
-    string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
+    string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned|[^\n]*from Time Machine by path|[^\n]*Bullseye Testing Technology)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
     string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}")
     set(expect_${o} "")
     if(DEFINED expect_std${o})
@@ -108,7 +115,11 @@ function(run_cmake test)
     endif()
   endforeach()
   unset(RunCMake_TEST_FAILED)
-  include(${top_src}/${test}-check.cmake OPTIONAL)
+  if(RunCMake-check-file AND EXISTS ${top_src}/${RunCMake-check-file})
+    include(${top_src}/${RunCMake-check-file})
+  else()
+    include(${top_src}/${test}-check.cmake OPTIONAL)
+  endif()
   if(RunCMake_TEST_FAILED)
     set(msg "${RunCMake_TEST_FAILED}\n${msg}")
   endif()
diff --git a/Tests/RunCMake/Swift/CMakeLists.txt b/Tests/RunCMake/Swift/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Swift/NotSupported-result.txt b/Tests/RunCMake/Swift/NotSupported-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Swift/NotSupported-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Swift/NotSupported-stderr.txt b/Tests/RunCMake/Swift/NotSupported-stderr.txt
new file mode 100644
index 0000000..9a9c23f
--- /dev/null
+++ b/Tests/RunCMake/Swift/NotSupported-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/CMakeDetermineSwiftCompiler.cmake:[0-9]+ \(message\):
+  Swift language not supported by "[^"]*" generator
+Call Stack \(most recent call first\):
+  NotSupported.cmake:[0-9]+ \(enable_language\)
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Swift/NotSupported.cmake b/Tests/RunCMake/Swift/NotSupported.cmake
new file mode 100644
index 0000000..19f297a
--- /dev/null
+++ b/Tests/RunCMake/Swift/NotSupported.cmake
@@ -0,0 +1 @@
+enable_language(Swift)
diff --git a/Tests/RunCMake/Swift/RunCMakeTest.cmake b/Tests/RunCMake/Swift/RunCMakeTest.cmake
new file mode 100644
index 0000000..4864295
--- /dev/null
+++ b/Tests/RunCMake/Swift/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+if(RunCMake_GENERATOR STREQUAL Xcode)
+  if(XCODE_BELOW_6_1)
+    run_cmake(XcodeTooOld)
+  endif()
+else()
+  run_cmake(NotSupported)
+endif()
diff --git a/Tests/RunCMake/Swift/XcodeTooOld-result.txt b/Tests/RunCMake/Swift/XcodeTooOld-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Swift/XcodeTooOld-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt b/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt
new file mode 100644
index 0000000..8d18f29
--- /dev/null
+++ b/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/CMakeDetermineSwiftCompiler.cmake:[0-9]+ \(message\):
+  Swift language not supported by Xcode [0-9.]+
+Call Stack \(most recent call first\):
+  XcodeTooOld.cmake:[0-9]+ \(enable_language\)
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Swift/XcodeTooOld.cmake b/Tests/RunCMake/Swift/XcodeTooOld.cmake
new file mode 100644
index 0000000..19f297a
--- /dev/null
+++ b/Tests/RunCMake/Swift/XcodeTooOld.cmake
@@ -0,0 +1 @@
+enable_language(Swift)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt
index b3f1e47..a845ffb 100644
--- a/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BOM-UTF-16-BE.cmake:
   File
 
     .*/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake
 
   starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt
index c08c902..cc4244b 100644
--- a/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BOM-UTF-16-LE.cmake:
   File
 
     .*/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake
 
   starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt
index 5dde4e3..5f851bf 100644
--- a/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BOM-UTF-32-BE.cmake:
   File
 
     .*/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake
 
   starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt
index eb054ec..d8fafd0 100644
--- a/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BOM-UTF-32-LE.cmake:
   File
 
     .*/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake
 
   starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt
index afd91f9..a288280 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace0.cmake:
   Syntax Error in cmake code at
 
     .*/Tests/RunCMake/Syntax/BracketNoSpace0.cmake:1:27
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt
index 826e511..391e11b 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace1.cmake:
   Syntax Error in cmake code at
 
     .*/Tests/RunCMake/Syntax/BracketNoSpace1.cmake:1:24
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt
index 23ecdcd..acaf7fe 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace2.cmake:
   Syntax Error in cmake code at
 
     .*/Tests/RunCMake/Syntax/BracketNoSpace2.cmake:1:44
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt
index 906d6fc..f12b2e5 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace3.cmake:
   Syntax Error in cmake code at
 
     .*/Tests/RunCMake/Syntax/BracketNoSpace3.cmake:1:45
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt
index a461e93..7157763 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace4.cmake:
   Syntax Error in cmake code at
 
     .*/Tests/RunCMake/Syntax/BracketNoSpace4.cmake:1:44
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt
index ff8bf1c..c13969d 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace5.cmake:
   Syntax Error in cmake code at
 
     .*/Tests/RunCMake/Syntax/BracketNoSpace5.cmake:1:45
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/ParenInENV-stderr.txt b/Tests/RunCMake/Syntax/ParenInENV-stderr.txt
index 7ecfe11..37c5d6e 100644
--- a/Tests/RunCMake/Syntax/ParenInENV-stderr.txt
+++ b/Tests/RunCMake/Syntax/ParenInENV-stderr.txt
@@ -1,9 +1,11 @@
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in ParenInENV.cmake:
   Syntax Warning in cmake code at
 
     .*/Tests/RunCMake/Syntax/ParenInENV.cmake:2:21
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.
 
 CMake Error at ParenInENV.cmake:2 \(message\):
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt b/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt
index 64ef8b1..45b2e6a 100644
--- a/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt
+++ b/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt
@@ -1,22 +1,28 @@
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in ParenNoSpace1.cmake:
   Syntax Warning in cmake code at
 
     .*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:1:26
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.
 
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in ParenNoSpace1.cmake:
   Syntax Warning in cmake code at
 
     .*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:2:26
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.
 
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in ParenNoSpace1.cmake:
   Syntax Error in cmake code at
 
     .*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:3:29
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt b/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
index 89c2d2a..a4ec6e7 100644
--- a/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
+++ b/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
@@ -1,17 +1,21 @@
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in StringNoSpace.cmake:
   Syntax Warning in cmake code at
 
     .*/Tests/RunCMake/Syntax/StringNoSpace.cmake:2:28
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.
 
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in StringNoSpace.cmake:
   Syntax Warning in cmake code at
 
     .*/Tests/RunCMake/Syntax/StringNoSpace.cmake:2:31
 
   Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.
 
 \[1 \${var} \\n 4\]
diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
index d0aa995..57047fb 100644
--- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
+++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
@@ -19,6 +19,7 @@
    \* CMP0052
    \* CMP0060
    \* CMP0063
+   \* CMP0065
 
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index b7de614..8ab618b 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -7,3 +7,55 @@ run_cmake(XcodeObjectNeedsQuote)
 if (NOT XCODE_VERSION VERSION_LESS 6)
   run_cmake(XcodePlatformFrameworks)
 endif()
+
+# Use a single build tree for a few tests without cleaning.
+
+if(NOT XCODE_VERSION VERSION_LESS 5)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeInstallIOS-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_BINARY_DIR}/ios_install")
+
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(XcodeInstallIOS)
+  run_cmake_command(XcodeInstallIOS-install ${CMAKE_COMMAND} --build . --target install)
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+  unset(RunCMake_TEST_OPTIONS)
+
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeBundlesOSX-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_OPTIONS "-DTEST_IOS=OFF")
+
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(XcodeBundles)
+  run_cmake_command(XcodeBundles-build ${CMAKE_COMMAND} --build .)
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+  unset(RunCMake_TEST_OPTIONS)
+
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeBundlesIOS-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_OPTIONS "-DTEST_IOS=ON")
+
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(XcodeBundles)
+  run_cmake_command(XcodeBundles-build ${CMAKE_COMMAND} --build .)
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+  unset(RunCMake_TEST_OPTIONS)
+endif()
+
+if(NOT XCODE_VERSION VERSION_LESS 7)
+  set(RunCMake_TEST_OPTIONS "-DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/osx.cmake")
+  run_cmake(XcodeTbdStub)
+  unset(RunCMake_TEST_OPTIONS)
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeBundles.cmake b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
new file mode 100644
index 0000000..2cbccfa
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
@@ -0,0 +1,45 @@
+# check if Xcode and CMake have the same understanding of Bundle layout
+
+cmake_minimum_required(VERSION 3.3)
+enable_language(C)
+
+if(TEST_IOS)
+  set(CMAKE_OSX_SYSROOT iphoneos)
+  set(CMAKE_OSX_ARCHITECTURES "armv7")
+  set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+  set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+endif(TEST_IOS)
+
+# App Bundle
+
+add_executable(AppBundle MACOSX_BUNDLE main.m)
+
+add_custom_target(AppBundleTest ALL
+  COMMAND ${CMAKE_COMMAND} -E copy
+    "$<TARGET_FILE:AppBundle>" "$<TARGET_FILE:AppBundle>.old")
+
+add_dependencies(AppBundleTest AppBundle)
+
+# Framework (not supported for iOS on Xcode < 6)
+
+if(NOT TEST_IOS OR NOT XCODE_VERSION VERSION_LESS 6)
+  add_library(Framework SHARED main.c)
+  set_target_properties(Framework PROPERTIES FRAMEWORK TRUE)
+
+  add_custom_target(FrameworkTest ALL
+    COMMAND ${CMAKE_COMMAND} -E copy
+      "$<TARGET_FILE:Framework>" "$<TARGET_FILE:Framework>.old")
+
+  add_dependencies(FrameworkTest Framework)
+endif()
+
+# Bundle
+
+add_library(Bundle MODULE main.c)
+set_target_properties(Bundle PROPERTIES BUNDLE TRUE)
+
+add_custom_target(BundleTest ALL
+  COMMAND ${CMAKE_COMMAND} -E copy
+    "$<TARGET_FILE:Bundle>" "$<TARGET_FILE:Bundle>.old")
+
+add_dependencies(BundleTest Bundle)
diff --git a/Tests/RunCMake/XcodeProject/XcodeInstallIOS-install-stdout.txt b/Tests/RunCMake/XcodeProject/XcodeInstallIOS-install-stdout.txt
new file mode 100644
index 0000000..f2478be
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeInstallIOS-install-stdout.txt
@@ -0,0 +1,2 @@
+-- Install configuration: .*
+-- Installing: .*/ios_install/lib/libfoo.a
diff --git a/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake b/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
new file mode 100644
index 0000000..a797410
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 2.8.5)
+
+project(XcodeInstallIOS)
+
+set(CMAKE_OSX_SYSROOT iphoneos)
+set(XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+
+set(CMAKE_OSX_ARCHITECTURES "armv7;i386")
+
+add_library(foo STATIC foo.cpp)
+install(TARGETS foo ARCHIVE DESTINATION lib)
diff --git a/Tests/RunCMake/XcodeProject/XcodeTbdStub-stdout.txt b/Tests/RunCMake/XcodeProject/XcodeTbdStub-stdout.txt
new file mode 100644
index 0000000..9d9e143
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeTbdStub-stdout.txt
@@ -0,0 +1 @@
+.*/libz\.tbd.*
diff --git a/Tests/RunCMake/XcodeProject/XcodeTbdStub.cmake b/Tests/RunCMake/XcodeProject/XcodeTbdStub.cmake
new file mode 100644
index 0000000..e83d7f3
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeTbdStub.cmake
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 3.3)
+find_package(ZLIB REQUIRED)
diff --git a/Tests/RunCMake/XcodeProject/foo.cpp b/Tests/RunCMake/XcodeProject/foo.cpp
new file mode 100644
index 0000000..2fb55ee
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/foo.cpp
@@ -0,0 +1 @@
+void foo() { }
diff --git a/Tests/RunCMake/XcodeProject/main.m b/Tests/RunCMake/XcodeProject/main.m
new file mode 100644
index 0000000..6dc190a
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/main.m
@@ -0,0 +1,3 @@
+int main(int argc, const char * argv[]) {
+    return 1;
+}
diff --git a/Tests/RunCMake/XcodeProject/osx.cmake b/Tests/RunCMake/XcodeProject/osx.cmake
new file mode 100644
index 0000000..e021fcd
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/osx.cmake
@@ -0,0 +1,18 @@
+set(CMAKE_SYSTEM_NAME Darwin)
+set(CMAKE_SYSTEM_VERSION 1)
+set(UNIX True)
+set(APPLE True)
+
+find_program(XCRUN_EXECUTABLE xcrun)
+if(NOT XCRUN_EXECUTABLE)
+  message(FATAL_ERROR "xcrun not found")
+endif()
+
+execute_process(
+  COMMAND ${XCRUN_EXECUTABLE} --sdk macosx --show-sdk-path
+  OUTPUT_VARIABLE OSX_SDK_PATH
+  OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+set(CMAKE_OSX_SYSROOT ${OSX_SDK_PATH} CACHE PATH "Sysroot used for OSX support")
+
+set(CMAKE_FIND_ROOT_PATH ${OSX_SDK_PATH} CACHE PATH "Find search path root")
diff --git a/Tests/RunCMake/ctest_build/BuildChangeId-check.cmake b/Tests/RunCMake/ctest_build/BuildChangeId-check.cmake
new file mode 100644
index 0000000..074801f
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/BuildChangeId-check.cmake
@@ -0,0 +1,12 @@
+file(GLOB build_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Build.xml")
+if(build_xml_file)
+  file(READ "${build_xml_file}" build_xml LIMIT 4096)
+  if(NOT build_xml MATCHES [[ChangeId="<>1"]])
+    string(REPLACE "\n" "\n  " build_xml "  ${build_xml}")
+    set(RunCMake_TEST_FAILED
+      "Build.xml does not have expected ChangeId:\n${build_xml}"
+      )
+  endif()
+else()
+  set(RunCMake_TEST_FAILED "Build.xml not found")
+endif()
diff --git a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
index c6f732c..324f25c 100644
--- a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
@@ -31,3 +31,12 @@ endif()
   endif()
 endfunction()
 run_BuildFailure()
+
+function(run_BuildChangeId)
+  set(CASE_TEST_PREFIX_CODE [[
+    set(CTEST_CHANGE_ID "<>1")
+  ]])
+
+  run_ctest(BuildChangeId)
+endfunction()
+run_BuildChangeId()
diff --git a/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt b/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt
new file mode 100644
index 0000000..7e94b8a
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt
@@ -0,0 +1,7 @@
+Run dashboard with model Experimental
+   Source directory: .*/Tests/RunCMake/ctest_start/ConfigInBuild
+   Build directory: .*/Tests/RunCMake/ctest_start/ConfigInBuild-build
+   Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/ConfigInBuild-build/CTestConfig.cmake
+   Site: test-site
+   Build name: test-build-name
+   Use Experimental tag: [0-9-]+
diff --git a/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt b/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt
new file mode 100644
index 0000000..c390372
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt
@@ -0,0 +1,7 @@
+Run dashboard with model Experimental
+   Source directory: .*/Tests/RunCMake/ctest_start/ConfigInSource
+   Build directory: .*/Tests/RunCMake/ctest_start/ConfigInSource-build
+   Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/ConfigInSource/CTestConfig.cmake
+   Site: test-site
+   Build name: test-build-name
+   Use Experimental tag: [0-9-]+
diff --git a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
index f765a0f..d630a79 100644
--- a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
@@ -8,3 +8,16 @@ function(run_ctest_start CASE_NAME)
 endfunction()
 
 run_ctest_start(StartQuiet Experimental QUIET)
+
+run_ctest_start(ConfigInSource Experimental)
+
+function(run_ConfigInBuild)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ConfigInBuild-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in
+                 ${RunCMake_BINARY_DIR}/ConfigInBuild-build/CTestConfig.cmake @ONLY)
+  run_ctest_start(ConfigInBuild Experimental)
+endfunction()
+run_ConfigInBuild()
diff --git a/Tests/RunCMake/ctest_test/CMakeLists.txt.in b/Tests/RunCMake/ctest_test/CMakeLists.txt.in
index cedf379..e61b556 100644
--- a/Tests/RunCMake/ctest_test/CMakeLists.txt.in
+++ b/Tests/RunCMake/ctest_test/CMakeLists.txt.in
@@ -2,3 +2,4 @@ cmake_minimum_required(VERSION 3.1)
 project(CTestTest at CASE_NAME@ NONE)
 include(CTest)
 add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
+ at CASE_CMAKELISTS_SUFFIX_CODE@
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt b/Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt
new file mode 100644
index 0000000..eafba1c
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt
@@ -0,0 +1 @@
+No tests were found!!!
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt
new file mode 100644
index 0000000..e203c10
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt
@@ -0,0 +1,2 @@
+Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadFail-build
+\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 4, Smallest test RunCMakeVersion requires 1\*\*\*\*\*$
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stderr.txt b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stderr.txt
new file mode 100644
index 0000000..7f2d7f6
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stderr.txt
@@ -0,0 +1 @@
+^Invalid value for 'CTEST_TEST_LOAD' : ERR2
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt
new file mode 100644
index 0000000..b54220c
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-build
+    Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion ..................   Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt
new file mode 100644
index 0000000..c221eed
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadPass-build
+    Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion ..................   Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
index d906290..e2f380c 100644
--- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
@@ -1,6 +1,8 @@
 include(RunCTest)
+set(RunCMake_TEST_TIMEOUT 60)
 
 set(CASE_CTEST_TEST_ARGS "")
+set(CASE_CTEST_TEST_LOAD "")
 
 function(run_ctest_test CASE_NAME)
   set(CASE_CTEST_TEST_ARGS "${ARGN}")
@@ -8,3 +10,67 @@ function(run_ctest_test CASE_NAME)
 endfunction()
 
 run_ctest_test(TestQuiet QUIET)
+
+# Tests for the 'Test Load' feature of ctest
+#
+# Spoof a load average value to make these tests more reliable.
+set(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING} 5)
+
+# Verify that new tests are started when the load average falls below
+# our threshold.
+run_ctest_test(TestLoadPass TEST_LOAD 6)
+
+# Verify that new tests are not started when the load average exceeds
+# our threshold.
+run_ctest_test(TestLoadFail TEST_LOAD 2)
+
+# Verify that when an invalid "TEST_LOAD" value is given, a warning
+# message is displayed and the value is ignored.
+run_ctest_test(TestLoadInvalid TEST_LOAD "ERR1")
+
+# Verify that new tests are started when the load average falls below
+# our threshold.
+set(CASE_CTEST_TEST_LOAD 7)
+run_ctest_test(CTestTestLoadPass)
+
+# Verify that new tests are not started when the load average exceeds
+# our threshold.
+set(CASE_CTEST_TEST_LOAD 4)
+run_ctest_test(CTestTestLoadFail)
+
+# Verify that when an invalid "CTEST_TEST_LOAD" value is given,
+# a warning message is displayed and the value is ignored.
+set(CASE_CTEST_TEST_LOAD "ERR2")
+run_ctest_test(CTestTestLoadInvalid)
+
+# Verify that the "TEST_LOAD" value has higher precedence than
+# the "CTEST_TEST_LOAD" value
+set(CASE_CTEST_TEST_LOAD "ERR3")
+run_ctest_test(TestLoadOrder TEST_LOAD "ERR4")
+
+unset(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING})
+unset(CASE_CTEST_TEST_LOAD)
+
+function(run_TestChangeId)
+  set(CASE_TEST_PREFIX_CODE [[
+    set(CTEST_CHANGE_ID "<>1")
+  ]])
+
+  run_ctest(TestChangeId)
+endfunction()
+run_TestChangeId()
+
+function(run_TestOutputSize)
+  set(CASE_CTEST_TEST_ARGS EXCLUDE RunCMakeVersion)
+  set(CASE_TEST_PREFIX_CODE [[
+set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 10)
+set(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE 12)
+  ]])
+  set(CASE_CMAKELISTS_SUFFIX_CODE [[
+add_test(NAME PassingTest COMMAND ${CMAKE_COMMAND} -E echo PassingTestOutput)
+add_test(NAME FailingTest COMMAND ${CMAKE_COMMAND} -E no_such_command)
+  ]])
+
+  run_ctest(TestOutputSize)
+endfunction()
+run_TestOutputSize()
diff --git a/Tests/RunCMake/ctest_test/TestChangeId-check.cmake b/Tests/RunCMake/ctest_test/TestChangeId-check.cmake
new file mode 100644
index 0000000..b9884f1
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestChangeId-check.cmake
@@ -0,0 +1,12 @@
+file(GLOB test_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Test.xml")
+if(test_xml_file)
+  file(READ "${test_xml_file}" test_xml LIMIT 4096)
+  if(NOT test_xml MATCHES [[ChangeId="<>1"]])
+    string(REPLACE "\n" "\n  " test_xml "  ${test_xml}")
+    set(RunCMake_TEST_FAILED
+      "Test.xml does not have expected ChangeId:\n${test_xml}"
+      )
+  endif()
+else()
+  set(RunCMake_TEST_FAILED "Test.xml not found")
+endif()
diff --git a/Tests/RunCMake/ctest_test/TestLoadFail-result.txt b/Tests/RunCMake/ctest_test/TestLoadFail-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadFail-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt b/Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt
new file mode 100644
index 0000000..eafba1c
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt
@@ -0,0 +1 @@
+No tests were found!!!
diff --git a/Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt
new file mode 100644
index 0000000..4d7ce48
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt
@@ -0,0 +1,2 @@
+Test project .*/Tests/RunCMake/ctest_test/TestLoadFail-build
+\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 2, Smallest test RunCMakeVersion requires 1\*\*\*\*\*$
diff --git a/Tests/RunCMake/ctest_test/TestLoadInvalid-stderr.txt b/Tests/RunCMake/ctest_test/TestLoadInvalid-stderr.txt
new file mode 100644
index 0000000..40ddb3a
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadInvalid-stderr.txt
@@ -0,0 +1 @@
+^Invalid value for 'TEST_LOAD' : ERR1
diff --git a/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt
new file mode 100644
index 0000000..c4fd35b
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/TestLoadInvalid-build
+    Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion ..................   Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/TestLoadOrder-stderr.txt b/Tests/RunCMake/ctest_test/TestLoadOrder-stderr.txt
new file mode 100644
index 0000000..1de730e
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadOrder-stderr.txt
@@ -0,0 +1 @@
+^Invalid value for 'TEST_LOAD' : ERR4
diff --git a/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt
new file mode 100644
index 0000000..22da092
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/TestLoadOrder-build
+    Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion ..................   Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt
new file mode 100644
index 0000000..e5048f4
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/TestLoadPass-build
+    Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion ..................   Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/TestOutputSize-check.cmake b/Tests/RunCMake/ctest_test/TestOutputSize-check.cmake
new file mode 100644
index 0000000..918d242
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestOutputSize-check.cmake
@@ -0,0 +1,17 @@
+file(GLOB test_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Test.xml")
+if(test_xml_file)
+  file(READ "${test_xml_file}" test_xml LIMIT 4096)
+  if("${test_xml}" MATCHES [[(<Test Status="passed">.*</Test>).*(<Test Status="failed">.*</Test>)]])
+    set(test_passed "${CMAKE_MATCH_1}")
+    set(test_failed "${CMAKE_MATCH_2}")
+  else()
+    set(RunCMake_TEST_FAILED "Test.xml does not contain a passed then failed test:\n ${test_xml}")
+  endif()
+  if(NOT "${test_passed}" MATCHES [[<Value>PassingTes\.\.\..*10 bytes]])
+    set(RunCMake_TEST_FAILED "Test.xml passed test output not truncated at 10 bytes:\n ${test_passed}")
+  elseif(NOT "${test_failed}" MATCHES [[<Value>CMake Error:\.\.\..*12 bytes]])
+    set(RunCMake_TEST_FAILED "Test.xml failed test output not truncated at 12 bytes:\n ${test_failed}")
+  endif()
+else()
+  set(RunCMake_TEST_FAILED "Test.xml not found")
+endif()
diff --git a/Tests/RunCMake/ctest_test/test.cmake.in b/Tests/RunCMake/ctest_test/test.cmake.in
index 1350abe..50b936d 100644
--- a/Tests/RunCMake/ctest_test/test.cmake.in
+++ b/Tests/RunCMake/ctest_test/test.cmake.in
@@ -1,4 +1,5 @@
 cmake_minimum_required(VERSION 3.1)
+ at CASE_TEST_PREFIX_CODE@
 
 set(CTEST_SITE                          "test-site")
 set(CTEST_BUILD_NAME                    "test-build-name")
@@ -8,6 +9,7 @@ set(CTEST_CMAKE_GENERATOR               "@RunCMake_GENERATOR@")
 set(CTEST_CMAKE_GENERATOR_PLATFORM      "@RunCMake_GENERATOR_PLATFORM@")
 set(CTEST_CMAKE_GENERATOR_TOOLSET       "@RunCMake_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
+set(CTEST_TEST_LOAD                     "@CASE_CTEST_TEST_LOAD@")
 
 set(ctest_test_args "@CASE_CTEST_TEST_ARGS@")
 ctest_start(Experimental)
diff --git a/Tests/RunCMake/export/AppendExport-stderr.txt b/Tests/RunCMake/export/AppendExport-stderr.txt
index 6e385d4..d71620e 100644
--- a/Tests/RunCMake/export/AppendExport-stderr.txt
+++ b/Tests/RunCMake/export/AppendExport-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at AppendExport.cmake:8 \(export\):
+CMake Error at AppendExport.cmake:[0-9]+ \(export\):
   export EXPORT signature does not recognise the APPEND option.
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/export/AppendExport.cmake b/Tests/RunCMake/export/AppendExport.cmake
index f36010b..2a99dfc 100644
--- a/Tests/RunCMake/export/AppendExport.cmake
+++ b/Tests/RunCMake/export/AppendExport.cmake
@@ -1,3 +1,4 @@
+enable_language(CXX)
 add_library(foo empty.cpp)
 export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
 install(TARGETS foo EXPORT fooExport
diff --git a/Tests/RunCMake/export/CMakeLists.txt b/Tests/RunCMake/export/CMakeLists.txt
index be9d403..12cd3c7 100644
--- a/Tests/RunCMake/export/CMakeLists.txt
+++ b/Tests/RunCMake/export/CMakeLists.txt
@@ -1,3 +1,3 @@
 cmake_minimum_required(VERSION 2.8.4)
-project(${RunCMake_TEST})
+project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/export/CustomTarget-result.txt b/Tests/RunCMake/export/CustomTarget-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/export/CustomTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/export/CustomTarget-stderr.txt b/Tests/RunCMake/export/CustomTarget-stderr.txt
new file mode 100644
index 0000000..57a9af3
--- /dev/null
+++ b/Tests/RunCMake/export/CustomTarget-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CustomTarget.cmake:[0-9]+ \(export\):
+  export given custom target "CustomTarget" which may not be exported.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/export/CustomTarget.cmake b/Tests/RunCMake/export/CustomTarget.cmake
new file mode 100644
index 0000000..4d2bf18
--- /dev/null
+++ b/Tests/RunCMake/export/CustomTarget.cmake
@@ -0,0 +1,2 @@
+add_custom_target(CustomTarget)
+export(TARGETS CustomTarget FILE somefile.cmake)
diff --git a/Tests/RunCMake/export/OldIface-stderr.txt b/Tests/RunCMake/export/OldIface-stderr.txt
index afb4ae3..818c2cb 100644
--- a/Tests/RunCMake/export/OldIface-stderr.txt
+++ b/Tests/RunCMake/export/OldIface-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at OldIface.cmake:8 \(export\):
+CMake Error at OldIface.cmake:[0-9]+ \(export\):
   export EXPORT signature does not recognise the
   EXPORT_LINK_INTERFACE_LIBRARIES option.
 Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/export/OldIface.cmake b/Tests/RunCMake/export/OldIface.cmake
index 5fb8e25..833b023 100644
--- a/Tests/RunCMake/export/OldIface.cmake
+++ b/Tests/RunCMake/export/OldIface.cmake
@@ -1,3 +1,4 @@
+enable_language(CXX)
 add_library(foo empty.cpp)
 export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
 install(TARGETS foo EXPORT fooExport
diff --git a/Tests/RunCMake/export/RunCMakeTest.cmake b/Tests/RunCMake/export/RunCMakeTest.cmake
index 4b04f18..6d0b7ca 100644
--- a/Tests/RunCMake/export/RunCMakeTest.cmake
+++ b/Tests/RunCMake/export/RunCMakeTest.cmake
@@ -1,5 +1,6 @@
 include(RunCMake)
 
+run_cmake(CustomTarget)
 run_cmake(TargetNotFound)
 run_cmake(AppendExport)
 run_cmake(OldIface)
diff --git a/Tests/RunCMake/find_program/A/testA b/Tests/RunCMake/find_program/A/testA
new file mode 100755
index 0000000..1a24852
--- /dev/null
+++ b/Tests/RunCMake/find_program/A/testA
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/find_program/A/testAandB b/Tests/RunCMake/find_program/A/testAandB
new file mode 100755
index 0000000..1a24852
--- /dev/null
+++ b/Tests/RunCMake/find_program/A/testAandB
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/find_program/B/testAandB b/Tests/RunCMake/find_program/B/testAandB
new file mode 100755
index 0000000..1a24852
--- /dev/null
+++ b/Tests/RunCMake/find_program/B/testAandB
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/find_program/B/testB b/Tests/RunCMake/find_program/B/testB
new file mode 100755
index 0000000..1a24852
--- /dev/null
+++ b/Tests/RunCMake/find_program/B/testB
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/find_program/CMakeLists.txt b/Tests/RunCMake/find_program/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/find_program/DirsPerName-stdout.txt b/Tests/RunCMake/find_program/DirsPerName-stdout.txt
new file mode 100644
index 0000000..dc1c82b
--- /dev/null
+++ b/Tests/RunCMake/find_program/DirsPerName-stdout.txt
@@ -0,0 +1,2 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/B/testB'
+-- PROG_ABS='[^']*/Tests/RunCMake/find_program/A/testA'
diff --git a/Tests/RunCMake/find_program/DirsPerName.cmake b/Tests/RunCMake/find_program/DirsPerName.cmake
new file mode 100644
index 0000000..6db778d
--- /dev/null
+++ b/Tests/RunCMake/find_program/DirsPerName.cmake
@@ -0,0 +1,12 @@
+find_program(PROG
+  NAMES testB testA
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG='${PROG}'")
+
+find_program(PROG_ABS
+  NAMES ${CMAKE_CURRENT_SOURCE_DIR}/A/testA
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG_ABS='${PROG_ABS}'")
diff --git a/Tests/RunCMake/find_program/EnvAndHints-stdout.txt b/Tests/RunCMake/find_program/EnvAndHints-stdout.txt
new file mode 100644
index 0000000..39329b2
--- /dev/null
+++ b/Tests/RunCMake/find_program/EnvAndHints-stdout.txt
@@ -0,0 +1 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/A/testAandB'
diff --git a/Tests/RunCMake/find_program/EnvAndHints.cmake b/Tests/RunCMake/find_program/EnvAndHints.cmake
new file mode 100644
index 0000000..14ebd6e
--- /dev/null
+++ b/Tests/RunCMake/find_program/EnvAndHints.cmake
@@ -0,0 +1,8 @@
+set(ENV_PATH "$ENV{PATH}")
+set(ENV{PATH} ${CMAKE_CURRENT_SOURCE_DIR}/A)
+find_program(PROG
+  NAMES testAandB
+  HINTS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
+  )
+message(STATUS "PROG='${PROG}'")
+set(ENV{PATH} "${ENV_PATH}")
diff --git a/Tests/RunCMake/find_program/NamesPerDir-stdout.txt b/Tests/RunCMake/find_program/NamesPerDir-stdout.txt
new file mode 100644
index 0000000..fd79185
--- /dev/null
+++ b/Tests/RunCMake/find_program/NamesPerDir-stdout.txt
@@ -0,0 +1,2 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/A/testA'
+-- PROG_ABS='[^']*/Tests/RunCMake/find_program/A/testA'
diff --git a/Tests/RunCMake/find_program/NamesPerDir.cmake b/Tests/RunCMake/find_program/NamesPerDir.cmake
new file mode 100644
index 0000000..5f00a28
--- /dev/null
+++ b/Tests/RunCMake/find_program/NamesPerDir.cmake
@@ -0,0 +1,12 @@
+find_program(PROG
+  NAMES testB testA NAMES_PER_DIR
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG='${PROG}'")
+
+find_program(PROG_ABS
+  NAMES ${CMAKE_CURRENT_SOURCE_DIR}/A/testA NAMES_PER_DIR
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG_ABS='${PROG_ABS}'")
diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake
new file mode 100644
index 0000000..89307c1
--- /dev/null
+++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCMake)
+
+run_cmake(EnvAndHints)
+run_cmake(DirsPerName)
+run_cmake(NamesPerDir)
+
+if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$")
+  run_cmake(WindowsCom)
+  run_cmake(WindowsExe)
+endif()
diff --git a/Tests/RunCMake/find_program/Win/testCom.com b/Tests/RunCMake/find_program/Win/testCom.com
new file mode 100755
index 0000000..e69de29
diff --git a/Tests/RunCMake/find_program/Win/testCom.exe b/Tests/RunCMake/find_program/Win/testCom.exe
new file mode 100755
index 0000000..e69de29
diff --git a/Tests/RunCMake/find_program/Win/testExe.exe b/Tests/RunCMake/find_program/Win/testExe.exe
new file mode 100755
index 0000000..e69de29
diff --git a/Tests/RunCMake/find_program/WindowsCom-stdout.txt b/Tests/RunCMake/find_program/WindowsCom-stdout.txt
new file mode 100644
index 0000000..e386fce
--- /dev/null
+++ b/Tests/RunCMake/find_program/WindowsCom-stdout.txt
@@ -0,0 +1 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/Win/testCom.com'
diff --git a/Tests/RunCMake/find_program/WindowsCom.cmake b/Tests/RunCMake/find_program/WindowsCom.cmake
new file mode 100644
index 0000000..b32d9e8
--- /dev/null
+++ b/Tests/RunCMake/find_program/WindowsCom.cmake
@@ -0,0 +1,6 @@
+find_program(PROG
+  NAMES testCom
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/Win
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG='${PROG}'")
diff --git a/Tests/RunCMake/find_program/WindowsExe-stdout.txt b/Tests/RunCMake/find_program/WindowsExe-stdout.txt
new file mode 100644
index 0000000..bdf48aa
--- /dev/null
+++ b/Tests/RunCMake/find_program/WindowsExe-stdout.txt
@@ -0,0 +1 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/Win/testExe.exe'
diff --git a/Tests/RunCMake/find_program/WindowsExe.cmake b/Tests/RunCMake/find_program/WindowsExe.cmake
new file mode 100644
index 0000000..3a336ec
--- /dev/null
+++ b/Tests/RunCMake/find_program/WindowsExe.cmake
@@ -0,0 +1,6 @@
+find_program(PROG
+  NAMES testExe
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/Win
+  NO_DEFAULT_PATH
+  )
+message(STATUS "PROG='${PROG}'")
diff --git a/Tests/RunCMake/get_filename_component/CMakeLists.txt b/Tests/RunCMake/get_filename_component/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/get_filename_component/CMakeLists.txt
+++ b/Tests/RunCMake/get_filename_component/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
index 9d7cf90..d822258 100644
--- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake
+++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
@@ -1,9 +1,11 @@
+# Assertion macro
 macro(check desc actual expect)
   if(NOT "x${actual}" STREQUAL "x${expect}")
     message(SEND_ERROR "${desc}: got \"${actual}\", not \"${expect}\"")
   endif()
 endmacro()
 
+# General test of all component types given an absolute path.
 set(filename "/path/to/filename.ext.in")
 set(expect_DIRECTORY "/path/to")
 set(expect_NAME "filename.ext.in")
@@ -13,14 +15,19 @@ set(expect_PATH "/path/to")
 foreach(c DIRECTORY NAME EXT NAME_WE PATH)
   get_filename_component(actual_${c} "${filename}" ${c})
   check("${c}" "${actual_${c}}" "${expect_${c}}")
+  list(APPEND non_cache_vars actual_${c})
 endforeach()
 
+# Test Windows paths with DIRECTORY component and an absolute Windows path.
 get_filename_component(test_slashes "c:\\path\\to\\filename.ext.in" DIRECTORY)
 check("DIRECTORY from backslashes" "${test_slashes}" "c:/path/to")
+list(APPEND non_cache_vars test_slashes)
 
 get_filename_component(test_winroot "c:\\filename.ext.in" DIRECTORY)
 check("DIRECTORY in windows root" "${test_winroot}" "c:/")
+list(APPEND non_cache_vars test_winroot)
 
+# Test finding absolute paths.
 get_filename_component(test_absolute "/path/to/a/../filename.ext.in" ABSOLUTE)
 check("ABSOLUTE" "${test_absolute}" "/path/to/filename.ext.in")
 
@@ -29,10 +36,113 @@ check("ABSOLUTE .. in root" "${test_absolute}" "/path/to/filename.ext.in")
 get_filename_component(test_absolute "c:/../path/to/filename.ext.in" ABSOLUTE)
 check("ABSOLUTE .. in windows root" "${test_absolute}" "c:/path/to/filename.ext.in")
 
+list(APPEND non_cache_vars test_absolute)
+
+# Test finding absolute paths from various base directories.
+
+get_filename_component(test_abs_base "testdir1" ABSOLUTE)
+check("ABSOLUTE .. from default base" "${test_abs_base}"
+      "${CMAKE_CURRENT_SOURCE_DIR}/testdir1")
+
+get_filename_component(test_abs_base "../testdir2" ABSOLUTE
+                       BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dummydir")
+check("ABSOLUTE .. from dummy base to parent" "${test_abs_base}"
+      "${CMAKE_CURRENT_SOURCE_DIR}/testdir2")
+
+get_filename_component(test_abs_base "testdir3" ABSOLUTE
+                       BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dummydir")
+check("ABSOLUTE .. from dummy base to child" "${test_abs_base}"
+      "${CMAKE_CURRENT_SOURCE_DIR}/dummydir/testdir3")
+
+list(APPEND non_cache_vars test_abs_base)
+
+# Test finding absolute paths with CACHE parameter.  (Note that more
+# rigorous testing of the CACHE parameter comes later with PROGRAM).
+
+get_filename_component(test_abs_base_1 "testdir4" ABSOLUTE CACHE)
+check("ABSOLUTE CACHE 1" "${test_abs_base_1}"
+      "${CMAKE_CURRENT_SOURCE_DIR}/testdir4")
+list(APPEND cache_vars test_abs_base_1)
+
+get_filename_component(test_abs_base_2 "testdir5" ABSOLUTE
+                       BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dummydir"
+                       CACHE)
+check("ABSOLUTE CACHE 2" "${test_abs_base_2}"
+      "${CMAKE_CURRENT_SOURCE_DIR}/dummydir/testdir5")
+list(APPEND cache_vars test_abs_base_2)
+
+# Test the PROGRAM component type.
+get_filename_component(test_program_name "/ arg1 arg2" PROGRAM)
+check("PROGRAM with no args output" "${test_program_name}" "/")
+
+get_filename_component(test_program_name "/ arg1 arg2" PROGRAM
+  PROGRAM_ARGS test_program_args)
+check("PROGRAM with args output: name" "${test_program_name}" "/")
+check("PROGRAM with args output: args" "${test_program_args}" " arg1 arg2")
+
+list(APPEND non_cache_vars test_program_name)
+list(APPEND non_cache_vars test_program_args)
+
+# Test CACHE parameter for most component types.
 get_filename_component(test_cache "/path/to/filename.ext.in" DIRECTORY CACHE)
 check("CACHE 1" "${test_cache}" "/path/to")
+# Make sure that the existing CACHE entry from previous is honored:
 get_filename_component(test_cache "/path/to/other/filename.ext.in" DIRECTORY CACHE)
 check("CACHE 2" "${test_cache}" "/path/to")
 unset(test_cache CACHE)
 get_filename_component(test_cache "/path/to/other/filename.ext.in" DIRECTORY CACHE)
 check("CACHE 3" "${test_cache}" "/path/to/other")
+
+list(APPEND cache_vars test_cache)
+
+# Test the PROGRAM component type with CACHE specified.
+
+# 1. Make sure it makes a cache variable in the first place for basic usage:
+get_filename_component(test_cache_program_name_1 "/ arg1 arg2" PROGRAM CACHE)
+check("PROGRAM CACHE 1 with no args output" "${test_cache_program_name_1}" "/")
+list(APPEND cache_vars test_cache_program_name_1)
+
+# 2. Set some existing cache variables & make sure the function returns them:
+set(test_cache_program_name_2 DummyProgramName CACHE FILEPATH "")
+get_filename_component(test_cache_program_name_2 "/ arg1 arg2" PROGRAM CACHE)
+check("PROGRAM CACHE 2 with no args output" "${test_cache_program_name_2}"
+  "DummyProgramName")
+list(APPEND cache_vars test_cache_program_name_2)
+
+# 3. Now test basic usage when PROGRAM_ARGS is used:
+get_filename_component(test_cache_program_name_3 "/ arg1 arg2" PROGRAM
+  PROGRAM_ARGS test_cache_program_args_3 CACHE)
+check("PROGRAM CACHE 3 name" "${test_cache_program_name_3}" "/")
+check("PROGRAM CACHE 3 args" "${test_cache_program_args_3}" " arg1 arg2")
+list(APPEND cache_vars test_cache_program_name_3)
+list(APPEND cache_vars test_cache_program_args_3)
+
+# 4. Test that existing cache variables are returned when PROGRAM_ARGS is used:
+set(test_cache_program_name_4 DummyPgm CACHE FILEPATH "")
+set(test_cache_program_args_4 DummyArgs CACHE STRING "")
+get_filename_component(test_cache_program_name_4 "/ arg1 arg2" PROGRAM
+  PROGRAM_ARGS test_cache_program_args_4 CACHE)
+check("PROGRAM CACHE 4 name" "${test_cache_program_name_4}" "DummyPgm")
+check("PROGRAM CACHE 4 args" "${test_cache_program_args_4}" "DummyArgs")
+list(APPEND cache_vars test_cache_program_name_4)
+list(APPEND cache_vars test_cache_program_name_4)
+
+# Test that ONLY the expected cache variables were created.
+get_cmake_property(current_cache_vars CACHE_VARIABLES)
+get_cmake_property(current_vars VARIABLES)
+
+foreach(thisVar ${cache_vars})
+  if(NOT thisVar IN_LIST current_cache_vars)
+    message(SEND_ERROR "${thisVar} expected in cache but was not found.")
+  endif()
+endforeach()
+
+foreach(thisVar ${non_cache_vars})
+  if(thisVar IN_LIST current_cache_vars)
+    message(SEND_ERROR "${thisVar} unexpectedly found in cache.")
+  endif()
+  if(NOT thisVar IN_LIST current_vars)
+    # Catch likely typo when appending to non_cache_vars:
+    message(SEND_ERROR "${thisVar} not found in regular variable list.")
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/get_property/BadArgument-result.txt b/Tests/RunCMake/get_property/BadArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadArgument-stderr.txt b/Tests/RunCMake/get_property/BadArgument-stderr.txt
new file mode 100644
index 0000000..37c4477
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadArgument-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at BadArgument.cmake:1 \(get_property\):
+  get_property given invalid argument "FOO".
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Argument.cmake b/Tests/RunCMake/get_property/BadArgument.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-Bad-Argument.cmake
rename to Tests/RunCMake/get_property/BadArgument.cmake
diff --git a/Tests/RunCMake/get_property/BadDirectory-result.txt b/Tests/RunCMake/get_property/BadDirectory-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadDirectory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadDirectory-stderr.txt b/Tests/RunCMake/get_property/BadDirectory-stderr.txt
new file mode 100644
index 0000000..98464f8
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadDirectory-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at BadDirectory.cmake:1 \(get_property\):
+  get_property DIRECTORY scope provided but requested directory was not
+  found.  This could be because the directory argument was invalid or, it is
+  valid but has not been processed yet.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Directory.cmake b/Tests/RunCMake/get_property/BadDirectory.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-Bad-Directory.cmake
rename to Tests/RunCMake/get_property/BadDirectory.cmake
diff --git a/Tests/RunCMake/get_property/BadScope-result.txt b/Tests/RunCMake/get_property/BadScope-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadScope-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadScope-stderr.txt b/Tests/RunCMake/get_property/BadScope-stderr.txt
new file mode 100644
index 0000000..4cc32c8
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadScope-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at BadScope.cmake:1 \(get_property\):
+  get_property given invalid scope FOO.  Valid scopes are GLOBAL, DIRECTORY,
+  TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Scope.cmake b/Tests/RunCMake/get_property/BadScope.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-Bad-Scope.cmake
rename to Tests/RunCMake/get_property/BadScope.cmake
diff --git a/Tests/RunCMake/get_property/BadTarget-result.txt b/Tests/RunCMake/get_property/BadTarget-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadTarget-stderr.txt b/Tests/RunCMake/get_property/BadTarget-stderr.txt
new file mode 100644
index 0000000..45a0df6
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadTarget-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at BadTarget.cmake:1 \(get_property\):
+  get_property could not find TARGET FOO.  Perhaps it has not yet been
+  created.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Target.cmake b/Tests/RunCMake/get_property/BadTarget.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-Bad-Target.cmake
rename to Tests/RunCMake/get_property/BadTarget.cmake
diff --git a/Tests/RunCMake/get_property/BadTest-result.txt b/Tests/RunCMake/get_property/BadTest-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadTest-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadTest-stderr.txt b/Tests/RunCMake/get_property/BadTest-stderr.txt
new file mode 100644
index 0000000..819c070
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadTest-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at BadTest.cmake:1 \(get_property\):
+  get_property given TEST name that does not exist: FOO
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Test.cmake b/Tests/RunCMake/get_property/BadTest.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-Bad-Test.cmake
rename to Tests/RunCMake/get_property/BadTest.cmake
diff --git a/Tests/RunCMake/get_property/GlobalName-result.txt b/Tests/RunCMake/get_property/GlobalName-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/GlobalName-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/GlobalName-stderr.txt b/Tests/RunCMake/get_property/GlobalName-stderr.txt
new file mode 100644
index 0000000..a7d4971
--- /dev/null
+++ b/Tests/RunCMake/get_property/GlobalName-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at GlobalName.cmake:1 \(get_property\):
+  get_property given name for GLOBAL scope.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Global-Name.cmake b/Tests/RunCMake/get_property/GlobalName.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-Global-Name.cmake
rename to Tests/RunCMake/get_property/GlobalName.cmake
diff --git a/Tests/RunCMake/get_property/MissingArgument-result.txt b/Tests/RunCMake/get_property/MissingArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/MissingArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/MissingArgument-stderr.txt b/Tests/RunCMake/get_property/MissingArgument-stderr.txt
new file mode 100644
index 0000000..8722712
--- /dev/null
+++ b/Tests/RunCMake/get_property/MissingArgument-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at MissingArgument.cmake:1 \(get_property\):
+  get_property called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Missing-Argument.cmake b/Tests/RunCMake/get_property/MissingArgument.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-Missing-Argument.cmake
rename to Tests/RunCMake/get_property/MissingArgument.cmake
diff --git a/Tests/RunCMake/get_property/NoCache-result.txt b/Tests/RunCMake/get_property/NoCache-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoCache-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoCache-stderr.txt b/Tests/RunCMake/get_property/NoCache-stderr.txt
new file mode 100644
index 0000000..defafb6
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoCache-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoCache.cmake:1 \(get_property\):
+  get_property not given name for CACHE scope.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Cache.cmake b/Tests/RunCMake/get_property/NoCache.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-No-Cache.cmake
rename to Tests/RunCMake/get_property/NoCache.cmake
diff --git a/Tests/RunCMake/get_property/NoProperty-result.txt b/Tests/RunCMake/get_property/NoProperty-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoProperty-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoProperty-stderr.txt b/Tests/RunCMake/get_property/NoProperty-stderr.txt
new file mode 100644
index 0000000..0ef147f
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoProperty-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoProperty.cmake:1 \(get_property\):
+  get_property not given a PROPERTY <name> argument.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Property.cmake b/Tests/RunCMake/get_property/NoProperty.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-No-Property.cmake
rename to Tests/RunCMake/get_property/NoProperty.cmake
diff --git a/Tests/RunCMake/get_property/NoSource-result.txt b/Tests/RunCMake/get_property/NoSource-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoSource-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoSource-stderr.txt b/Tests/RunCMake/get_property/NoSource-stderr.txt
new file mode 100644
index 0000000..59fd0ad
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoSource-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoSource.cmake:1 \(get_property\):
+  get_property not given name for SOURCE scope.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Source.cmake b/Tests/RunCMake/get_property/NoSource.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-No-Source.cmake
rename to Tests/RunCMake/get_property/NoSource.cmake
diff --git a/Tests/RunCMake/get_property/NoTarget-result.txt b/Tests/RunCMake/get_property/NoTarget-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoTarget-stderr.txt b/Tests/RunCMake/get_property/NoTarget-stderr.txt
new file mode 100644
index 0000000..a0e1a94
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoTarget-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoTarget.cmake:1 \(get_property\):
+  get_property not given name for TARGET scope.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Target.cmake b/Tests/RunCMake/get_property/NoTarget.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-No-Target.cmake
rename to Tests/RunCMake/get_property/NoTarget.cmake
diff --git a/Tests/RunCMake/get_property/NoTest-result.txt b/Tests/RunCMake/get_property/NoTest-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoTest-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoTest-stderr.txt b/Tests/RunCMake/get_property/NoTest-stderr.txt
new file mode 100644
index 0000000..c90a0ff
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoTest-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoTest.cmake:1 \(get_property\):
+  get_property not given name for TEST scope.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Test.cmake b/Tests/RunCMake/get_property/NoTest.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-No-Test.cmake
rename to Tests/RunCMake/get_property/NoTest.cmake
diff --git a/Tests/RunCMake/get_property/RunCMakeTest.cmake b/Tests/RunCMake/get_property/RunCMakeTest.cmake
index e420b5b..00eef34 100644
--- a/Tests/RunCMake/get_property/RunCMakeTest.cmake
+++ b/Tests/RunCMake/get_property/RunCMakeTest.cmake
@@ -8,3 +8,17 @@ run_cmake(source_properties)
 run_cmake(target_properties)
 run_cmake(test_properties)
 run_cmake(DebugConfigurations)
+
+run_cmake(MissingArgument)
+run_cmake(GlobalName)
+run_cmake(BadTest)
+run_cmake(BadTarget)
+run_cmake(BadScope)
+run_cmake(BadDirectory)
+run_cmake(BadArgument)
+run_cmake(VariableName)
+run_cmake(NoTest)
+run_cmake(NoTarget)
+run_cmake(NoSource)
+run_cmake(NoProperty)
+run_cmake(NoCache)
diff --git a/Tests/RunCMake/get_property/VariableName-result.txt b/Tests/RunCMake/get_property/VariableName-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/get_property/VariableName-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/VariableName-stderr.txt b/Tests/RunCMake/get_property/VariableName-stderr.txt
new file mode 100644
index 0000000..e9f3827
--- /dev/null
+++ b/Tests/RunCMake/get_property/VariableName-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at VariableName.cmake:1 \(get_property\):
+  get_property given name for VARIABLE scope.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Variable-Name.cmake b/Tests/RunCMake/get_property/VariableName.cmake
similarity index 100%
rename from Tests/CMakeTests/GetProperty-Variable-Name.cmake
rename to Tests/RunCMake/get_property/VariableName.cmake
diff --git a/Tests/RunCMake/get_property/target_properties-stderr.txt b/Tests/RunCMake/get_property/target_properties-stderr.txt
index d0981ac..6b3c6ca 100644
--- a/Tests/RunCMake/get_property/target_properties-stderr.txt
+++ b/Tests/RunCMake/get_property/target_properties-stderr.txt
@@ -3,4 +3,8 @@ get_property: --><--
 get_target_property: -->value<--
 get_property: -->value<--
 get_target_property: -->gtp_val-NOTFOUND<--
-get_property: --><--$
+get_property: --><--
+get_target_property: -->(.*)/Tests/RunCMake/get_property<--
+get_property: -->(.*)/Tests/RunCMake/get_property<--
+get_target_property: -->(.*)/Tests/RunCMake/get_property/target_properties-build<--
+get_property: -->(.*)/Tests/RunCMake/get_property/target_properties-build<--$
diff --git a/Tests/RunCMake/get_property/target_properties.cmake b/Tests/RunCMake/get_property/target_properties.cmake
index c5a141d..9ff833a 100644
--- a/Tests/RunCMake/get_property/target_properties.cmake
+++ b/Tests/RunCMake/get_property/target_properties.cmake
@@ -14,3 +14,5 @@ set_target_properties(tgt PROPERTIES empty "" custom value)
 check_target_property(tgt empty)
 check_target_property(tgt custom)
 check_target_property(tgt noexist)
+check_target_property(tgt SOURCE_DIR)
+check_target_property(tgt BINARY_DIR)
diff --git a/Tests/RunCMake/if/InvalidArgument1-result.txt b/Tests/RunCMake/if/InvalidArgument1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/if/InvalidArgument1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/if/InvalidArgument1-stderr.txt b/Tests/RunCMake/if/InvalidArgument1-stderr.txt
new file mode 100644
index 0000000..bf2a994
--- /dev/null
+++ b/Tests/RunCMake/if/InvalidArgument1-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Error at InvalidArgument1.cmake:1 \(if\):
+  if given arguments:
+
+    "NOT" "foo" "bar" "STREQUAL" "foo bar"
+
+  Unknown arguments specified
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/If-Invalid-Argument.cmake b/Tests/RunCMake/if/InvalidArgument1.cmake
similarity index 100%
rename from Tests/CMakeTests/If-Invalid-Argument.cmake
rename to Tests/RunCMake/if/InvalidArgument1.cmake
diff --git a/Tests/RunCMake/if/RunCMakeTest.cmake b/Tests/RunCMake/if/RunCMakeTest.cmake
index b5546a7..3f4d2a2 100644
--- a/Tests/RunCMake/if/RunCMakeTest.cmake
+++ b/Tests/RunCMake/if/RunCMakeTest.cmake
@@ -1,5 +1,9 @@
 include(RunCMake)
 
+run_cmake(InvalidArgument1)
 run_cmake(IsDirectory)
 run_cmake(IsDirectoryLong)
 run_cmake(elseif-message)
+
+run_cmake(TestNameThatExists)
+run_cmake(TestNameThatDoesNotExist)
diff --git a/Tests/RunCMake/if/TestNameThatDoesNotExist-stdout.txt b/Tests/RunCMake/if/TestNameThatDoesNotExist-stdout.txt
new file mode 100644
index 0000000..8874ca8
--- /dev/null
+++ b/Tests/RunCMake/if/TestNameThatDoesNotExist-stdout.txt
@@ -0,0 +1 @@
+TestThatDoesNotExist is false
diff --git a/Tests/RunCMake/if/TestNameThatDoesNotExist.cmake b/Tests/RunCMake/if/TestNameThatDoesNotExist.cmake
new file mode 100644
index 0000000..74bc8b0
--- /dev/null
+++ b/Tests/RunCMake/if/TestNameThatDoesNotExist.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0064 NEW)
+if(TEST TestThatDoesNotExist)
+  message(FATAL_ERROR "if TestThatDoesNotExist is true")
+else()
+  message(STATUS "if TestThatDoesNotExist is false")
+endif()
diff --git a/Tests/RunCMake/if/TestNameThatExists-stdout.txt b/Tests/RunCMake/if/TestNameThatExists-stdout.txt
new file mode 100644
index 0000000..54911bc
--- /dev/null
+++ b/Tests/RunCMake/if/TestNameThatExists-stdout.txt
@@ -0,0 +1 @@
+TestThatExists is true
diff --git a/Tests/RunCMake/if/TestNameThatExists.cmake b/Tests/RunCMake/if/TestNameThatExists.cmake
new file mode 100644
index 0000000..65c2b46
--- /dev/null
+++ b/Tests/RunCMake/if/TestNameThatExists.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0064 NEW)
+add_test(NAME TestThatExists COMMAND ${CMAKE_COMMAND} -E echo "A CMake Test")
+if(TEST TestThatExists)
+  message(STATUS "if TestThatExists is true")
+else()
+  message(FATAL_ERROR "if TestThatExists is false")
+endif()
diff --git a/Tests/RunCMake/include_directories/DirectoryBefore-stdout.txt b/Tests/RunCMake/include_directories/DirectoryBefore-stdout.txt
new file mode 100644
index 0000000..e986082
--- /dev/null
+++ b/Tests/RunCMake/include_directories/DirectoryBefore-stdout.txt
@@ -0,0 +1 @@
+-- INCLUDE_DIRECTORIES: '[^;]*/Tests/RunCMake/include_directories/BeforeDir;[^;]*/Tests/RunCMake/include_directories/AfterDir'
diff --git a/Tests/RunCMake/include_directories/DirectoryBefore.cmake b/Tests/RunCMake/include_directories/DirectoryBefore.cmake
new file mode 100644
index 0000000..be3f663
--- /dev/null
+++ b/Tests/RunCMake/include_directories/DirectoryBefore.cmake
@@ -0,0 +1,4 @@
+include_directories(AfterDir)
+include_directories(BEFORE BeforeDir)
+get_property(dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
+message(STATUS "INCLUDE_DIRECTORIES: '${dirs}'")
diff --git a/Tests/RunCMake/include_directories/RunCMakeTest.cmake b/Tests/RunCMake/include_directories/RunCMakeTest.cmake
index 54d5e97..57e8274 100644
--- a/Tests/RunCMake/include_directories/RunCMakeTest.cmake
+++ b/Tests/RunCMake/include_directories/RunCMakeTest.cmake
@@ -5,6 +5,7 @@ set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/NotDefa
 
 run_cmake(NotFoundContent)
 run_cmake(DebugIncludes)
+run_cmake(DirectoryBefore)
 run_cmake(TID-bad-target)
 run_cmake(ImportedTarget)
 run_cmake(CMP0021)
diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-result.txt b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-stderr.txt b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-stderr.txt
new file mode 100644
index 0000000..9844158
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<NOTAGENEX>
+
+  Expression did not evaluate to a known generator expression
diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad.cmake b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad.cmake
new file mode 100644
index 0000000..f050cdf
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad.cmake
@@ -0,0 +1 @@
+install(DIRECTORY dir DESTINATION $<NOTAGENEX>)
diff --git a/Tests/RunCMake/install/FILES-DESTINATION-bad-result.txt b/Tests/RunCMake/install/FILES-DESTINATION-bad-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-DESTINATION-bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/FILES-DESTINATION-bad-stderr.txt b/Tests/RunCMake/install/FILES-DESTINATION-bad-stderr.txt
new file mode 100644
index 0000000..9844158
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-DESTINATION-bad-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<NOTAGENEX>
+
+  Expression did not evaluate to a known generator expression
diff --git a/Tests/RunCMake/install/FILES-DESTINATION-bad.cmake b/Tests/RunCMake/install/FILES-DESTINATION-bad.cmake
new file mode 100644
index 0000000..0fda078
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-DESTINATION-bad.cmake
@@ -0,0 +1 @@
+install(FILES empty.c DESTINATION $<NOTAGENEX>)
diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake
index a5f5bd0..043bd1f 100644
--- a/Tests/RunCMake/install/RunCMakeTest.cmake
+++ b/Tests/RunCMake/install/RunCMakeTest.cmake
@@ -6,6 +6,8 @@ run_cmake(DIRECTORY-message-lazy)
 run_cmake(SkipInstallRulesWarning)
 run_cmake(SkipInstallRulesNoWarning1)
 run_cmake(SkipInstallRulesNoWarning2)
+run_cmake(DIRECTORY-DESTINATION-bad)
+run_cmake(FILES-DESTINATION-bad)
 run_cmake(TARGETS-DESTINATION-bad)
 run_cmake(CMP0062-OLD)
 run_cmake(CMP0062-NEW)
diff --git a/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
new file mode 100644
index 0000000..a0f8837
--- /dev/null
+++ b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Warning \(dev\) at GET-CMP0007-WARN.cmake:4 \(list\):
+  Policy CMP0007 is not set: list command no longer ignores empty elements.
+  Run "cmake --help-policy CMP0007" for policy details.  Use the cmake_policy
+  command to set the policy and suppress this warning.  List has value =
+  \[;NEW;OLD\].
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/list/GET-CMP0007-WARN.cmake b/Tests/RunCMake/list/GET-CMP0007-WARN.cmake
new file mode 100644
index 0000000..833f352
--- /dev/null
+++ b/Tests/RunCMake/list/GET-CMP0007-WARN.cmake
@@ -0,0 +1,7 @@
+cmake_policy(VERSION 2.4)
+set(thelist "" NEW OLD)
+
+list(GET thelist 1 thevalue)
+if (NOT thevalue STREQUAL "OLD")
+    message(SEND_ERROR "returned element '${thevalue}', but expected 'OLD'")
+endif()
diff --git a/Tests/RunCMake/list/GET-InvalidIndex-result.txt b/Tests/RunCMake/list/GET-InvalidIndex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/GET-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/GET-InvalidIndex-stderr.txt b/Tests/RunCMake/list/GET-InvalidIndex-stderr.txt
new file mode 100644
index 0000000..0409464
--- /dev/null
+++ b/Tests/RunCMake/list/GET-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at GET-InvalidIndex.cmake:2 \(list\):
+  list index: 3 out of range \(-3, 2\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Get-Invalid-Index.cmake b/Tests/RunCMake/list/GET-InvalidIndex.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Get-Invalid-Index.cmake
rename to Tests/RunCMake/list/GET-InvalidIndex.cmake
diff --git a/Tests/RunCMake/list/INSERT-InvalidIndex-result.txt b/Tests/RunCMake/list/INSERT-InvalidIndex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/INSERT-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/INSERT-InvalidIndex-stderr.txt b/Tests/RunCMake/list/INSERT-InvalidIndex-stderr.txt
new file mode 100644
index 0000000..6e15c0b
--- /dev/null
+++ b/Tests/RunCMake/list/INSERT-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at INSERT-InvalidIndex.cmake:2 \(list\):
+  list index: 3 out of range \(-3, 2\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Insert-Invalid-Index.cmake b/Tests/RunCMake/list/INSERT-InvalidIndex.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Insert-Invalid-Index.cmake
rename to Tests/RunCMake/list/INSERT-InvalidIndex.cmake
diff --git a/Tests/RunCMake/list/InvalidSubcommand-result.txt b/Tests/RunCMake/list/InvalidSubcommand-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/InvalidSubcommand-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/InvalidSubcommand-stderr.txt b/Tests/RunCMake/list/InvalidSubcommand-stderr.txt
new file mode 100644
index 0000000..74703d2
--- /dev/null
+++ b/Tests/RunCMake/list/InvalidSubcommand-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at InvalidSubcommand.cmake:1 \(list\):
+  list does not recognize sub-command NO_SUCH_SUBCOMMAND
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Invalid-Subcommand.cmake b/Tests/RunCMake/list/InvalidSubcommand.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Invalid-Subcommand.cmake
rename to Tests/RunCMake/list/InvalidSubcommand.cmake
diff --git a/Tests/RunCMake/list/LENGTH-TooManyArguments-result.txt b/Tests/RunCMake/list/LENGTH-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/LENGTH-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/LENGTH-TooManyArguments-stderr.txt b/Tests/RunCMake/list/LENGTH-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..239e708
--- /dev/null
+++ b/Tests/RunCMake/list/LENGTH-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at LENGTH-TooManyArguments.cmake:1 \(list\):
+  list sub-command LENGTH requires two arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Length-Too-Many-Arguments.cmake b/Tests/RunCMake/list/LENGTH-TooManyArguments.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Length-Too-Many-Arguments.cmake
rename to Tests/RunCMake/list/LENGTH-TooManyArguments.cmake
diff --git a/Tests/RunCMake/list/NoArguments-result.txt b/Tests/RunCMake/list/NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/NoArguments-stderr.txt b/Tests/RunCMake/list/NoArguments-stderr.txt
new file mode 100644
index 0000000..6fdf9cc
--- /dev/null
+++ b/Tests/RunCMake/list/NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoArguments.cmake:1 \(list\):
+  list must be called with at least two arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-No-Arguments.cmake b/Tests/RunCMake/list/NoArguments.cmake
similarity index 100%
rename from Tests/CMakeTests/List-No-Arguments.cmake
rename to Tests/RunCMake/list/NoArguments.cmake
diff --git a/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-result.txt b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-stderr.txt b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-stderr.txt
new file mode 100644
index 0000000..6f58875
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_AT-InvalidIndex.cmake:2 \(list\):
+  list index: 3 out of range \(-3, 2\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_At-Invalid-Index.cmake b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Remove_At-Invalid-Index.cmake
rename to Tests/RunCMake/list/REMOVE_AT-InvalidIndex.cmake
diff --git a/Tests/RunCMake/list/REMOVE_AT-NotList-result.txt b/Tests/RunCMake/list/REMOVE_AT-NotList-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_AT-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_AT-NotList-stderr.txt b/Tests/RunCMake/list/REMOVE_AT-NotList-stderr.txt
new file mode 100644
index 0000000..d6e8d85
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_AT-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_AT-NotList.cmake:2 \(list\):
+  list sub-command REMOVE_AT requires list to be present.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_At-Nonexistent-List.cmake b/Tests/RunCMake/list/REMOVE_AT-NotList.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Remove_At-Nonexistent-List.cmake
rename to Tests/RunCMake/list/REMOVE_AT-NotList.cmake
diff --git a/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-result.txt b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-stderr.txt b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-stderr.txt
new file mode 100644
index 0000000..96f3446
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_DUPLICATES-NotList.cmake:2 \(list\):
+  list sub-command REMOVE_DUPLICATES requires list to be present.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_Duplicates-Nonexistent-List.cmake b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Remove_Duplicates-Nonexistent-List.cmake
rename to Tests/RunCMake/list/REMOVE_DUPLICATES-NotList.cmake
diff --git a/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-result.txt b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-stderr.txt b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..f5c8711
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_DUPLICATES-TooManyArguments.cmake:1 \(list\):
+  list sub-command REMOVE_DUPLICATES only takes one argument.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_Duplicates-Too-Many-Arguments.cmake b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Remove_Duplicates-Too-Many-Arguments.cmake
rename to Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments.cmake
diff --git a/Tests/RunCMake/list/REMOVE_ITEM-NotList-result.txt b/Tests/RunCMake/list/REMOVE_ITEM-NotList-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_ITEM-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_ITEM-NotList-stderr.txt b/Tests/RunCMake/list/REMOVE_ITEM-NotList-stderr.txt
new file mode 100644
index 0000000..c32a4c0
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_ITEM-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_ITEM-NotList.cmake:2 \(list\):
+  list sub-command REMOVE_ITEM requires list to be present.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_Item-Nonexistent-List.cmake b/Tests/RunCMake/list/REMOVE_ITEM-NotList.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Remove_Item-Nonexistent-List.cmake
rename to Tests/RunCMake/list/REMOVE_ITEM-NotList.cmake
diff --git a/Tests/RunCMake/list/REVERSE-NotList-result.txt b/Tests/RunCMake/list/REVERSE-NotList-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/REVERSE-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REVERSE-NotList-stderr.txt b/Tests/RunCMake/list/REVERSE-NotList-stderr.txt
new file mode 100644
index 0000000..e9dcc06
--- /dev/null
+++ b/Tests/RunCMake/list/REVERSE-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REVERSE-NotList.cmake:2 \(list\):
+  list sub-command REVERSE requires list to be present.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Reverse-Nonexistent-List.cmake b/Tests/RunCMake/list/REVERSE-NotList.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Reverse-Nonexistent-List.cmake
rename to Tests/RunCMake/list/REVERSE-NotList.cmake
diff --git a/Tests/RunCMake/list/REVERSE-TooManyArguments-result.txt b/Tests/RunCMake/list/REVERSE-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/REVERSE-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REVERSE-TooManyArguments-stderr.txt b/Tests/RunCMake/list/REVERSE-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..7dabd9d
--- /dev/null
+++ b/Tests/RunCMake/list/REVERSE-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REVERSE-TooManyArguments.cmake:1 \(list\):
+  list sub-command REVERSE only takes one argument.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Reverse-Too-Many-Arguments.cmake b/Tests/RunCMake/list/REVERSE-TooManyArguments.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Reverse-Too-Many-Arguments.cmake
rename to Tests/RunCMake/list/REVERSE-TooManyArguments.cmake
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
index 555051d..25d6a03 100644
--- a/Tests/RunCMake/list/RunCMakeTest.cmake
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -3,3 +3,22 @@ include(RunCMake)
 run_cmake(EmptyGet0)
 run_cmake(EmptyRemoveAt0)
 run_cmake(EmptyInsert-1)
+
+run_cmake(NoArguments)
+run_cmake(InvalidSubcommand)
+run_cmake(GET-CMP0007-WARN)
+
+run_cmake(GET-InvalidIndex)
+run_cmake(INSERT-InvalidIndex)
+run_cmake(REMOVE_AT-InvalidIndex)
+
+run_cmake(LENGTH-TooManyArguments)
+run_cmake(REMOVE_DUPLICATES-TooManyArguments)
+run_cmake(REVERSE-TooManyArguments)
+run_cmake(SORT-TooManyArguments)
+
+run_cmake(REMOVE_AT-NotList)
+run_cmake(REMOVE_DUPLICATES-NotList)
+run_cmake(REMOVE_ITEM-NotList)
+run_cmake(REVERSE-NotList)
+run_cmake(SORT-NotList)
diff --git a/Tests/RunCMake/list/SORT-NotList-result.txt b/Tests/RunCMake/list/SORT-NotList-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/SORT-NotList-stderr.txt b/Tests/RunCMake/list/SORT-NotList-stderr.txt
new file mode 100644
index 0000000..396c5b5
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-NotList.cmake:2 \(list\):
+  list sub-command SORT requires list to be present.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Sort-Nonexistent-List.cmake b/Tests/RunCMake/list/SORT-NotList.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Sort-Nonexistent-List.cmake
rename to Tests/RunCMake/list/SORT-NotList.cmake
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt b/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..d3fad60
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-TooManyArguments.cmake:1 \(list\):
+  list sub-command SORT only takes one argument.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Sort-Too-Many-Arguments.cmake b/Tests/RunCMake/list/SORT-TooManyArguments.cmake
similarity index 100%
rename from Tests/CMakeTests/List-Sort-Too-Many-Arguments.cmake
rename to Tests/RunCMake/list/SORT-TooManyArguments.cmake
diff --git a/Tests/RunCMake/set_property/COMPILE_DEFINITIONS-stdout.txt b/Tests/RunCMake/set_property/COMPILE_DEFINITIONS-stdout.txt
new file mode 100644
index 0000000..dd5bae1
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_DEFINITIONS-stdout.txt
@@ -0,0 +1,2 @@
+-- Target COMPILE_DEFINITIONS is 'a;b;c;d;;e'
+-- Directory COMPILE_DEFINITIONS is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/COMPILE_DEFINITIONS.cmake b/Tests/RunCMake/set_property/COMPILE_DEFINITIONS.cmake
new file mode 100644
index 0000000..f0c63bf
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_DEFINITIONS.cmake
@@ -0,0 +1,3 @@
+include(Common.cmake)
+test_target_property(COMPILE_DEFINITIONS)
+test_directory_property(COMPILE_DEFINITIONS)
diff --git a/Tests/RunCMake/set_property/COMPILE_FEATURES-stdout.txt b/Tests/RunCMake/set_property/COMPILE_FEATURES-stdout.txt
new file mode 100644
index 0000000..bd5a992
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_FEATURES-stdout.txt
@@ -0,0 +1 @@
+-- Target COMPILE_FEATURES is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/COMPILE_FEATURES.cmake b/Tests/RunCMake/set_property/COMPILE_FEATURES.cmake
new file mode 100644
index 0000000..1ab52ef
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_FEATURES.cmake
@@ -0,0 +1,2 @@
+include(Common.cmake)
+test_target_property(COMPILE_FEATURES)
diff --git a/Tests/RunCMake/set_property/COMPILE_OPTIONS-stdout.txt b/Tests/RunCMake/set_property/COMPILE_OPTIONS-stdout.txt
new file mode 100644
index 0000000..1a20501
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_OPTIONS-stdout.txt
@@ -0,0 +1,2 @@
+-- Target COMPILE_OPTIONS is 'a;b;c;d;;e'
+-- Directory COMPILE_OPTIONS is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/COMPILE_OPTIONS.cmake b/Tests/RunCMake/set_property/COMPILE_OPTIONS.cmake
new file mode 100644
index 0000000..75f0535
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_OPTIONS.cmake
@@ -0,0 +1,3 @@
+include(Common.cmake)
+test_target_property(COMPILE_OPTIONS)
+test_directory_property(COMPILE_OPTIONS)
diff --git a/Tests/RunCMake/set_property/Common.cmake b/Tests/RunCMake/set_property/Common.cmake
new file mode 100644
index 0000000..9d5e4f4
--- /dev/null
+++ b/Tests/RunCMake/set_property/Common.cmake
@@ -0,0 +1,28 @@
+macro(test_target_property PROP)
+  add_custom_target(CustomTarget)
+  set_property(TARGET CustomTarget PROPERTY ${PROP} x)
+  set_property(TARGET CustomTarget PROPERTY ${PROP})
+  set_property(TARGET CustomTarget APPEND PROPERTY ${PROP})
+  set_property(TARGET CustomTarget PROPERTY ${PROP} a)
+  set_property(TARGET CustomTarget APPEND PROPERTY ${PROP} "")
+  set_property(TARGET CustomTarget APPEND PROPERTY ${PROP} b c)
+  set_property(TARGET CustomTarget APPEND PROPERTY ${PROP})
+  set_property(TARGET CustomTarget APPEND PROPERTY ${PROP} "d;;e")
+  get_property(val TARGET CustomTarget PROPERTY ${PROP})
+  message(STATUS "Target ${PROP} is '${val}'")
+  set_property(TARGET CustomTarget PROPERTY ${PROP})
+endmacro()
+
+macro(test_directory_property PROP)
+  set_property(DIRECTORY PROPERTY ${PROP} x)
+  set_property(DIRECTORY PROPERTY ${PROP})
+  set_property(DIRECTORY APPEND PROPERTY ${PROP})
+  set_property(DIRECTORY PROPERTY ${PROP} a)
+  set_property(DIRECTORY APPEND PROPERTY ${PROP} "")
+  set_property(DIRECTORY APPEND PROPERTY ${PROP} b c)
+  set_property(DIRECTORY APPEND PROPERTY ${PROP})
+  set_property(DIRECTORY APPEND PROPERTY ${PROP} "d;;e")
+  get_property(val DIRECTORY PROPERTY ${PROP})
+  message(STATUS "Directory ${PROP} is '${val}'")
+  set_property(DIRECTORY PROPERTY ${PROP})
+endmacro()
diff --git a/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES-stdout.txt b/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES-stdout.txt
new file mode 100644
index 0000000..c957dd5
--- /dev/null
+++ b/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES-stdout.txt
@@ -0,0 +1,2 @@
+-- Target INCLUDE_DIRECTORIES is 'a;b;c;d;;e'
+-- Directory INCLUDE_DIRECTORIES is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES.cmake b/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES.cmake
new file mode 100644
index 0000000..c9a9151
--- /dev/null
+++ b/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES.cmake
@@ -0,0 +1,3 @@
+include(Common.cmake)
+test_target_property(INCLUDE_DIRECTORIES)
+test_directory_property(INCLUDE_DIRECTORIES)
diff --git a/Tests/RunCMake/set_property/LINK_LIBRARIES-stdout.txt b/Tests/RunCMake/set_property/LINK_LIBRARIES-stdout.txt
new file mode 100644
index 0000000..9a3988e
--- /dev/null
+++ b/Tests/RunCMake/set_property/LINK_LIBRARIES-stdout.txt
@@ -0,0 +1 @@
+-- Target LINK_LIBRARIES is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/LINK_LIBRARIES.cmake b/Tests/RunCMake/set_property/LINK_LIBRARIES.cmake
index 994e874..5155f59 100644
--- a/Tests/RunCMake/set_property/LINK_LIBRARIES.cmake
+++ b/Tests/RunCMake/set_property/LINK_LIBRARIES.cmake
@@ -1,7 +1,2 @@
-add_custom_target(CustomTarget)
-set_property(TARGET CustomTarget PROPERTY LINK_LIBRARIES)
-set_property(TARGET CustomTarget APPEND PROPERTY LINK_LIBRARIES)
-get_property(val TARGET CustomTarget PROPERTY LINK_LIBRARIES)
-if (NOT "${val}" STREQUAL "")
-  message(FATAL_ERROR "LINK_LIBRARIES value is '${val}' but should be ''")
-endif()
+include(Common.cmake)
+test_target_property(LINK_LIBRARIES)
diff --git a/Tests/RunCMake/set_property/RunCMakeTest.cmake b/Tests/RunCMake/set_property/RunCMakeTest.cmake
index 54e63f7..37c7124 100644
--- a/Tests/RunCMake/set_property/RunCMakeTest.cmake
+++ b/Tests/RunCMake/set_property/RunCMakeTest.cmake
@@ -1,3 +1,9 @@
 include(RunCMake)
 
+run_cmake(COMPILE_DEFINITIONS)
+run_cmake(COMPILE_FEATURES)
+run_cmake(COMPILE_OPTIONS)
+run_cmake(INCLUDE_DIRECTORIES)
 run_cmake(LINK_LIBRARIES)
+run_cmake(SOURCES)
+run_cmake(USER_PROP)
diff --git a/Tests/RunCMake/set_property/SOURCES-stdout.txt b/Tests/RunCMake/set_property/SOURCES-stdout.txt
new file mode 100644
index 0000000..921d5b1
--- /dev/null
+++ b/Tests/RunCMake/set_property/SOURCES-stdout.txt
@@ -0,0 +1 @@
+-- Target SOURCES is 'a;b;c;d;e'
diff --git a/Tests/RunCMake/set_property/SOURCES.cmake b/Tests/RunCMake/set_property/SOURCES.cmake
new file mode 100644
index 0000000..820641e
--- /dev/null
+++ b/Tests/RunCMake/set_property/SOURCES.cmake
@@ -0,0 +1,2 @@
+include(Common.cmake)
+test_target_property(SOURCES)
diff --git a/Tests/RunCMake/set_property/USER_PROP-stdout.txt b/Tests/RunCMake/set_property/USER_PROP-stdout.txt
new file mode 100644
index 0000000..107cc87
--- /dev/null
+++ b/Tests/RunCMake/set_property/USER_PROP-stdout.txt
@@ -0,0 +1,2 @@
+-- Target USER_PROP is 'a;b;c;d;;e'
+-- Directory USER_PROP is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/USER_PROP.cmake b/Tests/RunCMake/set_property/USER_PROP.cmake
new file mode 100644
index 0000000..aa0aa83
--- /dev/null
+++ b/Tests/RunCMake/set_property/USER_PROP.cmake
@@ -0,0 +1,3 @@
+include(Common.cmake)
+test_target_property(USER_PROP)
+test_directory_property(USER_PROP)
diff --git a/Tests/RunCMake/string/Append.cmake b/Tests/RunCMake/string/Append.cmake
new file mode 100644
index 0000000..2634274
--- /dev/null
+++ b/Tests/RunCMake/string/Append.cmake
@@ -0,0 +1,58 @@
+set(out)
+string(APPEND out)
+if(DEFINED out)
+  message(FATAL_ERROR "\"string(APPEND out)\" set out to \"${out}\"")
+endif()
+
+set(out "")
+string(APPEND out)
+if(NOT out STREQUAL "")
+  message(FATAL_ERROR "\"string(APPEND out)\" set out to \"${out}\"")
+endif()
+
+set(out x)
+string(APPEND out)
+if(NOT out STREQUAL "x")
+  message(FATAL_ERROR "\"string(APPEND out)\" set out to \"${out}\"")
+endif()
+
+
+set(out)
+string(APPEND out a)
+if(NOT out STREQUAL "a")
+  message(FATAL_ERROR "\"string(APPEND out a)\" set out to \"${out}\"")
+endif()
+
+set(out "")
+string(APPEND out a)
+if(NOT out STREQUAL "a")
+  message(FATAL_ERROR "\"string(APPEND out a)\" set out to \"${out}\"")
+endif()
+
+set(out x)
+string(APPEND out a)
+if(NOT out STREQUAL "xa")
+  message(FATAL_ERROR "\"string(APPEND out a)\" set out to \"${out}\"")
+endif()
+
+
+set(out x)
+string(APPEND out a "b")
+if(NOT out STREQUAL "xab")
+  message(FATAL_ERROR "\"string(APPEND out a \"b\")\" set out to \"${out}\"")
+endif()
+
+set(b)
+set(out x)
+string(APPEND out ${b})
+if(NOT out STREQUAL "x")
+  message(FATAL_ERROR "\"string(APPEND out \${b})\" set out to \"${out}\"")
+endif()
+
+set(b b)
+set(out x)
+string(APPEND out a "${b}" [[
+${c}]])
+if(NOT out STREQUAL "xab\${c}")
+  message(FATAL_ERROR "\"string(APPEND out a \"\${b}\" [[\${c}]])\" set out to \"${out}\"")
+endif()
diff --git a/Tests/RunCMake/string/AppendNoArgs-result.txt b/Tests/RunCMake/string/AppendNoArgs-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/string/AppendNoArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/string/AppendNoArgs-stderr.txt b/Tests/RunCMake/string/AppendNoArgs-stderr.txt
new file mode 100644
index 0000000..75ad427
--- /dev/null
+++ b/Tests/RunCMake/string/AppendNoArgs-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at AppendNoArgs.cmake:1 \(string\):
+  string sub-command APPEND requires at least one argument.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/string/AppendNoArgs.cmake b/Tests/RunCMake/string/AppendNoArgs.cmake
new file mode 100644
index 0000000..f54fb77
--- /dev/null
+++ b/Tests/RunCMake/string/AppendNoArgs.cmake
@@ -0,0 +1 @@
+string(APPEND)
diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake
index 89f7ea5..8067d9d 100644
--- a/Tests/RunCMake/string/RunCMakeTest.cmake
+++ b/Tests/RunCMake/string/RunCMakeTest.cmake
@@ -1,5 +1,8 @@
 include(RunCMake)
 
+run_cmake(Append)
+run_cmake(AppendNoArgs)
+
 run_cmake(Concat)
 run_cmake(ConcatNoArgs)
 
diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
index 533c6a1..8307607 100644
--- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
@@ -7,3 +7,4 @@ run_cmake(CMP0023-NEW-2)
 run_cmake(MixedSignature)
 run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses)
 run_cmake(SubDirTarget)
+run_cmake(SharedDepNotTarget)
diff --git a/Tests/RunCMake/target_link_libraries/SharedDepNotTarget.cmake b/Tests/RunCMake/target_link_libraries/SharedDepNotTarget.cmake
new file mode 100644
index 0000000..bab537e
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/SharedDepNotTarget.cmake
@@ -0,0 +1,10 @@
+enable_language(C)
+set(CMAKE_LINK_DEPENDENT_LIBRARY_DIRS 1)
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
+add_library(imported SHARED IMPORTED)
+set_target_properties(imported PROPERTIES
+  IMPORTED_LOCATION "imported"
+  IMPORTED_LINK_DEPENDENT_LIBRARIES "/path/to/libSharedDep.so"
+  )
+add_executable(empty empty.c)
+target_link_libraries(empty imported)
diff --git a/Tests/RunCMake/get_filename_component/CMakeLists.txt b/Tests/RunCMake/while/CMakeLists.txt
similarity index 100%
copy from Tests/RunCMake/get_filename_component/CMakeLists.txt
copy to Tests/RunCMake/while/CMakeLists.txt
diff --git a/Tests/RunCMake/while/EndAlone-result.txt b/Tests/RunCMake/while/EndAlone-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/while/EndAlone-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/while/EndAlone-stderr.txt b/Tests/RunCMake/while/EndAlone-stderr.txt
new file mode 100644
index 0000000..cd98687
--- /dev/null
+++ b/Tests/RunCMake/while/EndAlone-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at EndAlone.cmake:1 \(endwhile\):
+  endwhile An ENDWHILE command was found outside of a proper WHILE ENDWHILE
+  structure.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/While-Endwhile-Alone.cmake b/Tests/RunCMake/while/EndAlone.cmake
similarity index 100%
rename from Tests/CMakeTests/While-Endwhile-Alone.cmake
rename to Tests/RunCMake/while/EndAlone.cmake
diff --git a/Tests/RunCMake/while/EndAloneArgs-result.txt b/Tests/RunCMake/while/EndAloneArgs-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/while/EndAloneArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/while/EndAloneArgs-stderr.txt b/Tests/RunCMake/while/EndAloneArgs-stderr.txt
new file mode 100644
index 0000000..a8c043d
--- /dev/null
+++ b/Tests/RunCMake/while/EndAloneArgs-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at EndAloneArgs.cmake:1 \(endwhile\):
+  endwhile An ENDWHILE command was found outside of a proper WHILE ENDWHILE
+  structure.  Or its arguments did not match the opening WHILE command.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/While-Endwhile-Alone-Args.cmake b/Tests/RunCMake/while/EndAloneArgs.cmake
similarity index 100%
rename from Tests/CMakeTests/While-Endwhile-Alone-Args.cmake
rename to Tests/RunCMake/while/EndAloneArgs.cmake
diff --git a/Tests/RunCMake/while/EndMismatch-stderr.txt b/Tests/RunCMake/while/EndMismatch-stderr.txt
new file mode 100644
index 0000000..d7439e8
--- /dev/null
+++ b/Tests/RunCMake/while/EndMismatch-stderr.txt
@@ -0,0 +1,13 @@
+^CMake Warning \(dev\) at EndMismatch.cmake:3 \(include\):
+  A logical block opening on the line
+
+    .*/Tests/RunCMake/while/EndMismatch.cmake:1 \(while\)
+
+  closes on the line
+
+    .*/Tests/RunCMake/while/EndMismatch.cmake:2 \(endwhile\)
+
+  with mis-matching arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.$
diff --git a/Tests/CMakeTests/While-Endwhile-Mismatch.cmake b/Tests/RunCMake/while/EndMismatch.cmake
similarity index 100%
rename from Tests/CMakeTests/While-Endwhile-Mismatch.cmake
rename to Tests/RunCMake/while/EndMismatch.cmake
diff --git a/Tests/RunCMake/while/EndMissing-result.txt b/Tests/RunCMake/while/EndMissing-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/while/EndMissing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/while/EndMissing-stderr.txt b/Tests/RunCMake/while/EndMissing-stderr.txt
new file mode 100644
index 0000000..099a8b2
--- /dev/null
+++ b/Tests/RunCMake/while/EndMissing-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at CMakeLists.txt:3 \(include\):
+  A logical block opening on the line
+
+    .*/Tests/RunCMake/while/EndMissing.cmake:1 \(while\)
+
+  is not closed.$
diff --git a/Tests/CMakeTests/While-Missing-Endwhile.cmake b/Tests/RunCMake/while/EndMissing.cmake
similarity index 100%
rename from Tests/CMakeTests/While-Missing-Endwhile.cmake
rename to Tests/RunCMake/while/EndMissing.cmake
diff --git a/Tests/RunCMake/while/MissingArgument-result.txt b/Tests/RunCMake/while/MissingArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/while/MissingArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/while/MissingArgument-stderr.txt b/Tests/RunCMake/while/MissingArgument-stderr.txt
new file mode 100644
index 0000000..7ff0971
--- /dev/null
+++ b/Tests/RunCMake/while/MissingArgument-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at MissingArgument.cmake:1 \(while\):
+  while called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/While-Missing-Argument.cmake b/Tests/RunCMake/while/MissingArgument.cmake
similarity index 100%
rename from Tests/CMakeTests/While-Missing-Argument.cmake
rename to Tests/RunCMake/while/MissingArgument.cmake
diff --git a/Tests/RunCMake/while/RunCMakeTest.cmake b/Tests/RunCMake/while/RunCMakeTest.cmake
new file mode 100644
index 0000000..7da80ac
--- /dev/null
+++ b/Tests/RunCMake/while/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(MissingArgument)
+run_cmake(EndMissing)
+run_cmake(EndMismatch)
+run_cmake(EndAlone)
+run_cmake(EndAloneArgs)
diff --git a/Tests/SimpleInstall/CMakeLists.txt b/Tests/SimpleInstall/CMakeLists.txt
index cc3c3be..e365076 100644
--- a/Tests/SimpleInstall/CMakeLists.txt
+++ b/Tests/SimpleInstall/CMakeLists.txt
@@ -209,9 +209,9 @@ else()
     ARCHIVE DESTINATION MyTest/lib/static
     OPTIONAL # for coverage...target should always exist
     )
-  install(FILES lib1.h DESTINATION MyTest/include/foo)
+  install(FILES lib1.h DESTINATION MyTest/include/$<1:foo>$<0:/wrong>)
   install(FILES lib2.h
-    DESTINATION MyTest/include/foo
+    DESTINATION $<1:MyTest/include/foo>$<0:/wrong>
     COMPONENT Development
     PERMISSIONS OWNER_READ OWNER_WRITE
     RENAME lib2renamed.h
@@ -252,7 +252,7 @@ else()
   file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
   file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
   install(
-    DIRECTORY TestSubDir scripts/ DESTINATION MyTest/share
+    DIRECTORY TestSubDir scripts/ DESTINATION $<1:MyTest/share>$<0:/wrong>
     FILE_PERMISSIONS OWNER_READ OWNER_WRITE
     DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                           GROUP_READ GROUP_EXECUTE
@@ -263,14 +263,14 @@ else()
 
   # Alternate directory installation for coverage.
   install(
-    DIRECTORY scripts/ DESTINATION MyTest/share/alt
+    DIRECTORY scripts/ DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
     COMPONENT Development
     USE_SOURCE_PERMISSIONS
     PATTERN "CVS" EXCLUDE
     REGEX "\\.txt$" EXCLUDE
     )
   install(
-    DIRECTORY TestSubDir DESTINATION MyTest/share/alt
+    DIRECTORY TestSubDir DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
     FILE_PERMISSIONS OWNER_READ OWNER_WRITE
     DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                           GROUP_READ GROUP_EXECUTE
diff --git a/Tests/SimpleInstallS2/CMakeLists.txt b/Tests/SimpleInstallS2/CMakeLists.txt
index cc3c3be..e365076 100644
--- a/Tests/SimpleInstallS2/CMakeLists.txt
+++ b/Tests/SimpleInstallS2/CMakeLists.txt
@@ -209,9 +209,9 @@ else()
     ARCHIVE DESTINATION MyTest/lib/static
     OPTIONAL # for coverage...target should always exist
     )
-  install(FILES lib1.h DESTINATION MyTest/include/foo)
+  install(FILES lib1.h DESTINATION MyTest/include/$<1:foo>$<0:/wrong>)
   install(FILES lib2.h
-    DESTINATION MyTest/include/foo
+    DESTINATION $<1:MyTest/include/foo>$<0:/wrong>
     COMPONENT Development
     PERMISSIONS OWNER_READ OWNER_WRITE
     RENAME lib2renamed.h
@@ -252,7 +252,7 @@ else()
   file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
   file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
   install(
-    DIRECTORY TestSubDir scripts/ DESTINATION MyTest/share
+    DIRECTORY TestSubDir scripts/ DESTINATION $<1:MyTest/share>$<0:/wrong>
     FILE_PERMISSIONS OWNER_READ OWNER_WRITE
     DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                           GROUP_READ GROUP_EXECUTE
@@ -263,14 +263,14 @@ else()
 
   # Alternate directory installation for coverage.
   install(
-    DIRECTORY scripts/ DESTINATION MyTest/share/alt
+    DIRECTORY scripts/ DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
     COMPONENT Development
     USE_SOURCE_PERMISSIONS
     PATTERN "CVS" EXCLUDE
     REGEX "\\.txt$" EXCLUDE
     )
   install(
-    DIRECTORY TestSubDir DESTINATION MyTest/share/alt
+    DIRECTORY TestSubDir DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
     FILE_PERMISSIONS OWNER_READ OWNER_WRITE
     DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                           GROUP_READ GROUP_EXECUTE
diff --git a/Tests/SwiftMix/CMain.c b/Tests/SwiftMix/CMain.c
new file mode 100644
index 0000000..13e2f8c
--- /dev/null
+++ b/Tests/SwiftMix/CMain.c
@@ -0,0 +1,4 @@
+extern int ObjCMain(int argc, char const* const argv[]);
+int main(int argc, char* argv[]) {
+  return ObjCMain(argc, argv);
+}
diff --git a/Tests/SwiftMix/CMakeLists.txt b/Tests/SwiftMix/CMakeLists.txt
new file mode 100644
index 0000000..5e50470
--- /dev/null
+++ b/Tests/SwiftMix/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.3)
+project(SwiftMix C Swift)
+
+add_executable(SwiftMix CMain.c ObjCMain.m SwiftMain.swift ObjC-Swift.h)
+set_property(TARGET SwiftMix PROPERTY XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "ObjC-Swift.h")
diff --git a/Tests/SwiftMix/ObjC-Swift.h b/Tests/SwiftMix/ObjC-Swift.h
new file mode 100644
index 0000000..e69de29
diff --git a/Tests/SwiftMix/ObjCMain.m b/Tests/SwiftMix/ObjCMain.m
new file mode 100644
index 0000000..7fa90ae
--- /dev/null
+++ b/Tests/SwiftMix/ObjCMain.m
@@ -0,0 +1,4 @@
+#import "SwiftMix-Swift.h"
+int ObjCMain(int argc, char const* const argv[]) {
+  return [SwiftMainClass SwiftMain:argc argv:argv];
+}
diff --git a/Tests/SwiftMix/SwiftMain.swift b/Tests/SwiftMix/SwiftMain.swift
new file mode 100644
index 0000000..3629ac8
--- /dev/null
+++ b/Tests/SwiftMix/SwiftMain.swift
@@ -0,0 +1,12 @@
+import Foundation
+
+ at objc class SwiftMainClass : NSObject {
+  class func SwiftMain(argc:Int, argv:UnsafePointer<UnsafePointer<CChar>>) -> Int32 {
+    dump("argc: \(argc)")
+    for (var i = 0; i < argc; ++i) {
+      let argi = String.fromCString(argv[i])
+      dump("arg[\(i)]: \(argi)");
+    }
+    return 0;
+  }
+}
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
new file mode 100644
index 0000000..5cb9739
--- /dev/null
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.3)
+project(SwiftOnly Swift)
+
+add_executable(SwiftOnly main.swift)
diff --git a/Tests/SwiftOnly/main.swift b/Tests/SwiftOnly/main.swift
new file mode 100644
index 0000000..28560d0
--- /dev/null
+++ b/Tests/SwiftOnly/main.swift
@@ -0,0 +1 @@
+dump("SwiftOnly")
diff --git a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt
index 3ee1855..f68e38e 100644
--- a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt
+++ b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt
@@ -35,12 +35,12 @@ add_library(hello SHARED hello.f)
 add_library(world SHARED world.f)
 target_link_libraries(hello world)
 if(CMAKE_Fortran_COMPILER_ID MATCHES SunPro)
-  target_link_libraries(hello fsu)
+  target_link_libraries(hello PRIVATE fsu)
   if(CMAKE_Fortran_PLATFORM_ID MATCHES SunOS)
-    target_link_libraries(hello sunmath m)
+    target_link_libraries(hello PRIVATE sunmath m)
     test_sunquad(CMAKE_HAS_SUNQUAD)
     if(CMAKE_HAS_SUNQUAD)
-      target_link_libraries(hello sunquad)
+      target_link_libraries(hello PRIVATE sunquad)
     endif()
   endif()
 endif()
diff --git a/Tests/VSNsightTegra/CMakeLists.txt b/Tests/VSNsightTegra/CMakeLists.txt
index 10f55d9..61a04fd 100644
--- a/Tests/VSNsightTegra/CMakeLists.txt
+++ b/Tests/VSNsightTegra/CMakeLists.txt
@@ -1,10 +1,16 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.3)
 project(VSNsightTegra C CXX)
 
+set(CMAKE_ANDROID_ARCH armv7-a-hard)
+set(CMAKE_ANDROID_STL_TYPE stlport_shared)
 set(CMAKE_ANDROID_API_MIN 9)
 set(CMAKE_ANDROID_API 15)
 set(CMAKE_ANDROID_GUI 1)
 
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+
 set(FIRST_C_FILES
   jni/first.c
   jni/first.h
@@ -38,3 +44,14 @@ add_executable(twolib-second
 target_include_directories(twolib-second PUBLIC jni)
 target_link_libraries(twolib-second twolib-first)
 target_link_libraries(twolib-second m) # test linking to library by name
+
+set_property(TARGET twolib-second PROPERTY C_STANDARD 11)
+set_target_properties(twolib-second PROPERTIES ANDROID_SKIP_ANT_STEP 1)
+set_target_properties(twolib-second PROPERTIES ANDROID_PROGUARD 1)
+set_target_properties(twolib-second PROPERTIES ANDROID_PROGUARD_CONFIG_PATH proguard-android.txt)
+set_target_properties(twolib-second PROPERTIES ANDROID_SECURE_PROPS_PATH /definitely/insecure)
+
+set_property(TARGET twolib-second PROPERTY ANDROID_NATIVE_LIB_DIRECTORIES $<TARGET_FILE_DIR:twolib-second>)
+set_property(TARGET twolib-second PROPERTY ANDROID_NATIVE_LIB_DEPENDENCIES $<TARGET_FILE_NAME:twolib-second>)
+
+set_property(TARGET twolib-second PROPERTY ANDROID_JAR_DIRECTORIES $<TARGET_FILE_DIR:twolib-first>)
diff --git a/Tests/VSNsightTegra/proguard-android.txt b/Tests/VSNsightTegra/proguard-android.txt
new file mode 100644
index 0000000..fe73bae
--- /dev/null
+++ b/Tests/VSNsightTegra/proguard-android.txt
@@ -0,0 +1,57 @@
+# This is a configuration file for ProGuard.
+# http://proguard.sourceforge.net/index.html#manual/usage.html
+
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-verbose
+
+# Optimization is turned off by default. Dex does not like code run
+# through the ProGuard optimize and preverify steps (and performs some
+# of these optimizations on its own).
+-dontoptimize
+-dontpreverify
+# Note that if you want to enable optimization, you cannot just
+# include optimization flags in your own project configuration file;
+# instead you will need to point to the
+# "proguard-android-optimize.txt" file instead of this one from your
+# project.properties file.
+
+-keepattributes *Annotation*
+-keep public class com.google.vending.licensing.ILicensingService
+-keep public class com.android.vending.licensing.ILicensingService
+
+# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+# keep setters in Views so that animations can still work.
+# see http://proguard.sourceforge.net/manual/examples.html#beans
+-keepclassmembers public class * extends android.view.View {
+   void set*(***);
+   *** get*();
+}
+
+# We want to keep methods in Activity that could be used in the XML attribute onClick
+-keepclassmembers class * extends android.app.Activity {
+   public void *(android.view.View);
+}
+
+# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+  public static final android.os.Parcelable$Creator *;
+}
+
+-keepclassmembers class **.R$* {
+    public static <fields>;
+}
+
+# The support library contains references to newer platform versions.
+# Don't warn about those in case this app is linking against an older
+# platform version.  We know about them, and they are safe.
+-dontwarn android.support.**
diff --git a/Tests/VSResource/CMakeLists.txt b/Tests/VSResource/CMakeLists.txt
index 17eb041..3b9cfc3 100644
--- a/Tests/VSResource/CMakeLists.txt
+++ b/Tests/VSResource/CMakeLists.txt
@@ -46,7 +46,10 @@ else()
   include_directories(${CMAKE_CURRENT_BINARY_DIR})
 endif()
 
+add_library(ResourceLib STATIC lib.cpp lib.rc)
+
 add_executable(VSResource main.cpp test.rc)
+target_link_libraries(VSResource ResourceLib)
 
 set_property(TARGET VSResource
   PROPERTY VS_GLOBAL_CMakeTestVsGlobalVariable "test val")
diff --git a/Tests/VSResource/lib.cpp b/Tests/VSResource/lib.cpp
new file mode 100644
index 0000000..006e3e4
--- /dev/null
+++ b/Tests/VSResource/lib.cpp
@@ -0,0 +1 @@
+int lib() { return 0; }
diff --git a/Tests/VSResource/lib.rc b/Tests/VSResource/lib.rc
new file mode 100644
index 0000000..1ffade6
--- /dev/null
+++ b/Tests/VSResource/lib.rc
@@ -0,0 +1,4 @@
+STRINGTABLE
+BEGIN
+  1234 "5"
+END
diff --git a/Tests/VSResource/main.cpp b/Tests/VSResource/main.cpp
index 7ee0c74..ccf700c 100644
--- a/Tests/VSResource/main.cpp
+++ b/Tests/VSResource/main.cpp
@@ -1,6 +1,8 @@
 #include <windows.h>
 #include <stdio.h>
 
+extern int lib();
+
 struct x
 {
   const char *txt;
@@ -76,5 +78,5 @@ int main(int argc, char** argv)
       }
     }
 
-  return ret;
+  return ret + lib();
 }
diff --git a/Tests/VSWinStorePhone/CMakeLists.txt b/Tests/VSWinStorePhone/CMakeLists.txt
index 8357d5f..ae82755 100644
--- a/Tests/VSWinStorePhone/CMakeLists.txt
+++ b/Tests/VSWinStorePhone/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.0)
 project(VSWinStorePhone)
-
-if(MSVC_VERSION GREATER 1700)
+if(MSVC_VERSION GREATER 1899)
+  set(COMPILER_VERSION "14")
+elseif(MSVC_VERSION GREATER 1700)
   set(COMPILER_VERSION "12")
 elseif(MSVC_VERSION GREATER 1600)
   set(COMPILER_VERSION "11")
@@ -91,6 +92,7 @@ elseif (NOT "${PLATFORM}" STREQUAL "DESKTOP")
     set(ASSET_FILES ${ASSET_FILES}
     Direct3DApp1/Assets/Logo.png
     Direct3DApp1/Assets/SmallLogo.png
+    Direct3DApp1/Assets/SmallLogo44x44.png
     Direct3DApp1/Assets/SplashScreen.png
     Direct3DApp1/Assets/StoreLogo.png
     )
@@ -124,4 +126,15 @@ source_group("Resource Files" FILES ${RESOURCE_FILES})
 
 add_executable(${EXE_NAME} WIN32 ${SOURCE_FILES} ${HEADER_FILES} ${RESOURCE_FILES})
 set_property(TARGET ${EXE_NAME} PROPERTY VS_WINRT_COMPONENT TRUE)
+
+string(SUBSTRING "${CMAKE_SYSTEM_VERSION}" 0, 4, SHORT_VERSION)
+
+if("${SHORT_VERSION}" STREQUAL "10.0")
+  message(STATUS "Targeting Windows 10. Setting Extensions to version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+  set_property(TARGET ${EXE_NAME} PROPERTY VS_DESKTOP_EXTENSIONS_VERSION "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+  set_property(TARGET ${EXE_NAME} PROPERTY VS_MOBILE_EXTENSIONS_VERSION "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+  set_property(TARGET ${EXE_NAME} PROPERTY VS_IOT_EXTENSIONS_VERSION "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+endif()
+
+
 target_link_libraries(${EXE_NAME} d3d11)
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo44x44.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo44x44.png
new file mode 100644
index 0000000..28810b7
Binary files /dev/null and b/Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo44x44.png differ
diff --git a/Tests/VSWinStorePhone/cmake/Package_vc14.store.appxmanifest.in b/Tests/VSWinStorePhone/cmake/Package_vc14.store.appxmanifest.in
new file mode 100644
index 0000000..6b27ab7
--- /dev/null
+++ b/Tests/VSWinStorePhone/cmake/Package_vc14.store.appxmanifest.in
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package
+  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
+  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
+  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
+  IgnorableNamespaces="uap mp">
+
+  <Identity Name="@PACKAGE_GUID@" Publisher="CN=mgong" Version="1.1.0.0" />
+  <mp:PhoneIdentity PhoneProductId="@PACKAGE_GUID@" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
+
+  <Properties>
+    <DisplayName>@SHORT_NAME@</DisplayName>
+    <PublisherDisplayName>mgong</PublisherDisplayName>
+    <Logo>Assets/StoreLogo.png</Logo>
+  </Properties>
+
+  <Dependencies>
+    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.65535.65535" />
+  </Dependencies>
+
+  <Resources>
+    <Resource Language="x-generate" />
+  </Resources>
+  <Applications>
+    <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="@SHORT_NAME at .App">
+      <uap:VisualElements
+        DisplayName="@SHORT_NAME@"
+        Description="@SHORT_NAME@"
+        BackgroundColor="#336699"
+        Square150x150Logo="Assets/Logo.png"
+        Square44x44Logo="Assets/SmallLogo44x44.png">
+        <uap:SplashScreen Image="Assets/SplashScreen.png" />
+      </uap:VisualElements>
+    </Application>
+  </Applications>
+</Package>
diff --git a/Tests/iOSNavApp/CMakeLists.txt b/Tests/iOSNavApp/CMakeLists.txt
index 12c3ada..1fc33e0 100644
--- a/Tests/iOSNavApp/CMakeLists.txt
+++ b/Tests/iOSNavApp/CMakeLists.txt
@@ -3,7 +3,6 @@ project(NavApp3)
 
 set(CMAKE_OSX_SYSROOT iphoneos4.3)
 set(CMAKE_OSX_ARCHITECTURES "armv6;armv7;i386")
-set(CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos;-iphonesimulator")
 
 include_directories(
   ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/Utilities/Doxygen/doc_makeall.sh.in b/Utilities/Doxygen/doc_makeall.sh.in
index ed7b521..fceafdd 100755
--- a/Utilities/Doxygen/doc_makeall.sh.in
+++ b/Utilities/Doxygen/doc_makeall.sh.in
@@ -130,7 +130,7 @@ export RESULTING_HTML_TARZ_ARCHIVE_FILE="$DOXTEMP/$PROJECT_NAME-html.tar.gz"
 
 if test "x at VTK_SOURCE_DIR@" != "x" ; then
   if test "x$PERL_PROG" != "xNOTFOUND" ; then
-    $PERL_PROG "$PATH_TO_VTK_DOX_SCRIPTS/doc_contributors.pl" \
+    "$PERL_PROG" "$PATH_TO_VTK_DOX_SCRIPTS/doc_contributors.pl" \
         --authors  "$SOURCE_DIR/Utilities/Doxygen/authors.txt" \
         --cachedir "$DOXTEMP/cache" \
         --class_group '^(cm[A-Z0-9][A-Za-z0-9]+)\.(?:c|cpp|cxx|h|fl)$' \
@@ -158,7 +158,7 @@ if test "x at VTK_SOURCE_DIR@" != "x" ; then
   fi
 
   if test "x$GNUPLOT_PROG" != "xNOTFOUND" ; then
-    $GNUPLOT_PROG "$DOXTEMP/contrib/history.plt"
+    "$GNUPLOT_PROG" "$DOXTEMP/contrib/history.plt"
   fi
 fi
 
@@ -168,7 +168,7 @@ fi
 if test "x$DOXYGEN_PROG" != "xNOTFOUND" ; then
 
     if test "x$RM_PROG" != "xNOTFOUND" ; then
-        $RM_PROG -fr "$OUTPUT_DIRECTORY"
+        "$RM_PROG" -fr "$OUTPUT_DIRECTORY"
     fi
 
     "$DOXYGEN_PROG" "$DOXYFILE"
@@ -182,7 +182,7 @@ fi
 
 if test "x at VTK_SOURCE_DIR@" != "x" ; then
   if test "x$PERL_PROG" != "xNOTFOUND" ; then
-    $PERL_PROG "$PATH_TO_VTK_DOX_SCRIPTS/doc_rmpath.pl" \
+    "$PERL_PROG" "$PATH_TO_VTK_DOX_SCRIPTS/doc_rmpath.pl" \
         --verbose \
         --to "$INTERMEDIATE_DOX_DIR" \
         --html "$OUTPUT_DIRECTORY/html"
@@ -198,7 +198,7 @@ if test "x$COMPILE_HTML_HELP" == "xON" ; then
         if test "x$HHC_PROG" != "xNOTFOUND" ; then
             "$HHC_PROG" index.hhp
             if test "x$MV_PROG" != "xNOTFOUND" ; then
-                $MV_PROG -f index.chm "$RESULTING_HTML_HELP_FILE"
+                "$MV_PROG" -f index.chm "$RESULTING_HTML_HELP_FILE"
             fi
        fi
    fi
@@ -212,15 +212,15 @@ if test "x$CREATE_HTML_TARZ_ARCHIVE" == "xON" ; then
         cd "$OUTPUT_DIRECTORY"
         if test "x$TAR_PROG" != "xNOTFOUND" ; then
             if test "x$RM_PROG" != "xNOTFOUND" ; then
-                $RM_PROG -f html.tar
+                "$RM_PROG" -f html.tar
             fi
-            $TAR_PROG -cf html.tar html
+            "$TAR_PROG" -cf html.tar html
             if test "x$GZIP_PROG" != "xNOTFOUND" ; then
                 if test "x$RM_PROG" != "xNOTFOUND" ; then
-                    $RM_PROG -f html.tar.gz
+                    "$RM_PROG" -f html.tar.gz
                 fi
-                $GZIP_PROG html.tar
-                $MV_PROG -f html.tar.gz "$RESULTING_HTML_TARZ_ARCHIVE_FILE"
+                "$GZIP_PROG" html.tar
+                "$MV_PROG" -f html.tar.gz "$RESULTING_HTML_TARZ_ARCHIVE_FILE"
             fi
        fi
    fi
@@ -230,18 +230,18 @@ fi
 # Clean-up.
 
 if test "x$RM_PROG" != "xNOTFOUND" ; then
-    $RM_PROG -fr "$INTERMEDIATE_DOX_DIR"
+    "$RM_PROG" -fr "$INTERMEDIATE_DOX_DIR"
 
     if test "x$DOWNLOAD_VTK_TAGFILE" == "xON" ; then
         if test "x$VTK_TAGFILE" != "x" ; then
-            $RM_PROG -f "$VTK_TAGFILE_DEST_DIR/$VTK_TAGFILE"
+            "$RM_PROG" -f "$VTK_TAGFILE_DEST_DIR/$VTK_TAGFILE"
         fi
     fi
 
     if test "x$COMPILE_HTML_HELP" == "xON" ; then
         if test "x$RESULTING_HTML_HELP_FILE" != "x" ; then
             if test "x$ALLOW_ERASE_OUTPUT_DIRECTORY" == "xON" ; then
-                $RM_PROG -fr "$OUTPUT_DIRECTORY"
+                "$RM_PROG" -fr "$OUTPUT_DIRECTORY"
             fi
         fi
     fi
diff --git a/Utilities/Release/Cygwin/README.cygwin.in b/Utilities/Release/Cygwin/README.cygwin.in
index 6c42a4c..17cf2a1 100644
--- a/Utilities/Release/Cygwin/README.cygwin.in
+++ b/Utilities/Release/Cygwin/README.cygwin.in
@@ -8,7 +8,7 @@ Build requirements
   make
 
 Canonical homepage:
-  http://www.cmake.org
+  https://cmake.org
 
 Canonical download:
   ftp://www.cmake.org/pub/cmake/
diff --git a/Utilities/Release/create-cmake-release.cmake b/Utilities/Release/create-cmake-release.cmake
index 19f4cb1..4cfa2ed 100644
--- a/Utilities/Release/create-cmake-release.cmake
+++ b/Utilities/Release/create-cmake-release.cmake
@@ -11,7 +11,6 @@ set(RELEASE_SCRIPTS_BATCH_1
   dashmacmini5_release.cmake  # Mac Darwin64 universal x86_64;i386
   magrathea_release.cmake     # Linux
   linux64_release.cmake       # Linux x86_64
-  ibm_aix_release.cmake       # AIX
 )
 
 set(RELEASE_SCRIPTS_BATCH_2
@@ -55,6 +54,7 @@ mkdir \${name}-build &&
 cd \${name}-build &&
 \"${CMAKE_COMMAND}\" ../\${name}-src/Utilities/Sphinx \\
   -DCMAKE_INSTALL_PREFIX=\"\$inst/\" \\
+  -DCMAKE_DOC_DIR=doc/cmake \\
   -DSPHINX_EXECUTABLE=\"${SPHINX_EXECUTABLE}\" \\
   -DSPHINX_HTML=ON -DSPHINX_MAN=ON &&
 make install &&
diff --git a/Utilities/Release/dash2win64_cygwin.cmake b/Utilities/Release/dash2win64_cygwin.cmake
index ac3c527..c0cd761 100644
--- a/Utilities/Release/dash2win64_cygwin.cmake
+++ b/Utilities/Release/dash2win64_cygwin.cmake
@@ -1,5 +1,6 @@
 set(CMAKE_RELEASE_DIRECTORY "c:/cygwin/home/dashboard/CMakeReleaseCygwin")
 set(PROCESSORS 9)
+set(BOOTSTRAP_ARGS "")
 set(MAKE_PROGRAM "make")
 set(MAKE "${MAKE_PROGRAM} -j8")
 set(HOST dash2win64)
@@ -12,6 +13,7 @@ CTEST_TEST_TIMEOUT:STRING=7200
 DART_TESTING_TIMEOUT:STRING=7200
 SPHINX_HTML:BOOL=ON
 SPHINX_MAN:BOOL=ON
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
 ")
 set(CXX g++)
 set(CC  gcc)
diff --git a/Utilities/Release/dash2win64_release.cmake b/Utilities/Release/dash2win64_release.cmake
index 2511db4..ecfd7c5 100644
--- a/Utilities/Release/dash2win64_release.cmake
+++ b/Utilities/Release/dash2win64_release.cmake
@@ -1,6 +1,6 @@
 set(CMAKE_RELEASE_DIRECTORY "c:/cygwin/home/dashboard/CMakeReleaseDirectory")
 set(CONFIGURE_WITH_CMAKE TRUE)
-set(CMAKE_CONFIGURE_PATH "c:/Program\\ Files\\ \\(x86\\)/CMake\\ 2.8/bin/cmake.exe")
+set(CMAKE_CONFIGURE_PATH "c:/Program\\ Files\\ \\(x86\\)/CMake/bin/cmake.exe")
 set(PROCESSORS 8)
 set(HOST dash2win64)
 set(CPACK_BINARY_GENERATORS "NSIS ZIP")
@@ -8,12 +8,14 @@ set(CPACK_SOURCE_GENERATORS "ZIP")
 set(MAKE_PROGRAM "make")
 set(MAKE "${MAKE_PROGRAM} -j8")
 set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release
+CMAKE_DOC_DIR:STRING=doc/cmake
 CMAKE_USE_OPENSSL:BOOL=OFF
 CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
 CMAKE_Fortran_COMPILER:FILEPATH=FALSE
 CMAKE_GENERATOR:INTERNAL=Unix Makefiles
 BUILD_QtDialog:BOOL:=TRUE
 CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
 QT_QMAKE_EXECUTABLE:FILEPATH=c:/Dashboards/Support/qt-build/Qt/bin/qmake.exe
 ")
 get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
diff --git a/Utilities/Release/dashmacmini2_release.cmake b/Utilities/Release/dashmacmini2_release.cmake
index ba82aab..cd4c5a1 100644
--- a/Utilities/Release/dashmacmini2_release.cmake
+++ b/Utilities/Release/dashmacmini2_release.cmake
@@ -1,7 +1,7 @@
 set(PROCESSORS 2)
 set(CMAKE_RELEASE_DIRECTORY /Users/kitware/CMakeReleaseDirectory)
 set(USER_OVERRIDE "set(CMAKE_CXX_LINK_EXECUTABLE \\\"gcc  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>  -shared-libgcc -lstdc++-static\\\")")
-set(INSTALL_PREFIX /)
+set(BOOTSTRAP_ARGS "--prefix=/ --docdir=doc/cmake")
 set(HOST dashmacmini2)
 set(MAKE_PROGRAM "make")
 set(MAKE "${MAKE_PROGRAM} -j2")
@@ -18,6 +18,7 @@ CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
 CPACK_SYSTEM_NAME:STRING=Darwin-universal
 BUILD_QtDialog:BOOL=TRUE
 CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
 QT_QMAKE_EXECUTABLE:FILEPATH=/Users/kitware/Support/qt-4.8.0/install/bin/qmake
 ")
 get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
diff --git a/Utilities/Release/dashmacmini5_release.cmake b/Utilities/Release/dashmacmini5_release.cmake
index bc95982..b147013 100644
--- a/Utilities/Release/dashmacmini5_release.cmake
+++ b/Utilities/Release/dashmacmini5_release.cmake
@@ -1,7 +1,7 @@
 set(PROCESSORS 4)
 set(CMAKE_RELEASE_DIRECTORY /Users/kitware/CMakeReleaseDirectory)
 # set(USER_OVERRIDE "set(CMAKE_CXX_LINK_EXECUTABLE \\\"gcc  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>  -shared-libgcc -lstdc++-static\\\")")
-set(INSTALL_PREFIX /)
+set(BOOTSTRAP_ARGS "--prefix=/ --docdir=doc/cmake")
 set(HOST dashmacmini5)
 set(MAKE_PROGRAM "make")
 set(MAKE "${MAKE_PROGRAM} -j5")
@@ -20,7 +20,8 @@ CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
 CPACK_SYSTEM_NAME:STRING=Darwin-x86_64
 BUILD_QtDialog:BOOL=TRUE
 CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE
-QT_QMAKE_EXECUTABLE:FILEPATH=/Users/kitware/Support/qt-4.8.0/install/bin/qmake
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
+QT_QMAKE_EXECUTABLE:FILEPATH=/Users/kitware/Support/qt-4.8.6/install/bin/qmake
 ")
 get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
 include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/ibm_aix_release.cmake b/Utilities/Release/ibm_aix_release.cmake
deleted file mode 100644
index 5a6efe6..0000000
--- a/Utilities/Release/ibm_aix_release.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-set(CMAKE_RELEASE_DIRECTORY "/bench1/noibm34/CMakeReleaseDirectory")
-set(PROCESSORS 64)
-set(HOST "ibm-backend")
-set(SCRIPT_NAME aix)
-set(MAKE_PROGRAM "make")
-set(CC "xlc_r")
-set(CXX "xlC_r")
-set(FC "xlf")
-set(LDFLAGS "-Wl,-bmaxdata:0x80000000") # Push "Segmentation fault in extend_brk" over horizon
-set(INITIAL_CACHE "
-CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-")
-get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
-include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/linux64_release.cmake b/Utilities/Release/linux64_release.cmake
index 513f42f..81442e7 100644
--- a/Utilities/Release/linux64_release.cmake
+++ b/Utilities/Release/linux64_release.cmake
@@ -1,4 +1,5 @@
 set(PROCESSORS 4)
+set(BOOTSTRAP_ARGS "--docdir=doc/cmake")
 set(HOST linux64)
 set(MAKE_PROGRAM "make")
 set(CC /opt/gcc-4.9.2/bin/gcc)
@@ -11,12 +12,13 @@ CURSES_LIBRARY:FILEPATH=/home/kitware/ncurses-5.9/lib/libncurses.a
 CURSES_INCLUDE_PATH:PATH=/home/kitware/ncurses-5.9/include
 FORM_LIBRARY:FILEPATH=/home/kitware/ncurses-5.9/lib/libform.a
 CMAKE_USE_OPENSSL:BOOL=ON
-OPENSSL_CRYPTO_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.1j/lib/libcrypto.a
-OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.0.1j/include
-OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.1j/lib/libssl.a
+OPENSSL_CRYPTO_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.2d/lib/libcrypto.a
+OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.0.2d/include
+OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.2d/lib/libssl.a
 CPACK_SYSTEM_NAME:STRING=Linux-x86_64
 BUILD_QtDialog:BOOL:=TRUE
 CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
 QT_QMAKE_EXECUTABLE:FILEPATH=/home/kitware/qt-4.8.6/bin/qmake
 ")
 get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
diff --git a/Utilities/Release/magrathea_release.cmake b/Utilities/Release/magrathea_release.cmake
index 1bf75dd..0634dda 100644
--- a/Utilities/Release/magrathea_release.cmake
+++ b/Utilities/Release/magrathea_release.cmake
@@ -1,4 +1,5 @@
 set(PROCESSORS 1)
+set(BOOTSTRAP_ARGS "--docdir=doc/cmake")
 set(HOST magrathea)
 set(MAKE_PROGRAM "make")
 set(CC gcc332s)
@@ -11,12 +12,13 @@ CURSES_LIBRARY:FILEPATH=/usr/i686-gcc-332s/lib/libncurses.a
 CURSES_INCLUDE_PATH:PATH=/usr/i686-gcc-332s/include/ncurses
 FORM_LIBRARY:FILEPATH=/usr/i686-gcc-332s/lib/libform.a
 CMAKE_USE_OPENSSL:BOOL=ON
-OPENSSL_CRYPTO_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.1g-install/lib/libcrypto.a
-OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.0.1g-install/include
-OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.1g-install/lib/libssl.a
+OPENSSL_CRYPTO_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.2d/lib/libcrypto.a
+OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.0.2d/include
+OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.2d/lib/libssl.a
 CPACK_SYSTEM_NAME:STRING=Linux-i386
 BUILD_QtDialog:BOOL:=TRUE
 CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
 QT_QMAKE_EXECUTABLE:FILEPATH=/home/kitware/qt-4.43-install/bin/qmake
 ")
 get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
diff --git a/Utilities/Release/release_cmake.sh.in b/Utilities/Release/release_cmake.sh.in
index 76fdb3a..06e720f 100755
--- a/Utilities/Release/release_cmake.sh.in
+++ b/Utilities/Release/release_cmake.sh.in
@@ -116,15 +116,9 @@ if [ ! -z "@CONFIGURE_WITH_CMAKE@" ]; then
     @CMAKE_CONFIGURE_PATH@ ../@CMAKE_CREATE_VERSION@
     check_exit_value $? "Configure cmake" || exit 1
 else
-    if [ -z "@INSTALL_PREFIX@" ]; then
-	echo  "Run cmake bootstrap --parallel=@PROCESSORS@"
-	../@CMAKE_CREATE_VERSION@/bootstrap --parallel=@PROCESSORS@
-	check_exit_value $? "Bootstrap cmake" || exit 1
-    else
-	echo  "Run cmake bootstrap --prefix=@INSTALL_PREFIX@ --parallel=@PROCESSORS@"
-	../@CMAKE_CREATE_VERSION@/bootstrap --prefix=@INSTALL_PREFIX@ --parallel=@PROCESSORS@
-	check_exit_value $? "Bootstrap cmake" || exit 1
-    fi
+    echo  "Run cmake bootstrap @BOOTSTRAP_ARGS@ --parallel=@PROCESSORS@"
+    ../@CMAKE_CREATE_VERSION@/bootstrap @BOOTSTRAP_ARGS@ --parallel=@PROCESSORS@
+    check_exit_value $? "Bootstrap cmake" || exit 1
 fi
 
 echo "Build cmake with @MAKE@"
diff --git a/Utilities/Release/upload_release.cmake b/Utilities/Release/upload_release.cmake
index ac41300..171811a 100644
--- a/Utilities/Release/upload_release.cmake
+++ b/Utilities/Release/upload_release.cmake
@@ -1,6 +1,6 @@
 set(CTEST_RUN_CURRENT_SCRIPT 0)
 if(NOT VERSION)
- set(VERSION 3.3)
+ set(VERSION 3.4)
 endif()
 if(NOT DEFINED PROJECT_PREFIX)
   set(PROJECT_PREFIX cmake-${VERSION})
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index a755ca1..1baca35 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -19,6 +19,9 @@ if(NOT CMake_SOURCE_DIR)
   include(${CMake_SOURCE_DIR}/Source/CMakeInstallDestinations.cmake)
   unset(CMAKE_DATA_DIR)
   unset(CMAKE_DATA_DIR CACHE)
+  macro(CMake_OPTIONAL_COMPONENT)
+    set(COMPONENT "")
+  endmacro()
 endif()
 project(CMakeHelp NONE)
 
@@ -153,28 +156,35 @@ if(SPHINX_MAN)
     if("x${m}" MATCHES "^x(.+)\\.([1-9])\\.rst$")
       set(name "${CMAKE_MATCH_1}")
       set(sec "${CMAKE_MATCH_2}")
+      CMake_OPTIONAL_COMPONENT(sphinx-man)
       install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/${name}.${sec}
-              DESTINATION ${CMAKE_MAN_DIR}/man${sec})
+              DESTINATION ${CMAKE_MAN_DIR}/man${sec}
+              ${COMPONENT})
     endif()
   endforeach()
 endif()
 
 if(SPHINX_HTML)
+  CMake_OPTIONAL_COMPONENT(sphinx-html)
   install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
           DESTINATION ${CMAKE_DOC_DIR}
+          ${COMPONENT}
           PATTERN .buildinfo EXCLUDE
           )
 endif()
 
 if(SPHINX_SINGLEHTML)
+  CMake_OPTIONAL_COMPONENT(sphinx-singlehtml)
   install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/singlehtml
           DESTINATION ${CMAKE_DOC_DIR}
+          ${COMPONENT}
           PATTERN .buildinfo EXCLUDE
           )
 endif()
 
 if(SPHINX_QTHELP)
+  CMake_OPTIONAL_COMPONENT(sphinx-qthelp)
   install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qthelp/CMake-${CMake_VERSION_MAJOR}${CMake_VERSION_MINOR}${CMake_VERSION_PATCH}.qch
-          DESTINATION ${CMAKE_DOC_DIR}
+          DESTINATION ${CMAKE_DOC_DIR} ${COMPONENT}
           )
 endif()
diff --git a/Utilities/Sphinx/templates/layout.html b/Utilities/Sphinx/templates/layout.html
index 1c5728c..177e044 100644
--- a/Utilities/Sphinx/templates/layout.html
+++ b/Utilities/Sphinx/templates/layout.html
@@ -5,7 +5,7 @@
          style="vertical-align: middle; margin-top: -2px" />
   </li>
   <li>
-    <a href="http://www.cmake.org/">CMake</a>{{ reldelim1 }}
+    <a href="https://cmake.org/">CMake</a>{{ reldelim1 }}
   </li>
   <li>
     <a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>{{ reldelim1 }}
diff --git a/Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake b/Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake
deleted file mode 100644
index 396001b..0000000
--- a/Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake
+++ /dev/null
@@ -1,71 +0,0 @@
-# - Check if the source code provided in the SOURCE argument compiles.
-# CURL_CHECK_C_SOURCE_COMPILES(SOURCE VAR)
-# - macro which checks if the source code compiles
-#  SOURCE   - source code to try to compile
-#  VAR      - variable to store whether the source code compiled
-#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
-#
-#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
-#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-#  CMAKE_REQUIRED_INCLUDES = list of include directories
-#  CMAKE_REQUIRED_LIBRARIES = list of libraries to link
-
-macro(CURL_CHECK_C_SOURCE_COMPILES SOURCE VAR)
-  if(NOT DEFINED "${VAR}")
-    set(message "${VAR}")
-    # If the number of arguments is greater than 2 (SOURCE VAR)
-    if(${ARGC} GREATER 2)
-      # then add the third argument as a message
-      set(message "${ARGV2} (${VAR})")
-    endif()
-    set(MACRO_CHECK_FUNCTION_DEFINITIONS
-      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
-    if(CMAKE_REQUIRED_LIBRARIES)
-      set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
-    endif()
-    if(CMAKE_REQUIRED_INCLUDES)
-      set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
-        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
-    endif()
-    set(src "")
-    foreach(def ${EXTRA_DEFINES})
-      set(src "${src}#define ${def} 1\n")
-    endforeach(def)
-    foreach(inc ${HEADER_INCLUDES})
-      set(src "${src}#include <${inc}>\n")
-    endforeach(inc)
-
-    set(src "${src}\nint main() { ${SOURCE} ; return 0; }")
-    set(CMAKE_CONFIGURABLE_FILE_CONTENT "${src}")
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeConfigurableFile.in
-      "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
-      IMMEDIATE)
-    message(STATUS "Performing Test ${message}")
-    try_compile(${VAR}
-      ${CMAKE_BINARY_DIR}
-      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
-      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
-      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-      "${CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
-      "${CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
-      OUTPUT_VARIABLE OUTPUT)
-    if(${VAR})
-      set(${VAR} 1 CACHE INTERNAL "Test ${message}")
-      message(STATUS "Performing Test ${message} - Success")
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-        "Performing C SOURCE FILE Test ${message} succeded with the following output:\n"
-        "${OUTPUT}\n"
-        "Source file was:\n${src}\n")
-    else()
-      message(STATUS "Performing Test ${message} - Failed")
-      set(${VAR} "" CACHE INTERNAL "Test ${message}")
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-        "Performing C SOURCE FILE Test ${message} failed with the following output:\n"
-        "${OUTPUT}\n"
-        "Source file was:\n${src}\n")
-    endif()
-  endif()
-endmacro()
diff --git a/Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake b/Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake
deleted file mode 100644
index e62eebe..0000000
--- a/Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake
+++ /dev/null
@@ -1,83 +0,0 @@
-# - Check if the source code provided in the SOURCE argument compiles and runs.
-# CURL_CHECK_C_SOURCE_RUNS(SOURCE VAR)
-# - macro which checks if the source code runs
-#  SOURCE   - source code to try to compile
-#  VAR - variable to store size if the type exists.
-#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
-#
-#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
-#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-#  CMAKE_REQUIRED_INCLUDES = list of include directories
-#  CMAKE_REQUIRED_LIBRARIES = list of libraries to link
-
-macro(CURL_CHECK_C_SOURCE_RUNS SOURCE VAR)
-  if(NOT DEFINED "${VAR}")
-    set(message "${VAR}")
-    # If the number of arguments is greater than 2 (SOURCE VAR)
-    if(${ARGC} GREATER 2)
-      # then add the third argument as a message
-      set(message "${ARGV2} (${VAR})")
-    endif(${ARGC} GREATER 2)
-    set(MACRO_CHECK_FUNCTION_DEFINITIONS
-      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
-    if(CMAKE_REQUIRED_LIBRARIES)
-      set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
-    else(CMAKE_REQUIRED_LIBRARIES)
-      set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
-    endif(CMAKE_REQUIRED_LIBRARIES)
-    if(CMAKE_REQUIRED_INCLUDES)
-      set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
-        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
-    else(CMAKE_REQUIRED_INCLUDES)
-      set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
-    endif(CMAKE_REQUIRED_INCLUDES)
-    set(src "")
-    foreach(def ${EXTRA_DEFINES})
-      set(src "${src}#define ${def} 1\n")
-    endforeach(def)
-    foreach(inc ${HEADER_INCLUDES})
-      set(src "${src}#include <${inc}>\n")
-    endforeach(inc)
-
-    set(src "${src}\nint main() { ${SOURCE} ; return 0; }")
-    set(CMAKE_CONFIGURABLE_FILE_CONTENT "${src}")
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeConfigurableFile.in
-      "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
-      IMMEDIATE)
-    message(STATUS "Performing Test ${message}")
-    try_run(${VAR} ${VAR}_COMPILED
-      ${CMAKE_BINARY_DIR}
-      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
-      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
-      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-      "${CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
-      "${CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
-      OUTPUT_VARIABLE OUTPUT)
-    # if it did not compile make the return value fail code of 1
-    if(NOT ${VAR}_COMPILED)
-      set(${VAR} 1)
-    endif(NOT ${VAR}_COMPILED)
-    # if the return value was 0 then it worked
-    set(result_var ${${VAR}})
-    if("${result_var}" EQUAL 0)
-      set(${VAR} 1 CACHE INTERNAL "Test ${message}")
-      message(STATUS "Performing Test ${message} - Success")
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-        "Performing C SOURCE FILE Test ${message} succeded with the following output:\n"
-        "${OUTPUT}\n"
-        "Return value: ${${VAR}}\n"
-        "Source file was:\n${src}\n")
-    else("${result_var}" EQUAL 0)
-      message(STATUS "Performing Test ${message} - Failed")
-      set(${VAR} "" CACHE INTERNAL "Test ${message}")
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-        "Performing C SOURCE FILE Test ${message} failed with the following output:\n"
-        "${OUTPUT}\n"
-        "Return value: ${result_var}\n"
-        "Source file was:\n${src}\n")
-    endif("${result_var}" EQUAL 0)
-  endif()
-endmacro(CURL_CHECK_C_SOURCE_RUNS)
diff --git a/Utilities/cmcurl/CMake/CurlTests.c b/Utilities/cmcurl/CMake/CurlTests.c
index 199871a..3c71232 100644
--- a/Utilities/cmcurl/CMake/CurlTests.c
+++ b/Utilities/cmcurl/CMake/CurlTests.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -71,264 +71,88 @@ main ()
 }
 #endif
 
-#ifdef HAVE_GETHOSTBYADDR_R_5
+/* tests for gethostbyaddr_r or gethostbyname_r */
+#if defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
+    defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
+    defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
+    defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \
+    defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
+    defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+#   define _REENTRANT
+    /* no idea whether _REENTRANT is always set, just invent a new flag */
+#   define TEST_GETHOSTBYFOO_REENTRANT
+#endif
+#if defined(HAVE_GETHOSTBYADDR_R_5) || \
+    defined(HAVE_GETHOSTBYADDR_R_7) || \
+    defined(HAVE_GETHOSTBYADDR_R_8) || \
+    defined(HAVE_GETHOSTBYNAME_R_3) || \
+    defined(HAVE_GETHOSTBYNAME_R_5) || \
+    defined(HAVE_GETHOSTBYNAME_R_6) || \
+    defined(TEST_GETHOSTBYFOO_REENTRANT)
 #include <sys/types.h>
 #include <netdb.h>
-int
-main ()
-{
-
-char * address;
-int length;
-int type;
-struct hostent h;
-struct hostent_data hdata;
-int rc;
-#ifndef gethostbyaddr_r
-  (void)gethostbyaddr_r;
-#endif
-rc = gethostbyaddr_r(address, length, type, &h, &hdata);
-  ;
-  return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYADDR_R_5_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-int
-main ()
-{
-
-char * address;
-int length;q
-int type;
-struct hostent h;
-struct hostent_data hdata;
-int rc;
-#ifndef gethostbyaddr_r
-  (void)gethostbyaddr_r;
-#endif
-rc = gethostbyaddr_r(address, length, type, &h, &hdata);
-  ;
-  return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYADDR_R_7
-#include <sys/types.h>
-#include <netdb.h>
-int
-main ()
-{
-
-char * address;
-int length;
-int type;
-struct hostent h;
-char buffer[8192];
-int h_errnop;
-struct hostent * hp;
-
-#ifndef gethostbyaddr_r
-  (void)gethostbyaddr_r;
-#endif
-hp = gethostbyaddr_r(address, length, type, &h,
-                     buffer, 8192, &h_errnop);
-  ;
-  return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYADDR_R_7_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-int
-main ()
+int main(void)
 {
-
-char * address;
-int length;
-int type;
-struct hostent h;
-char buffer[8192];
-int h_errnop;
-struct hostent * hp;
-
-#ifndef gethostbyaddr_r
-  (void)gethostbyaddr_r;
-#endif
-hp = gethostbyaddr_r(address, length, type, &h,
-                     buffer, 8192, &h_errnop);
-  ;
-  return 0;
-}
+  char *address = "example.com";
+  int length = 0;
+  int type = 0;
+  struct hostent h;
+  int rc = 0;
+#if defined(HAVE_GETHOSTBYADDR_R_5) || \
+    defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
+    \
+    defined(HAVE_GETHOSTBYNAME_R_3) || \
+    defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
+  struct hostent_data hdata;
+#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
+      defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
+      defined(HAVE_GETHOSTBYADDR_R_8) || \
+      defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
+      \
+      defined(HAVE_GETHOSTBYNAME_R_5) || \
+      defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
+      defined(HAVE_GETHOSTBYNAME_R_6) || \
+      defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+  char buffer[8192];
+  int h_errnop;
+  struct hostent *hp;
 #endif
-#ifdef HAVE_GETHOSTBYADDR_R_8
-#include <sys/types.h>
-#include <netdb.h>
-int
-main ()
-{
-
-char * address;
-int length;
-int type;
-struct hostent h;
-char buffer[8192];
-int h_errnop;
-struct hostent * hp;
-int rc;
-
-#ifndef gethostbyaddr_r
-  (void)gethostbyaddr_r;
-#endif
-rc = gethostbyaddr_r(address, length, type, &h,
-                     buffer, 8192, &hp, &h_errnop);
-  ;
-  return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYADDR_R_8_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-int
-main ()
-{
-
-char * address;
-int length;
-int type;
-struct hostent h;
-char buffer[8192];
-int h_errnop;
-struct hostent * hp;
-int rc;
 
 #ifndef gethostbyaddr_r
   (void)gethostbyaddr_r;
 #endif
-rc = gethostbyaddr_r(address, length, type, &h,
-                     buffer, 8192, &hp, &h_errnop);
-  ;
-  return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_3
-#include <string.h>
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-
-int
-main ()
-{
-
-struct hostent_data data;
-#ifndef gethostbyname_r
-  (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL);
-  ;
-  return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_3_REENTRANT
-#define _REENTRANT
-#include <string.h>
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-
-int
-main ()
-{
-
-struct hostent_data data;
-#ifndef gethostbyname_r
-  (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL);
-  ;
-  return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_5
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-
-int
-main ()
-{
-#ifndef gethostbyname_r
-  (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL, 0, NULL);
-  ;
-  return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_5_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
 
-int
-main ()
-{
-
-#ifndef gethostbyname_r
-  (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL, 0, NULL);
-  ;
+#if   defined(HAVE_GETHOSTBYADDR_R_5) || \
+      defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT)
+  rc = gethostbyaddr_r(address, length, type, &h, &hdata);
+#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
+      defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT)
+  hp = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &h_errnop);
+  (void)hp;
+#elif defined(HAVE_GETHOSTBYADDR_R_8) || \
+      defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT)
+  rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop);
+#endif
+
+#if   defined(HAVE_GETHOSTBYNAME_R_3) || \
+      defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
+  rc = gethostbyname_r(address, &h, &hdata);
+#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
+      defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT)
+  rc = gethostbyname_r(address, &h, buffer, 8192, &h_errnop);
+  (void)hp; /* not used for test */
+#elif defined(HAVE_GETHOSTBYNAME_R_6) || \
+      defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+  rc = gethostbyname_r(address, &h, buffer, 8192, &hp, &h_errnop);
+#endif
+
+  (void)length;
+  (void)type;
+  (void)rc;
   return 0;
 }
 #endif
-#ifdef HAVE_GETHOSTBYNAME_R_6
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-
-int
-main ()
-{
 
-#ifndef gethostbyname_r
-  (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL, 0, NULL, NULL);
-  ;
-  return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_6_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-
-int
-main ()
-{
-
-#ifndef gethostbyname_r
-  (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL, 0, NULL, NULL);
-  ;
-  return 0;
-}
-#endif
 #ifdef HAVE_SOCKLEN_T
 #ifdef _WIN32
 #include <ws2tcpip.h>
diff --git a/Utilities/cmcurl/CMake/FindGSS.cmake b/Utilities/cmcurl/CMake/FindGSS.cmake
new file mode 100644
index 0000000..dfaeaf3
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindGSS.cmake
@@ -0,0 +1,289 @@
+# - Try to find the GSS Kerberos library
+# Once done this will define
+#
+#  GSS_ROOT_DIR - Set this variable to the root installation of GSS
+#
+# Read-Only variables:
+#  GSS_FOUND - system has the Heimdal library
+#  GSS_FLAVOUR - "MIT" or "Heimdal" if anything found.
+#  GSS_INCLUDE_DIR - the Heimdal include directory
+#  GSS_LIBRARIES - The libraries needed to use GSS
+#  GSS_LINK_DIRECTORIES - Directories to add to linker search path
+#  GSS_LINKER_FLAGS - Additional linker flags
+#  GSS_COMPILER_FLAGS - Additional compiler flags
+#  GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
+#                In case the library is found but no version info availabe it'll be set to "unknown"
+
+set(_MIT_MODNAME mit-krb5-gssapi)
+set(_HEIMDAL_MODNAME heimdal-gssapi)
+
+include(CheckIncludeFile)
+include(CheckIncludeFiles)
+include(CheckTypeSize)
+
+set(_GSS_ROOT_HINTS
+    "${GSS_ROOT_DIR}"
+    "$ENV{GSS_ROOT_DIR}"
+)
+
+# try to find library using system pkg-config if user didn't specify root dir
+if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
+    if(UNIX)
+        find_package(PkgConfig QUIET)
+        pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
+        list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
+    elseif(WIN32)
+        list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
+    endif()
+endif()
+
+if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
+    find_file(_GSS_CONFIGURE_SCRIPT
+        NAMES
+            "krb5-config"
+        HINTS
+            ${_GSS_ROOT_HINTS}
+        PATH_SUFFIXES
+            bin
+        NO_CMAKE_PATH
+        NO_CMAKE_ENVIRONMENT_PATH
+    )
+
+    # if not found in user-supplied directories, maybe system knows better
+    find_file(_GSS_CONFIGURE_SCRIPT
+        NAMES
+            "krb5-config"
+        PATH_SUFFIXES
+            bin
+    )
+
+    if(_GSS_CONFIGURE_SCRIPT)
+        execute_process(
+            COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
+            OUTPUT_VARIABLE _GSS_CFLAGS
+            RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+        )
+message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
+        if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
+            # should also work in an odd case when multiple directories are given
+            string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
+            string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
+            string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
+
+            foreach(_flag ${_GSS_CFLAGS})
+                if(_flag MATCHES "^-I.*")
+                    string(REGEX REPLACE "^-I" "" _val "${_flag}")
+                    list(APPEND _GSS_INCLUDE_DIR "${_val}")
+                else()
+                    list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
+                endif()
+            endforeach()
+        endif()
+
+        execute_process(
+            COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
+            OUTPUT_VARIABLE _GSS_LIB_FLAGS
+            RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+        )
+message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
+        if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
+            # this script gives us libraries and link directories. Blah. We have to deal with it.
+            string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
+            string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
+            string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
+
+            foreach(_flag ${_GSS_LIB_FLAGS})
+                if(_flag MATCHES "^-l.*")
+                    string(REGEX REPLACE "^-l" "" _val "${_flag}")
+                    list(APPEND _GSS_LIBRARIES "${_val}")
+                elseif(_flag MATCHES "^-L.*")
+                    string(REGEX REPLACE "^-L" "" _val "${_flag}")
+                    list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
+                else()
+                    list(APPEND _GSS_LINKER_FLAGS "${_flag}")
+                endif()
+            endforeach()
+        endif()
+
+
+        execute_process(
+            COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
+            OUTPUT_VARIABLE _GSS_VERSION
+            RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+        )
+
+        # older versions may not have the "--version" parameter. In this case we just don't care.
+        if(_GSS_CONFIGURE_FAILED)
+            set(_GSS_VERSION 0)
+        endif()
+
+
+        execute_process(
+            COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
+            OUTPUT_VARIABLE _GSS_VENDOR
+            RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+        )
+
+        # older versions may not have the "--vendor" parameter. In this case we just don't care.
+        if(_GSS_CONFIGURE_FAILED)
+            set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
+        else()
+            if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
+                set(GSS_FLAVOUR "Heimdal")
+            else()
+                set(GSS_FLAVOUR "MIT")
+            endif()
+        endif()
+
+    else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
+
+        find_path(_GSS_INCLUDE_DIR
+            NAMES
+                "gssapi/gssapi.h"
+            HINTS
+                ${_GSS_ROOT_HINTS}
+            PATH_SUFFIXES
+                include
+                inc
+        )
+
+        if(_GSS_INCLUDE_DIR) #jay, we've found something
+            set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
+            check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
+
+            if(_GSS_HAVE_MIT_HEADERS)
+                set(GSS_FLAVOUR "MIT")
+            else()
+                # prevent compiling the header - just check if we can include it
+                set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
+                check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
+
+                check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
+                if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
+                    set(GSS_FLAVOUR "Heimdal")
+                endif()
+                set(CMAKE_REQUIRED_DEFINITIONS "")
+            endif()
+        else()
+            # I'm not convienced if this is the right way but this is what autotools do at the moment
+            find_path(_GSS_INCLUDE_DIR
+                NAMES
+                    "gssapi.h"
+                HINTS
+                    ${_GSS_ROOT_HINTS}
+                PATH_SUFFIXES
+                    include
+                    inc
+            )
+
+            if(_GSS_INCLUDE_DIR)
+                set(GSS_FLAVOUR "Heimdal")
+            endif()
+        endif()
+
+        # if we have headers, check if we can link libraries
+        if(GSS_FLAVOUR)
+            set(_GSS_LIBDIR_SUFFIXES "")
+            set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
+            get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
+            list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
+
+            if(WIN32)
+                if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+                    list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
+                    if(GSS_FLAVOUR STREQUAL "MIT")
+                        set(_GSS_LIBNAME "gssapi64")
+                    else()
+                        set(_GSS_LIBNAME "libgssapi")
+                    endif()
+                else()
+                    list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
+                    if(GSS_FLAVOUR STREQUAL "MIT")
+                        set(_GSS_LIBNAME "gssapi32")
+                    else()
+                        set(_GSS_LIBNAME "libgssapi")
+                    endif()
+                endif()
+            else()
+                list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
+                if(GSS_FLAVOUR STREQUAL "MIT")
+                    set(_GSS_LIBNAME "gssapi_krb5")
+                else()
+                    set(_GSS_LIBNAME "gssapi")
+                endif()
+            endif()
+
+            find_library(_GSS_LIBRARIES
+                NAMES
+                    ${_GSS_LIBNAME}
+                HINTS
+                    ${_GSS_LIBDIR_HINTS}
+                PATH_SUFFIXES
+                    ${_GSS_LIBDIR_SUFFIXES}
+            )
+
+        endif()
+
+    endif()
+else()
+    if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
+        set(GSS_FLAVOUR "MIT")
+        set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
+    else()
+        set(GSS_FLAVOUR "Heimdal")
+        set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
+    endif()
+endif()
+
+set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
+set(GSS_LIBRARIES ${_GSS_LIBRARIES})
+set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES})
+set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS})
+set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
+set(GSS_VERSION ${_GSS_VERSION})
+
+if(GSS_FLAVOUR)
+
+    if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
+        if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+            set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
+        else()
+            set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
+        endif()
+
+        if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
+            file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
+                 REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
+
+            string(REGEX MATCH "[0-9]\\.[^\"]+"
+                   GSS_VERSION "${heimdal_version_str}")
+        endif()
+
+        if(NOT GSS_VERSION)
+            set(GSS_VERSION "Heimdal Unknown")
+        endif()
+    elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
+        get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
+        if(WIN32 AND _MIT_VERSION)
+            set(GSS_VERSION "${_MIT_VERSION}")
+        else()
+            set(GSS_VERSION "MIT Unknown")
+        endif()
+    endif()
+endif()
+
+
+include(FindPackageHandleStandardArgs)
+
+set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
+
+find_package_handle_standard_args(GSS
+    REQUIRED_VARS
+        ${_GSS_REQUIRED_VARS}
+    VERSION_VAR
+        GSS_VERSION
+    FAIL_MESSAGE
+        "Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
+)
+
+mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES)
diff --git a/Utilities/cmcurl/CMake/Macros.cmake b/Utilities/cmcurl/CMake/Macros.cmake
index 0f8eb57..dab005f 100644
--- a/Utilities/cmcurl/CMake/Macros.cmake
+++ b/Utilities/cmcurl/CMake/Macros.cmake
@@ -1,7 +1,10 @@
 #File defines convenience macros for available feature testing
 
 # This macro checks if the symbol exists in the library and if it
-# does, it prepends library to the list.
+# does, it prepends library to the list.  It is intended to be called
+# multiple times with a sequence of possibly dependent libraries in
+# order of least-to-most-dependent.  Some libraries depend on others
+# to link correctly.
 macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
   check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
     ${VARIABLE})
@@ -11,6 +14,9 @@ macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
 endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
 
 # Check if header file exists and add it to the list.
+# This macro is intended to be called multiple times with a sequence of
+# possibly dependent header files.  Some headers depend on others to be
+# compiled correctly.
 macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
   check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
   if(${VARIABLE})
diff --git a/Utilities/cmcurl/CMake/OtherTests.cmake b/Utilities/cmcurl/CMake/OtherTests.cmake
index 039d189..4f07f22 100644
--- a/Utilities/cmcurl/CMake/OtherTests.cmake
+++ b/Utilities/cmcurl/CMake/OtherTests.cmake
@@ -1,15 +1,10 @@
-include(CurlCheckCSourceCompiles)
-set(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
-set(HEADER_INCLUDES)
-set(headers_hack)
+include(CheckCSourceCompiles)
+# The begin of the sources (macros and includes)
+set(_source_epilogue "#undef inline")
 
 macro(add_header_include check header)
   if(${check})
-    set(headers_hack
-      "${headers_hack}\n#include <${header}>")
-    #SET(HEADER_INCLUDES
-    #  ${HEADER_INCLUDES}
-    #  "${header}")
+    set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
   endif(${check})
 endmacro(add_header_include)
 
@@ -18,8 +13,8 @@ if(HAVE_WINDOWS_H)
   add_header_include(HAVE_WINDOWS_H "windows.h")
   add_header_include(HAVE_WINSOCK2_H "winsock2.h")
   add_header_include(HAVE_WINSOCK_H "winsock.h")
-  set(EXTRA_DEFINES ${EXTRA_DEFINES}
-    "__unused7\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#define __unused3")
+  set(_source_epilogue
+      "${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif")
   set(signature_call_conv "PASCAL")
   if(HAVE_LIBWS2_32)
     set(CMAKE_REQUIRED_LIBRARIES ws2_32)
@@ -29,14 +24,12 @@ else(HAVE_WINDOWS_H)
   add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
 endif(HAVE_WINDOWS_H)
 
-set(EXTRA_DEFINES_BACKUP "${EXTRA_DEFINES}")
-set(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
-curl_check_c_source_compiles("recv(0, 0, 0, 0)" curl_cv_recv)
+check_c_source_compiles("${_source_epilogue}
+int main(void) {
+    recv(0, 0, 0, 0);
+    return 0;
+}" curl_cv_recv)
 if(curl_cv_recv)
-  #    AC_CACHE_CHECK([types of arguments and return type for recv],
-  #[curl_cv_func_recv_args], [
-  #SET(curl_cv_func_recv_args "unknown")
-  #for recv_retv in 'int' 'ssize_t'; do
   if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
     foreach(recv_retv "int" "ssize_t" )
       foreach(recv_arg1 "int" "ssize_t" "SOCKET")
@@ -45,16 +38,22 @@ if(curl_cv_recv)
             foreach(recv_arg4 "int" "unsigned int")
               if(NOT curl_cv_func_recv_done)
                 unset(curl_cv_func_recv_test CACHE)
-                set(extern_line "extern ${recv_retv} ${signature_call_conv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})\;")
-                set(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
-                curl_check_c_source_compiles("
+                check_c_source_compiles("
+                  ${_source_epilogue}
+                  extern ${recv_retv} ${signature_call_conv}
+                  recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
+                  int main(void) {
                     ${recv_arg1} s=0;
                     ${recv_arg2} buf=0;
                     ${recv_arg3} len=0;
                     ${recv_arg4} flags=0;
-                    ${recv_retv} res = recv(s, buf, len, flags)"
-                  curl_cv_func_recv_test
-                  "${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
+                    ${recv_retv} res = recv(s, buf, len, flags);
+                    (void) res;
+                    return 0;
+                  }"
+                  curl_cv_func_recv_test)
+                message(STATUS
+                  "Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
                 if(curl_cv_func_recv_test)
                   set(curl_cv_func_recv_args
                     "${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}")
@@ -72,18 +71,13 @@ if(curl_cv_recv)
         endforeach(recv_arg2)
       endforeach(recv_arg1)
     endforeach(recv_retv)
-  else(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
+  else()
     string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
     string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
     string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}")
     string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}")
     string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
-    #MESSAGE("RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}")
-    #MESSAGE("RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}")
-    #MESSAGE("RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}")
-    #MESSAGE("RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}")
-    #MESSAGE("RECV_TYPE_RETV ${RECV_TYPE_RETV}")
-  endif(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
+  endif()
 
   if("${curl_cv_func_recv_args}" STREQUAL "unknown")
     message(FATAL_ERROR "Cannot find proper types to use for recv args")
@@ -94,12 +88,12 @@ endif(curl_cv_recv)
 set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
 set(HAVE_RECV 1)
 
-curl_check_c_source_compiles("send(0, 0, 0, 0)" curl_cv_send)
+check_c_source_compiles("${_source_epilogue}
+int main(void) {
+    send(0, 0, 0, 0);
+    return 0;
+}" curl_cv_send)
 if(curl_cv_send)
-  #    AC_CACHE_CHECK([types of arguments and return type for send],
-  #[curl_cv_func_send_args], [
-  #SET(curl_cv_func_send_args "unknown")
-  #for send_retv in 'int' 'ssize_t'; do
   if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
     foreach(send_retv "int" "ssize_t" )
       foreach(send_arg1 "int" "ssize_t" "SOCKET")
@@ -108,18 +102,23 @@ if(curl_cv_send)
             foreach(send_arg4 "int" "unsigned int")
               if(NOT curl_cv_func_send_done)
                 unset(curl_cv_func_send_test CACHE)
-                set(extern_line "extern ${send_retv} ${signature_call_conv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})\;")
-                set(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
-                curl_check_c_source_compiles("
+                check_c_source_compiles("
+                  ${_source_epilogue}
+                  extern ${send_retv} ${signature_call_conv}
+                  send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
+                  int main(void) {
                     ${send_arg1} s=0;
                     ${send_arg2} buf=0;
                     ${send_arg3} len=0;
                     ${send_arg4} flags=0;
-                    ${send_retv} res = send(s, buf, len, flags)"
-                  curl_cv_func_send_test
-                  "${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
+                    ${send_retv} res = send(s, buf, len, flags);
+                    (void) res;
+                    return 0;
+                  }"
+                  curl_cv_func_send_test)
+                message(STATUS
+                  "Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
                 if(curl_cv_func_send_test)
-                  #MESSAGE("Found arguments: ${curl_cv_func_send_test}")
                   string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
                   string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
                   set(curl_cv_func_send_args
@@ -138,20 +137,14 @@ if(curl_cv_send)
         endforeach(send_arg2)
       endforeach(send_arg1)
     endforeach(send_retv)
-  else(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
+  else()
     string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
     string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
     string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}")
     string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}")
     string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}")
     string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}")
-    #MESSAGE("SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}")
-    #MESSAGE("SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}")
-    #MESSAGE("SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}")
-    #MESSAGE("SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}")
-    #MESSAGE("SEND_TYPE_RETV ${SEND_TYPE_RETV}")
-    #MESSAGE("SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}")
-  endif(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
+  endif()
 
   if("${curl_cv_func_send_args}" STREQUAL "unknown")
     message(FATAL_ERROR "Cannot find proper types to use for send args")
@@ -163,88 +156,71 @@ endif(curl_cv_send)
 set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
 set(HAVE_SEND 1)
 
-set(EXTRA_DEFINES "${EXTRA_DEFINES}\n${headers_hack}\n#define __unused5")
-curl_check_c_source_compiles("int flag = MSG_NOSIGNAL" HAVE_MSG_NOSIGNAL)
-
-set(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
-set(HEADER_INCLUDES)
-set(headers_hack)
+check_c_source_compiles("${_source_epilogue}
+  int main(void) {
+    int flag = MSG_NOSIGNAL;
+    (void)flag;
+    return 0;
+  }" HAVE_MSG_NOSIGNAL)
 
-macro(add_header_include check header)
-  if(${check})
-    set(headers_hack
-      "${headers_hack}\n#include <${header}>")
-    #SET(HEADER_INCLUDES
-    #  ${HEADER_INCLUDES}
-    #  "${header}")
-  endif(${check})
-endmacro(add_header_include header)
-
-if(HAVE_WINDOWS_H)
-  set(EXTRA_DEFINES ${EXTRA_DEFINES}
-    "__unused7\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#define __unused3")
-  add_header_include(HAVE_WINDOWS_H "windows.h")
-  add_header_include(HAVE_WINSOCK2_H "winsock2.h")
-  add_header_include(HAVE_WINSOCK_H "winsock.h")
-else(HAVE_WINDOWS_H)
-  add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
+if(NOT HAVE_WINDOWS_H)
   add_header_include(HAVE_SYS_TIME_H "sys/time.h")
   add_header_include(TIME_WITH_SYS_TIME "time.h")
   add_header_include(HAVE_TIME_H "time.h")
-endif(HAVE_WINDOWS_H)
-set(EXTRA_DEFINES "${EXTRA_DEFINES}\n${headers_hack}\n#define __unused5")
-curl_check_c_source_compiles("struct timeval ts;\nts.tv_sec  = 0;\nts.tv_usec = 0" HAVE_STRUCT_TIMEVAL)
-
-
-include(CurlCheckCSourceRuns)
-set(EXTRA_DEFINES)
-set(HEADER_INCLUDES)
+endif()
+check_c_source_compiles("${_source_epilogue}
+int main(void) {
+  struct timeval ts;
+  ts.tv_sec  = 0;
+  ts.tv_usec = 0;
+  (void)ts;
+  return 0;
+}" HAVE_STRUCT_TIMEVAL)
+
+
+include(CheckCSourceRuns)
+set(CMAKE_REQUIRED_FLAGS)
 if(HAVE_SYS_POLL_H)
-  set(HEADER_INCLUDES "sys/poll.h")
+  set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
 endif(HAVE_SYS_POLL_H)
-curl_check_c_source_runs("return poll((void *)0, 0, 10 /*ms*/)" HAVE_POLL_FINE)
+check_c_source_runs("
+  #ifdef HAVE_SYS_POLL_H
+  #  include <sys/poll.h>
+  #endif
+  int main(void) {
+    return poll((void *)0, 0, 10 /*ms*/);
+  }" HAVE_POLL_FINE)
 
 set(HAVE_SIG_ATOMIC_T 1)
-set(EXTRA_DEFINES)
-set(HEADER_INCLUDES)
+set(CMAKE_REQUIRED_FLAGS)
 if(HAVE_SIGNAL_H)
-  set(HEADER_INCLUDES "signal.h")
+  set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H")
   set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
 endif(HAVE_SIGNAL_H)
 check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
 if(HAVE_SIZEOF_SIG_ATOMIC_T)
-  curl_check_c_source_compiles("static volatile sig_atomic_t dummy = 0" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
+  check_c_source_compiles("
+    #ifdef HAVE_SIGNAL_H
+    #  include <signal.h>
+    #endif
+    int main(void) {
+      static volatile sig_atomic_t dummy = 0;
+      (void)dummy;
+      return 0;
+    }" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
   if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
     set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
   endif(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
 endif(HAVE_SIZEOF_SIG_ATOMIC_T)
 
-set(CHECK_TYPE_SIZE_PREINCLUDE
-  "#undef inline")
-
 if(HAVE_WINDOWS_H)
-  set(CHECK_TYPE_SIZE_PREINCLUDE "${CHECK_TYPE_SIZE_PREINCLUDE}
-  #ifndef WIN32_LEAN_AND_MEAN
-  #define WIN32_LEAN_AND_MEAN
-  #endif
-  #include <windows.h>")
-  if(HAVE_WINSOCK2_H)
-    set(CHECK_TYPE_SIZE_PREINCLUDE "${CHECK_TYPE_SIZE_PREINCLUDE}\n#include <winsock2.h>")
-  endif(HAVE_WINSOCK2_H)
-else(HAVE_WINDOWS_H)
+  set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
+else()
+  set(CMAKE_EXTRA_INCLUDE_FILES)
   if(HAVE_SYS_SOCKET_H)
-    set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
-      "sys/socket.h")
+    set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
   endif(HAVE_SYS_SOCKET_H)
-  if(HAVE_NETINET_IN_H)
-    set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
-      "netinet/in.h")
-  endif(HAVE_NETINET_IN_H)
-  if(HAVE_ARPA_INET_H)
-    set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
-      "arpa/inet.h")
-  endif(HAVE_ARPA_INET_H)
-endif(HAVE_WINDOWS_H)
+endif()
 
 check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
 if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
diff --git a/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake b/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
index 0e26a17..53d0a5e 100644
--- a/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
+++ b/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
@@ -5,6 +5,7 @@ if(NOT UNIX)
     set(HAVE_LIBSOCKET 0)
     set(NOT_NEED_LIBNSL 0)
     set(HAVE_LIBNSL 0)
+    set(HAVE_GETHOSTNAME 1)
     set(HAVE_LIBZ 0)
     set(HAVE_LIBCRYPTO 0)
 
@@ -14,7 +15,6 @@ if(NOT UNIX)
     set(HAVE_ARPA_INET_H 0)
     set(HAVE_DLFCN_H 0)
     set(HAVE_FCNTL_H 1)
-    set(HAVE_FEATURES_H 0)
     set(HAVE_INTTYPES_H 0)
     set(HAVE_IO_H 1)
     set(HAVE_MALLOC_H 1)
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index 32e4561..39b70c0 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -3,6 +3,7 @@ set(BUILD_CURL_EXE OFF CACHE INTERNAL "No curl exe")
 set(BUILD_CURL_TESTS OFF CACHE INTERNAL "No curl tests")
 set(BUILD_DASHBOARD_REPORTS OFF CACHE INTERNAL "No curl dashboard reports")
 set(BUILD_RELEASE_DEBUG_DIRS OFF CACHE INTERNAL "No curl release/debug dirs")
+set(CMAKE_USE_GSSAPI OFF CACHE INTERNAL "Disable curl gssapi")
 set(CMAKE_USE_LIBSSH2 OFF CACHE INTERNAL "Disable curl libssh2")
 set(CMAKE_USE_OPENLDAP OFF CACHE INTERNAL "No curl OpenLDAP")
 set(CURL_DISABLE_COOKIES OFF CACHE INTERNAL "Do not disable curl cookie support")
@@ -16,18 +17,24 @@ set(CURL_DISABLE_IMAP ON CACHE INTERNAL "Disable curl imap protocol?")
 set(CURL_DISABLE_LDAP ON CACHE INTERNAL "Disable curl ldap protocol?")
 set(CURL_DISABLE_LDAPS ON CACHE INTERNAL "Disable curl ldaps protocol?")
 set(CURL_DISABLE_POP3 ON CACHE INTERNAL "Disable curl pop3 protocol?")
+set(CURL_DISABLE_PROXY OFF CACHE INTERNAL "Do not disable curl proxy")
 set(CURL_DISABLE_RTSP ON CACHE INTERNAL "Disable curl rtsp protocol?")
 set(CURL_DISABLE_SMTP ON CACHE INTERNAL "Disable curl smtp protocol?")
 set(CURL_DISABLE_TELNET ON CACHE INTERNAL "Disable curl telnet protocol?")
 set(CURL_DISABLE_TFTP ON CACHE INTERNAL "Disable curl tftp protocol?")
-set(CURL_DISABLE_VERBOSE_STRING OFF CACHE INTERNAL "Do not disable curl verbosity")
+set(CURL_DISABLE_VERBOSE_STRINGS OFF CACHE INTERNAL "Do not disable curl verbosity")
 set(CURL_HIDDEN_SYMBOLS OFF CACHE INTERNAL "No curl hidden symbols")
-set(CURL_LDAP_WIN OFF CACHE INTERNAL "No curl Windows LDAP")
 set(CURL_STATICLIB ON CACHE INTERNAL "Static curl")
-set(CURL_USE_ARES OFF CACHE INTERNAL "No curl c-ares support")
 set(DISABLED_THREADSAFE OFF CACHE INTERNAL "Curl can use thread-safe functions")
-set(ENABLE_IPV6 OFF CACHE INTERNAL "Curl IPv6 support")
+set(ENABLE_ARES OFF CACHE INTERNAL "No curl c-ares support")
+set(ENABLE_CURLDEBUG OFF CACHE INTERNAL "No curl TrackMemory features")
+set(ENABLE_DEBUG OFF CACHE INTERNAL "No curl debug features")
+set(ENABLE_IPV6 OFF CACHE INTERNAL "No curl IPv6 support")
+set(ENABLE_MANUAL OFF CACHE INTERNAL "No curl built-in manual")
+set(ENABLE_THREADED_RESOLVER OFF CACHE INTERNAL "No curl POSIX threaded DNS lookup")
+set(ENABLE_UNIX_SOCKETS OFF CACHE INTERNAL "No curl Unix domain sockets support")
 set(HTTP_ONLY OFF CACHE INTERNAL "Curl is not http-only")
+set(USE_WIN32_LDAP OFF CACHE INTERNAL "No curl Windows LDAP")
 
 # Windows Vista and above have inet_pton, but this will link on
 # older versions and then the executable will fail to launch at
@@ -36,6 +43,14 @@ if(WIN32)
   set(HAVE_INET_PTON 0 CACHE INTERNAL "Do not use inet_pton")
 endif()
 
+# Starting with OSX 10.11 there is an unrelated libnetwork library which will
+# be picked up during curl configuration. Linking against this library is
+# unnecessary and breaks backward compatibility of the resulting binaries
+# because libnetwork is unavailable on older OSX versions.
+if(APPLE)
+  set(HAVE_LIBNETWORK 0 CACHE INTERNAL "Do not use libnetwork")
+endif(APPLE)
+
 # Disable warnings to avoid changing 3rd party code.
 if(CMAKE_C_COMPILER_ID MATCHES
     "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
@@ -51,7 +66,7 @@ endif()
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -96,27 +111,17 @@ message(WARNING "the curl cmake build system is poorly maintained. Be aware")
 endif()
 
 file (READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
-string (REGEX MATCH "LIBCURL_VERSION_MAJOR[ \t]+([0-9]+)"
-  LIBCURL_VERSION_MJ ${CURL_VERSION_H_CONTENTS})
-string (REGEX MATCH "([0-9]+)"
-  LIBCURL_VERSION_MJ ${LIBCURL_VERSION_MJ})
-string (REGEX MATCH
-  "LIBCURL_VERSION_MINOR[ \t]+([0-9]+)"
-  LIBCURL_VERSION_MI ${CURL_VERSION_H_CONTENTS})
-string (REGEX MATCH "([0-9]+)" LIBCURL_VERSION_MI ${LIBCURL_VERSION_MI})
-string (REGEX MATCH
-  "LIBCURL_VERSION_PATCH[ \t]+([0-9]+)"
-  LIBCURL_VERSION_PT ${CURL_VERSION_H_CONTENTS})
-string (REGEX MATCH "([0-9]+)" LIBCURL_VERSION_PT ${LIBCURL_VERSION_PT})
-set (CURL_MAJOR_VERSION ${LIBCURL_VERSION_MJ})
-set (CURL_MINOR_VERSION ${LIBCURL_VERSION_MI})
-set (CURL_PATCH_VERSION ${LIBCURL_VERSION_PT})
+string (REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
+  CURL_VERSION ${CURL_VERSION_H_CONTENTS})
+string (REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
+string (REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+"
+  CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS})
+string (REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
 
 include_regular_expression("^.*$")    # Sukender: Is it necessary?
 
 # Setup package meta-data
 # SET(PACKAGE "curl")
-set(CURL_VERSION ${CURL_MAJOR_VERSION}.${CURL_MINOR_VERSION}.${CURL_PATCH_VERSION})
 if(0) # This code not needed for building within CMake.
 message(STATUS "curl version=[${CURL_VERSION}]")
 endif()
@@ -134,12 +139,35 @@ include_directories( ${CURL_SOURCE_DIR}/include )
 option(BUILD_CURL_EXE "Set to ON to build cURL executable." ON)
 option(BUILD_CURL_TESTS "Set to ON to build cURL tests." ON)
 option(CURL_STATICLIB "Set to ON to build libcurl with static linking." OFF)
-option(CURL_USE_ARES "Set to ON to enable c-ares support" OFF)
+option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
+option(ENABLE_THREADED_RESOLVER "Set to ON to enable POSIX threaded DNS lookup" OFF)
+
+option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF)
+option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF)
+
+if (ENABLE_DEBUG)
+  # DEBUGBUILD will be defined only for Debug builds
+  if(NOT CMAKE_VERSION VERSION_LESS 3.0)
+    set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUGBUILD>)
+  else()
+    set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUGBUILD)
+  endif()
+  set(ENABLE_CURLDEBUG ON)
+endif()
+
+if (ENABLE_CURLDEBUG)
+  set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG)
+endif()
+
 # initialize CURL_LIBS
 set(CURL_LIBS "")
 
-if(CURL_USE_ARES)
-  set(USE_ARES ${CURL_USE_ARES})
+if(ENABLE_THREADED_RESOLVER AND ENABLE_ARES)
+  message(FATAL_ERROR "Options ENABLE_THREADED_RESOLVER and ENABLE_ARES are mutually exclusive")
+endif()
+
+if(ENABLE_ARES)
+  set(USE_ARES 1)
   find_package(CARES REQUIRED)
   list(APPEND CURL_LIBS ${CARES_LIBRARY} )
   set(CURL_LIBS ${CURL_LIBS} ${CARES_LIBRARY})
@@ -221,9 +249,52 @@ option(CURL_DISABLE_VERBOSE_STRINGS "to disable verbose strings" OFF)
 mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS)
 option(DISABLED_THREADSAFE "Set to explicitly specify we don't want to use thread-safe functions" OFF)
 mark_as_advanced(DISABLED_THREADSAFE)
-option(ENABLE_IPV6 "Define if you want to enable IPv6 support" OFF)
+option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON)
 mark_as_advanced(ENABLE_IPV6)
+if(ENABLE_IPV6)
+  include(CheckStructHasMember)
+  check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h"
+                          HAVE_SOCKADDR_IN6_SIN6_ADDR)
+  check_struct_has_member("struct sockaddr_in6" sin6_scope_id "netinet/in.h"
+                          HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
+  if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR)
+    message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support")
+    # Force the feature off as this name is used as guard macro...
+    set(ENABLE_IPV6 OFF
+        CACHE BOOL "Define if you want to enable IPv6 support" FORCE)
+  endif()
+endif()
 
+option(ENABLE_MANUAL "to provide the built-in manual" ON)
+unset(USE_MANUAL CACHE) # TODO: cache NROFF/NROFF_MANOPT/USE_MANUAL vars?
+if(ENABLE_MANUAL)
+  find_program(NROFF NAMES gnroff nroff)
+  if(NROFF)
+    # Need a way to write to stdin, this will do
+    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt" "test")
+    # Tests for a valid nroff option to generate a manpage
+    foreach(_MANOPT "-man" "-mandoc")
+      execute_process(COMMAND "${NROFF}" ${_MANOPT}
+        OUTPUT_VARIABLE NROFF_MANOPT_OUTPUT
+        INPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt"
+        ERROR_QUIET)
+      # Save the option if it was valid
+      if(NROFF_MANOPT_OUTPUT)
+        message("Found *nroff option: -- ${_MANOPT}")
+        set(NROFF_MANOPT ${_MANOPT})
+        set(USE_MANUAL 1)
+        break()
+      endif()
+    endforeach()
+    # No need for the temporary file
+    file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt")
+    if(NOT USE_MANUAL)
+      message(WARNING "Found no *nroff option to get plaintext from man pages")
+    endif()
+  else()
+    message(WARNING "Found no *nroff program")
+  endif()
+endif()
 
 # We need ansi c-flags, especially on HP
 set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
@@ -250,9 +321,22 @@ include (CheckCSourceCompiles)
 
 # On windows preload settings
 if(WIN32)
+  set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WINSOCKAPI_")
   include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
 endif(WIN32)
 
+if(ENABLE_THREADED_RESOLVER)
+  check_include_file_concat("pthread.h" HAVE_PTHREAD_H)
+  if(HAVE_PTHREAD_H)
+    set(CMAKE_THREAD_PREFER_PTHREAD 1)
+    find_package(Threads)
+    if(CMAKE_USE_PTHREADS_INIT)
+      set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+      set(USE_THREADS_POSIX 1)
+    endif()
+  endif()
+endif()
+
 # Check for all needed libraries
 if(0) # This code not needed for building within CMake.
 check_library_exists_concat("dl"     dlopen       HAVE_LIBDL)
@@ -277,19 +361,78 @@ if(NOT NOT_NEED_LIBNSL)
   check_library_exists_concat("nsl"    gethostbyname  HAVE_LIBNSL)
 endif(NOT NOT_NEED_LIBNSL)
 
+check_function_exists(gethostname HAVE_GETHOSTNAME)
+
 if(WIN32)
   check_library_exists_concat("ws2_32" getch        HAVE_LIBWS2_32)
   check_library_exists_concat("winmm"  getch        HAVE_LIBWINMM)
 endif()
 
+set(USE_OPENSSL OFF)
+set(HAVE_LIBCRYPTO OFF)
+set(HAVE_LIBSSL OFF)
+
+if(CMAKE_USE_OPENSSL)
+  find_package(OpenSSL)
+  if(OPENSSL_FOUND)
+    list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
+    set(USE_OPENSSL ON)
+    set(HAVE_LIBCRYPTO ON)
+    set(HAVE_LIBSSL ON)
+    include_directories(${OPENSSL_INCLUDE_DIR})
+    set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
+    check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
+    check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
+    check_include_file("openssl/err.h"    HAVE_OPENSSL_ERR_H)
+    check_include_file("openssl/pem.h"    HAVE_OPENSSL_PEM_H)
+    check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
+    check_include_file("openssl/rsa.h"    HAVE_OPENSSL_RSA_H)
+    check_include_file("openssl/ssl.h"    HAVE_OPENSSL_SSL_H)
+    check_include_file("openssl/x509.h"   HAVE_OPENSSL_X509_H)
+    check_include_file("openssl/rand.h"   HAVE_OPENSSL_RAND_H)
+
+    # Optionally build with a specific CA cert bundle.
+    if(CURL_CA_BUNDLE)
+      add_definitions(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}")
+    endif()
+    # Optionally build with a specific CA cert dir.
+    if(CURL_CA_PATH)
+      add_definitions(-DCURL_CA_PATH="${CURL_CA_PATH}")
+    endif()
+  endif()
+elseif(WIN32)
+  # Use Windows SSL/TLS native implementation.
+  add_definitions(-DUSE_SCHANNEL)
+  set(USE_WINDOWS_SSPI 1)
+elseif(APPLE)
+  # Use OS X SSL/TLS native implementation if available on target version.
+  if(CMAKE_OSX_DEPLOYMENT_TARGET)
+    set(OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
+  else()
+    execute_process(
+      COMMAND sw_vers -productVersion
+      OUTPUT_VARIABLE OSX_VERSION
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+      )
+  endif()
+  if(NOT OSX_VERSION VERSION_LESS 10.6 AND
+     CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
+    add_definitions(-DUSE_DARWINSSL)
+    list(APPEND CURL_LIBS
+      "-framework CoreFoundation"
+      "-framework Security"
+      )
+  endif()
+endif()
+
 if(NOT CURL_DISABLE_LDAP)
 
   if(WIN32)
-    option(CURL_LDAP_WIN "Use Windows LDAP implementation" ON)
-    if(CURL_LDAP_WIN)
+    option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
+    if(USE_WIN32_LDAP)
       check_library_exists("wldap32" cldap_open "" HAVE_WLDAP32)
       if(NOT HAVE_WLDAP32)
-        set(CURL_LDAP_WIN OFF)
+        set(USE_WIN32_LDAP OFF)
       endif()
     endif()
   endif()
@@ -299,13 +442,14 @@ if(NOT CURL_DISABLE_LDAP)
   set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library")
   set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library")
 
-  if(CMAKE_USE_OPENLDAP AND CURL_LDAP_WIN)
-    message(FATAL_ERROR "Cannot use CURL_LDAP_WIN and CMAKE_USE_OPENLDAP at the same time")
+  if(CMAKE_USE_OPENLDAP AND USE_WIN32_LDAP)
+    message(FATAL_ERROR "Cannot use USE_WIN32_LDAP and CMAKE_USE_OPENLDAP at the same time")
   endif()
   
   # Now that we know, we're not using windows LDAP...
-  if(NOT CURL_LDAP_WIN)
+  if(NOT USE_WIN32_LDAP)
     # Check for LDAP
+    set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
     check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP)
     check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER)
   else()
@@ -359,8 +503,8 @@ if(NOT CURL_DISABLE_LDAP)
         return 0;
       }"
     )
-    set(CMAKE_REQUIRED_DEFINITIONS "-DLDAP_DEPRECATED=1" "-DWIN32_LEAN_AND_MEAN")
-    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
+    set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DLDAP_DEPRECATED=1")
+    list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
     if(HAVE_LIBLBER)
       list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
     endif()
@@ -394,9 +538,6 @@ check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN)
 # Check for symbol dlopen (same as HAVE_LIBDL)
 check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
 
-# For other tests to use the same libraries
-set(CMAKE_REQUIRED_LIBRARIES ${CURL_LIBS})
-
 if(0) # This code not needed for building within CMake.
 option(CURL_ZLIB "Set to ON to enable building cURL with zlib support." ON)
 set(HAVE_LIBZ OFF)
@@ -409,6 +550,7 @@ if(CURL_ZLIB)
     set(HAVE_ZLIB ON)
     set(HAVE_LIBZ ON)
     list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
+    include_directories(${ZLIB_INCLUDE_DIRS})
   endif()
 endif()
 endif()
@@ -423,67 +565,6 @@ if(CURL_SPECIAL_LIBZ)
   set(HAVE_ZLIB_H 0)
 endif()
 
-#-----------------------------------------------------------------------------
-
-set(USE_SSLEAY OFF)
-set(USE_OPENSSL OFF)
-set(HAVE_LIBCRYPTO OFF)
-set(HAVE_LIBSSL OFF)
-
-if(CMAKE_USE_OPENSSL)
-  find_package(OpenSSL)
-  if(OPENSSL_FOUND)
-    list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
-    set(USE_SSLEAY ON)
-    set(USE_OPENSSL ON)
-    set(HAVE_LIBCRYPTO ON)
-    set(HAVE_LIBSSL ON)
-    include_directories(${OPENSSL_INCLUDE_DIR})
-    set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
-    check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
-    check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
-    check_include_file("openssl/err.h"    HAVE_OPENSSL_ERR_H)
-    check_include_file("openssl/pem.h"    HAVE_OPENSSL_PEM_H)
-    check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
-    check_include_file("openssl/rsa.h"    HAVE_OPENSSL_RSA_H)
-    check_include_file("openssl/ssl.h"    HAVE_OPENSSL_SSL_H)
-    check_include_file("openssl/x509.h"   HAVE_OPENSSL_X509_H)
-    check_include_file("openssl/rand.h"   HAVE_OPENSSL_RAND_H)
-
-    # Optionally build with a specific CA cert bundle.
-    if(CURL_CA_BUNDLE)
-      add_definitions(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}")
-    endif()
-    # Optionally build with a specific CA cert dir.
-    if(CURL_CA_PATH)
-      add_definitions(-DCURL_CA_PATH="${CURL_CA_PATH}")
-    endif()
-  endif(OPENSSL_FOUND)
-elseif(WIN32)
-  # Use Windows SSL/TLS native implementation.
-  add_definitions(-DUSE_SCHANNEL)
-  set(USE_WINDOWS_SSPI 1)
-elseif(APPLE)
-  # Use OS X SSL/TLS native implementation if available on target version.
-  if(CMAKE_OSX_DEPLOYMENT_TARGET)
-    set(OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
-  else()
-    execute_process(
-      COMMAND sw_vers -productVersion
-      OUTPUT_VARIABLE OSX_VERSION
-      OUTPUT_STRIP_TRAILING_WHITESPACE
-      )
-  endif()
-  if(NOT OSX_VERSION VERSION_LESS 10.6 AND
-     CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
-    add_definitions(-DUSE_DARWINSSL)
-    list(APPEND CURL_LIBS
-      "-framework CoreFoundation"
-      "-framework Security"
-      )
-  endif()
-endif()
-
 #libSSH2
 option(CMAKE_USE_LIBSSH2 "Use libSSH2" ON)
 mark_as_advanced(CMAKE_USE_LIBSSH2)
@@ -497,6 +578,7 @@ if(CMAKE_USE_LIBSSH2)
     list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY})
     set(CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBRARY})
     set(CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}")
+    include_directories("${LIBSSH2_INCLUDE_DIR}")
     set(HAVE_LIBSSH2 ON)
     set(USE_LIBSSH2 ON)
 
@@ -517,26 +599,87 @@ if(CMAKE_USE_LIBSSH2)
   endif(LIBSSH2_FOUND)
 endif(CMAKE_USE_LIBSSH2)
 
-# If we have features.h, then do the _BSD_SOURCE magic
-check_include_file("features.h"       HAVE_FEATURES_H)
+option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
+mark_as_advanced(CMAKE_USE_GSSAPI)
 
-# Check for header files
-if(NOT UNIX)
-  check_include_file_concat("ws2tcpip.h"     HAVE_WS2TCPIP_H)
-  check_include_file_concat("winsock2.h"     HAVE_WINSOCK2_H)
+if(CMAKE_USE_GSSAPI)
+  find_package(GSS)
+
+  set(HAVE_GSSAPI ${GSS_FOUND})
+  if(GSS_FOUND)
+
+    message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"")
+
+    set(CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIR})
+    check_include_file_concat("gssapi/gssapi.h"  HAVE_GSSAPI_GSSAPI_H)
+    check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
+    check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H)
+
+    if(GSS_FLAVOUR STREQUAL "Heimdal")
+      set(HAVE_GSSHEIMDAL ON)
+    else() # MIT
+      set(HAVE_GSSMIT ON)
+      set(_INCLUDE_LIST "")
+      if(HAVE_GSSAPI_GSSAPI_H)
+        list(APPEND _INCLUDE_LIST "gssapi/gssapi.h")
+      endif()
+      if(HAVE_GSSAPI_GSSAPI_GENERIC_H)
+        list(APPEND _INCLUDE_LIST "gssapi/gssapi_generic.h")
+      endif()
+      if(HAVE_GSSAPI_GSSAPI_KRB5_H)
+        list(APPEND _INCLUDE_LIST "gssapi/gssapi_krb5.h")
+      endif()
+
+      string(REPLACE ";" " " _COMPILER_FLAGS_STR "${GSS_COMPILER_FLAGS}")
+      string(REPLACE ";" " " _LINKER_FLAGS_STR "${GSS_LINKER_FLAGS}")
+
+      foreach(_dir ${GSS_LINK_DIRECTORIES})
+        set(_LINKER_FLAGS_STR "${_LINKER_FLAGS_STR} -L\"${_dir}\"")
+      endforeach()
+
+      set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}")
+      set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
+      check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+      if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+        set(HAVE_OLD_GSSMIT ON)
+      endif()
+
+    endif()
+
+    include_directories(${GSS_INCLUDE_DIR})
+    link_directories(${GSS_LINK_DIRECTORIES})
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}")
+    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
+    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
+    list(APPEND CURL_LIBS ${GSS_LIBRARIES})
+
+  else()
+    message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.")
+  endif()
+endif()
+
+option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON)
+if(ENABLE_UNIX_SOCKETS)
+  include(CheckStructHasMember)
+  check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
 else()
-  set(HAVE_WS2TCPIP_H 0)
-  set(HAVE_WINSOCK2_H 0)
+  unset(USE_UNIX_SOCKETS CACHE)
 endif()
-check_include_file_concat("stdio.h"          HAVE_STDIO_H)
+
+# Check for header files
 if(NOT UNIX)
   check_include_file_concat("windows.h"      HAVE_WINDOWS_H)
   check_include_file_concat("winsock.h"      HAVE_WINSOCK_H)
+  check_include_file_concat("ws2tcpip.h"     HAVE_WS2TCPIP_H)
+  check_include_file_concat("winsock2.h"     HAVE_WINSOCK2_H)
 else()
   set(HAVE_WINDOWS_H 0)
   set(HAVE_WINSOCK_H 0)
+  set(HAVE_WS2TCPIP_H 0)
+  set(HAVE_WINSOCK2_H 0)
 endif()
 
+check_include_file_concat("stdio.h"          HAVE_STDIO_H)
 check_include_file_concat("inttypes.h"       HAVE_INTTYPES_H)
 check_include_file_concat("sys/filio.h"      HAVE_SYS_FILIO_H)
 check_include_file_concat("sys/ioctl.h"      HAVE_SYS_IOCTL_H)
@@ -561,9 +704,6 @@ check_include_file_concat("des.h"            HAVE_DES_H)
 check_include_file_concat("err.h"            HAVE_ERR_H)
 check_include_file_concat("errno.h"          HAVE_ERRNO_H)
 check_include_file_concat("fcntl.h"          HAVE_FCNTL_H)
-check_include_file_concat("gssapi/gssapi.h"  HAVE_GSSAPI_GSSAPI_H)
-check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
-check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H)
 check_include_file_concat("idn-free.h"       HAVE_IDN_FREE_H)
 check_include_file_concat("ifaddrs.h"        HAVE_IFADDRS_H)
 check_include_file_concat("io.h"             HAVE_IO_H)
@@ -636,6 +776,12 @@ find_file(RANDOM_FILE urandom /dev)
 mark_as_advanced(RANDOM_FILE)
 
 # Check for some functions that are used
+if(HAVE_LIBWS2_32)
+  set(CMAKE_REQUIRED_LIBRARIES ws2_32)
+elseif(HAVE_LIBSOCKET)
+  set(CMAKE_REQUIRED_LIBRARIES socket)
+endif()
+
 check_symbol_exists(basename      "${CURL_INCLUDES}" HAVE_BASENAME)
 check_symbol_exists(socket        "${CURL_INCLUDES}" HAVE_SOCKET)
 check_symbol_exists(poll          "${CURL_INCLUDES}" HAVE_POLL)
@@ -678,7 +824,6 @@ if(CMAKE_USE_OPENSSL)
     HAVE_CRYPTO_CLEANUP_ALL_EX_DATA)
   if(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
     set(USE_OPENSSL 1)
-    set(USE_SSLEAY 1)
   endif(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
 endif(CMAKE_USE_OPENSSL)
 check_symbol_exists(gmtime_r      "${CURL_INCLUDES}" HAVE_GMTIME_R)
@@ -699,6 +844,7 @@ check_symbol_exists(strerror_r     "${CURL_INCLUDES}" HAVE_STRERROR_R)
 check_symbol_exists(siginterrupt   "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
 check_symbol_exists(perror         "${CURL_INCLUDES}" HAVE_PERROR)
 check_symbol_exists(fork           "${CURL_INCLUDES}" HAVE_FORK)
+check_symbol_exists(getaddrinfo    "${CURL_INCLUDES}" HAVE_GETADDRINFO)
 check_symbol_exists(freeaddrinfo   "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
 check_symbol_exists(freeifaddrs    "${CURL_INCLUDES}" HAVE_FREEIFADDRS)
 check_symbol_exists(pipe           "${CURL_INCLUDES}" HAVE_PIPE)
@@ -737,12 +883,7 @@ if(NOT HAVE_STRICMP)
   set(HAVE_LDAP_URL_PARSE 1)
 endif(NOT HAVE_STRICMP)
 
-
-
 # Do curl specific tests
-if(HAVE_LIBWS2_32)
-  set(CMAKE_REQUIRED_LIBRARIES ws2_32)
-endif()
 foreach(CURL_TEST
     HAVE_FCNTL_O_NONBLOCK
     HAVE_IOCTLSOCKET
@@ -929,24 +1070,6 @@ if(MSVC)
   add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
 endif(MSVC)
 
-# Sets up the dependencies (zlib, OpenSSL, etc.) of a cURL subproject according to options.
-# TODO This is far to be complete!
-function(SETUP_CURL_DEPENDENCIES TARGET_NAME)
-  if(CURL_ZLIB AND ZLIB_FOUND)
-    include_directories(${ZLIB_INCLUDE_DIR})
-  endif()
-
-  if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND)
-    include_directories(${OPENSSL_INCLUDE_DIR})
-  endif()
-
-  if(CMAKE_USE_LIBSSH2 AND LIBSSH2_FOUND)
-    include_directories(${LIBSSH2_INCLUDE_DIR})
-  endif()
-
-  target_link_libraries(${TARGET_NAME} ${CURL_LIBS})
-endfunction()
-
 # Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
 function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
   file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT)
@@ -984,6 +1107,133 @@ install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmcurl)
 #-----------------------------------------------------------------------------
 
 if(0) # This code not needed for building within CMake.
+# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL, WINSSL, DARWINSSL
+if(USE_OPENSSL)
+  set(SSL_ENABLED 1)
+endif()
+
+# Helper to populate a list (_items) with a label when conditions (the remaining
+# args) are satisfied
+function(_add_if label)
+  # TODO need to disable policy CMP0054 (CMake 3.1) to allow this indirection
+  if(${ARGN})
+    set(_items ${_items} "${label}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+# Clear list and try to detect available features
+set(_items)
+_add_if("SSL"           SSL_ENABLED)
+_add_if("IPv6"          ENABLE_IPV6)
+_add_if("unix-sockets"  USE_UNIX_SOCKETS)
+_add_if("libz"          HAVE_LIBZ)
+_add_if("AsynchDNS"     USE_ARES OR USE_THREADS_POSIX)
+_add_if("IDN"           HAVE_LIBIDN)
+# TODO SSP1 (WinSSL) check is missing
+_add_if("SSPI"          USE_WINDOWS_SSPI)
+_add_if("GSS-API"       HAVE_GSSAPI)
+# TODO SSP1 missing for SPNEGO
+_add_if("SPNEGO"        NOT CURL_DISABLE_CRYPTO_AUTH AND
+                        (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
+_add_if("Kerberos"      NOT CURL_DISABLE_CRYPTO_AUTH AND
+                        (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
+# NTLM support requires crypto function adaptions from various SSL libs
+# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS, DARWINSSL
+if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR
+   USE_WINDOWS_SSPI OR GNUTLS_ENABLED OR NSS_ENABLED OR DARWINSSL_ENABLED))
+  _add_if("NTLM"        1)
+  # TODO missing option (autoconf: --enable-ntlm-wb)
+  _add_if("NTLM_WB"     NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
+endif()
+# TODO missing option (--enable-tls-srp), depends on GNUTLS_SRP/OPENSSL_SRP
+_add_if("TLS-SRP"       USE_TLS_SRP)
+# TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header
+_add_if("HTTP2"         USE_NGHTTP2)
+string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
+message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
+
+# Clear list and try to detect available protocols
+set(_items)
+_add_if("HTTP"          NOT CURL_DISABLE_HTTP)
+_add_if("HTTPS"         NOT CURL_DISABLE_HTTP AND SSL_ENABLED)
+_add_if("FTP"           NOT CURL_DISABLE_FTP)
+_add_if("FTPS"          NOT CURL_DISABLE_FTP AND SSL_ENABLED)
+_add_if("FILE"          NOT CURL_DISABLE_FILE)
+_add_if("TELNET"        NOT CURL_DISABLE_TELNET)
+_add_if("LDAP"          NOT CURL_DISABLE_LDAP)
+# CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS
+# TODO check HAVE_LDAP_SSL (in autoconf this is enabled with --enable-ldaps)
+_add_if("LDAPS"         NOT CURL_DISABLE_LDAPS AND
+                        ((USE_OPENLDAP AND SSL_ENABLED) OR
+                        (NOT USE_OPENLDAP AND HAVE_LDAP_SSL)))
+_add_if("DICT"          NOT CURL_DISABLE_DICT)
+_add_if("TFTP"          NOT CURL_DISABLE_TFTP)
+_add_if("GOPHER"        NOT CURL_DISABLE_GOPHER)
+_add_if("POP3"          NOT CURL_DISABLE_POP3)
+_add_if("POP3S"         NOT CURL_DISABLE_POP3 AND SSL_ENABLED)
+_add_if("IMAP"          NOT CURL_DISABLE_IMAP)
+_add_if("IMAPS"         NOT CURL_DISABLE_IMAP AND SSL_ENABLED)
+_add_if("SMTP"          NOT CURL_DISABLE_SMTP)
+_add_if("SMTPS"         NOT CURL_DISABLE_SMTP AND SSL_ENABLED)
+_add_if("SCP"           USE_LIBSSH2)
+_add_if("SFTP"          USE_LIBSSH2)
+_add_if("RTSP"          NOT CURL_DISABLE_RTSP)
+_add_if("RTMP"          USE_LIBRTMP)
+list(SORT _items)
+string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}")
+message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}")
+
+# curl-config needs the following options to be set.
+set(CC                      "${CMAKE_C_COMPILER}")
+# TODO probably put a -D... options here?
+set(CONFIGURE_OPTIONS       "")
+# TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB?
+set(CPPFLAG_CURL_STATICLIB  "")
+# TODO need to set this (see CURL_CHECK_CA_BUNDLE in acinclude.m4)
+set(CURL_CA_BUNDLE          "")
+set(CURLVERSION             "${CURL_VERSION}")
+set(ENABLE_SHARED           "yes")
+if(CURL_STATICLIB)
+  # Broken: LIBCURL_LIBS below; .a lib is not built
+  message(WARNING "Static linking is broken!")
+  set(ENABLE_STATIC         "no")
+else()
+  set(ENABLE_STATIC         "no")
+endif()
+set(exec_prefix             "\${prefix}")
+set(includedir              "\${prefix}/include")
+set(LDFLAGS                 "${CMAKE_SHARED_LINKER_FLAGS}")
+set(LIBCURL_LIBS            "")
+set(libdir                  "${CMAKE_INSTALL_PREFIX}/lib")
+# TODO CURL_LIBS also contains absolute paths which don't work with static -l...
+foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
+  set(LIBCURL_LIBS          "${LIBCURL_LIBS} -l${_lib}")
+endforeach()
+# "a" (Linux) or "lib" (Windows)
+string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
+set(prefix                  "${CMAKE_INSTALL_PREFIX}")
+# Set this to "yes" to append all libraries on which -lcurl is dependent
+set(REQUIRE_LIB_DEPS        "no")
+# SUPPORT_FEATURES
+# SUPPORT_PROTOCOLS
+set(VERSIONNUM              "${CURL_VERSION_NUM}")
+
+# Finally generate a "curl-config" matching this config
+configure_file("${CURL_SOURCE_DIR}/curl-config.in"
+               "${CURL_BINARY_DIR}/curl-config" @ONLY)
+install(FILES "${CMAKE_BINARY_DIR}/curl-config"
+        DESTINATION bin
+        PERMISSIONS
+          OWNER_READ OWNER_WRITE OWNER_EXECUTE
+          GROUP_READ GROUP_EXECUTE
+          WORLD_READ WORLD_EXECUTE)
+
+# Finally generate a pkg-config file matching this config
+configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in"
+               "${CURL_BINARY_DIR}/libcurl.pc" @ONLY)
+install(FILES "${CMAKE_BINARY_DIR}/libcurl.pc"
+        DESTINATION lib/pkgconfig)
+
 # This needs to be run very last so other parts of the scripts can take advantage of this.
 if(NOT CURL_CONFIG_HAS_BEEN_RUN_BEFORE)
   set(CURL_CONFIG_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL "Flag to track whether this is the first time running CMake or if CMake has been configured before")
diff --git a/Utilities/cmcurl/COPYING b/Utilities/cmcurl/COPYING
index dd990b6..6b5d59f 100644
--- a/Utilities/cmcurl/COPYING
+++ b/Utilities/cmcurl/COPYING
@@ -1,6 +1,6 @@
 COPYRIGHT AND PERMISSION NOTICE
 
-Copyright (c) 1996 - 2014, Daniel Stenberg, <daniel at haxx.se>.
+Copyright (c) 1996 - 2015, Daniel Stenberg, <daniel at haxx.se>.
 
 All rights reserved.
 
diff --git a/Utilities/cmcurl/README-CMake.txt b/Utilities/cmcurl/README-CMake.txt
index 3f053d8..1e75672 100644
--- a/Utilities/cmcurl/README-CMake.txt
+++ b/Utilities/cmcurl/README-CMake.txt
@@ -11,7 +11,7 @@ branch, but it is merged into our history.
 Update curl from upstream as follows.  Create a local branch to
 explicitly reference the upstream snapshot branch head:
 
- git branch curl-upstream 3fe5d9bf
+ git branch curl-upstream 70654261
 
 Use a temporary directory to checkout the branch:
 
@@ -24,7 +24,7 @@ Use a temporary directory to checkout the branch:
 Now place the (reduced) curl content in this directory.  See
 instructions shown by
 
- git log 3fe5d9bf
+ git log 70654261
 
 for help extracting the content from the upstream repo.  Then run
 the following commands to commit the new version.  Substitute the
@@ -34,8 +34,8 @@ appropriate date and version number:
 
  GIT_AUTHOR_NAME='Curl Upstream' \
  GIT_AUTHOR_EMAIL='curl-library at cool.haxx.se' \
- GIT_AUTHOR_DATE='Wed Sep 10 08:07:58 2014 +0200' \
- git commit -m 'curl 7.38.0 (reduced)' &&
+ GIT_AUTHOR_DATE='Tue Aug 11 20:13:01 2015 +0200' \
+ git commit -m 'curl 7.44.0 (reduced)' &&
  git commit --amend
 
 Edit the commit message to describe the procedure used to obtain the
diff --git a/Utilities/cmcurl/include/curl/curl.h b/Utilities/cmcurl/include/curl/curl.h
index 40d0b81..86ce1ff 100644
--- a/Utilities/cmcurl/include/curl/curl.h
+++ b/Utilities/cmcurl/include/curl/curl.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -521,6 +521,9 @@ typedef enum {
   CURLE_CHUNK_FAILED,            /* 88 - chunk callback reported error */
   CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
                                     session will be queued */
+  CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
+                                     match */
+  CURLE_SSL_INVALIDCERTSTATUS,   /* 91 - invalid certificate status */
   CURL_LAST /* never use! */
 } CURLcode;
 
@@ -722,6 +725,10 @@ typedef enum {
    servers, a user can this way allow the vulnerability back. */
 #define CURLSSLOPT_ALLOW_BEAST (1<<0)
 
+/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
+   SSL backends where such behavior is present. */
+#define CURLSSLOPT_NO_REVOKE (1<<1)
+
 #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
                           the obsolete stuff removed! */
 
@@ -803,6 +810,8 @@ typedef enum {
 #define CURLPROTO_RTMPS  (1<<23)
 #define CURLPROTO_RTMPTS (1<<24)
 #define CURLPROTO_GOPHER (1<<25)
+#define CURLPROTO_SMB    (1<<26)
+#define CURLPROTO_SMBS   (1<<27)
 #define CURLPROTO_ALL    (~0) /* enable everything */
 
 /* long may be 32 or 64 bits, but we should never depend on anything else
@@ -841,7 +850,7 @@ typedef enum {
   CINIT(WRITEDATA, OBJECTPOINT, 1),
 
   /* The full URL to get/put */
-  CINIT(URL,  OBJECTPOINT, 2),
+  CINIT(URL, OBJECTPOINT, 2),
 
   /* Port number to connect to, if other than default. */
   CINIT(PORT, LONG, 3),
@@ -985,7 +994,7 @@ typedef enum {
   CINIT(HEADER, LONG, 42),       /* throw the header out too */
   CINIT(NOPROGRESS, LONG, 43),   /* shut off the progress meter */
   CINIT(NOBODY, LONG, 44),       /* use HEAD to get http document */
-  CINIT(FAILONERROR, LONG, 45),  /* no output on http error codes >= 300 */
+  CINIT(FAILONERROR, LONG, 45),  /* no output on http error codes >= 400 */
   CINIT(UPLOAD, LONG, 46),       /* this is an upload */
   CINIT(POST, LONG, 47),         /* HTTP POST method */
   CINIT(DIRLISTONLY, LONG, 48),  /* bare names when listing directories */
@@ -1611,6 +1620,31 @@ typedef enum {
   /* Pass in a bitmask of "header options" */
   CINIT(HEADEROPT, LONG, 229),
 
+  /* The public key in DER form used to validate the peer public key
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(PINNEDPUBLICKEY, OBJECTPOINT, 230),
+
+  /* Path to Unix domain socket */
+  CINIT(UNIX_SOCKET_PATH, OBJECTPOINT, 231),
+
+  /* Set if we should verify the certificate status. */
+  CINIT(SSL_VERIFYSTATUS, LONG, 232),
+
+  /* Set if we should enable TLS false start. */
+  CINIT(SSL_FALSESTART, LONG, 233),
+
+  /* Do not squash dot-dot sequences */
+  CINIT(PATH_AS_IS, LONG, 234),
+
+  /* Proxy Service Name */
+  CINIT(PROXY_SERVICE_NAME, OBJECTPOINT, 235),
+
+  /* Service Name */
+  CINIT(SERVICE_NAME, OBJECTPOINT, 236),
+
+  /* Wait/don't wait for pipe/mutex to clarify */
+  CINIT(PIPEWAIT, LONG, 237),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
@@ -1647,8 +1681,8 @@ typedef enum {
      option might be handy to force libcurl to use a specific IP version. */
 #define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
                                      versions that your system allows */
-#define CURL_IPRESOLVE_V4       1 /* resolve to ipv4 addresses */
-#define CURL_IPRESOLVE_V6       2 /* resolve to ipv6 addresses */
+#define CURL_IPRESOLVE_V4       1 /* resolve to IPv4 addresses */
+#define CURL_IPRESOLVE_V6       2 /* resolve to IPv6 addresses */
 
   /* three convenient "aliases" that follow the name scheme better */
 #define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
@@ -1665,6 +1699,11 @@ enum {
   CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
 };
 
+/* Convenience definition simple because the name of the version is HTTP/2 and
+   not 2.0. The 2_0 version of the enum name was set while the version was
+   still planned to be 2.0 and we stick to it for compatibility. */
+#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
+
 /*
  * Public API enums for RTSP requests
  */
@@ -2028,7 +2067,7 @@ typedef enum {
   CURLSSLBACKEND_OPENSSL = 1,
   CURLSSLBACKEND_GNUTLS = 2,
   CURLSSLBACKEND_NSS = 3,
-  CURLSSLBACKEND_QSOSSL = 4,
+  CURLSSLBACKEND_OBSOLETE4 = 4,  /* Was QSOSSL. */
   CURLSSLBACKEND_GSKIT = 5,
   CURLSSLBACKEND_POLARSSL = 6,
   CURLSSLBACKEND_CYASSL = 7,
@@ -2235,25 +2274,30 @@ typedef struct {
 
 } curl_version_info_data;
 
-#define CURL_VERSION_IPV6      (1<<0)  /* IPv6-enabled */
-#define CURL_VERSION_KERBEROS4 (1<<1)  /* kerberos auth is supported */
-#define CURL_VERSION_SSL       (1<<2)  /* SSL options are present */
-#define CURL_VERSION_LIBZ      (1<<3)  /* libz features are present */
-#define CURL_VERSION_NTLM      (1<<4)  /* NTLM auth is supported */
-#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support
-                                            (deprecated) */
-#define CURL_VERSION_DEBUG     (1<<6)  /* built with debug capabilities */
-#define CURL_VERSION_ASYNCHDNS (1<<7)  /* asynchronous dns resolves */
-#define CURL_VERSION_SPNEGO    (1<<8)  /* SPNEGO auth is supported */
-#define CURL_VERSION_LARGEFILE (1<<9)  /* supports files bigger than 2GB */
-#define CURL_VERSION_IDN       (1<<10) /* International Domain Names support */
-#define CURL_VERSION_SSPI      (1<<11) /* SSPI is supported */
-#define CURL_VERSION_CONV      (1<<12) /* character conversions supported */
-#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
-#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
-#define CURL_VERSION_NTLM_WB   (1<<15) /* NTLM delegating to winbind helper */
-#define CURL_VERSION_HTTP2     (1<<16) /* HTTP2 support built-in */
-#define CURL_VERSION_GSSAPI    (1<<17) /* GSS-API is supported */
+#define CURL_VERSION_IPV6         (1<<0)  /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4    (1<<1)  /* Kerberos V4 auth is supported
+                                             (deprecated) */
+#define CURL_VERSION_SSL          (1<<2)  /* SSL options are present */
+#define CURL_VERSION_LIBZ         (1<<3)  /* libz features are present */
+#define CURL_VERSION_NTLM         (1<<4)  /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5)  /* Negotiate auth is supported
+                                             (deprecated) */
+#define CURL_VERSION_DEBUG        (1<<6)  /* Built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS    (1<<7)  /* Asynchronous DNS resolves */
+#define CURL_VERSION_SPNEGO       (1<<8)  /* SPNEGO auth is supported */
+#define CURL_VERSION_LARGEFILE    (1<<9)  /* Supports files larger than 2GB */
+#define CURL_VERSION_IDN          (1<<10) /* Internationized Domain Names are
+                                             supported */
+#define CURL_VERSION_SSPI         (1<<11) /* Built against Windows SSPI */
+#define CURL_VERSION_CONV         (1<<12) /* Character conversions supported */
+#define CURL_VERSION_CURLDEBUG    (1<<13) /* Debug memory tracking supported */
+#define CURL_VERSION_TLSAUTH_SRP  (1<<14) /* TLS-SRP auth is supported */
+#define CURL_VERSION_NTLM_WB      (1<<15) /* NTLM delegation to winbind helper
+                                             is suported */
+#define CURL_VERSION_HTTP2        (1<<16) /* HTTP2 support built-in */
+#define CURL_VERSION_GSSAPI       (1<<17) /* Built against a GSS-API library */
+#define CURL_VERSION_KERBEROS5    (1<<18) /* Kerberos V5 auth is supported */
+#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
 
  /*
  * NAME curl_version_info()
diff --git a/Utilities/cmcurl/include/curl/curlver.h b/Utilities/cmcurl/include/curl/curlver.h
index c0cb509..a41fdef 100644
--- a/Utilities/cmcurl/include/curl/curlver.h
+++ b/Utilities/cmcurl/include/curl/curlver.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,16 +26,16 @@
    a script at release-time. This was made its own header file in 7.11.2 */
 
 /* This is the global package copyright */
-#define LIBCURL_COPYRIGHT "1996 - 2014 Daniel Stenberg, <daniel at haxx.se>."
+#define LIBCURL_COPYRIGHT "1996 - 2015 Daniel Stenberg, <daniel at haxx.se>."
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.38.0"
+#define LIBCURL_VERSION "7.44.0"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 38
+#define LIBCURL_VERSION_MINOR 44
 #define LIBCURL_VERSION_PATCH 0
 
 /* This is the numeric version of the libcurl version number, meant for easier
@@ -52,8 +52,12 @@
    This 6-digit (24 bits) hexadecimal number does not show pre-release number,
    and it is always a greater number in a more recent release. It makes
    comparisons with greater than and less than work.
+
+   Note: This define is the full hex number and _does not_ use the
+   CURL_VERSION_BITS() macro since curl's own configure script greps for it
+   and needs it to contain the full number.
 */
-#define LIBCURL_VERSION_NUM 0x072600
+#define LIBCURL_VERSION_NUM 0x072C00
 
 /*
  * This is the date and time when the full source package was created. The
@@ -66,4 +70,8 @@
  */
 #define LIBCURL_TIMESTAMP "DEV"
 
+#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
+#define CURL_AT_LEAST_VERSION(x,y,z) \
+  (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
+
 #endif /* __CURL_CURLVER_H */
diff --git a/Utilities/cmcurl/include/curl/mprintf.h b/Utilities/cmcurl/include/curl/mprintf.h
index cc9e7f5..c6b0d76 100644
--- a/Utilities/cmcurl/include/curl/mprintf.h
+++ b/Utilities/cmcurl/include/curl/mprintf.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -57,15 +57,8 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
 # undef vaprintf
 # define printf curl_mprintf
 # define fprintf curl_mfprintf
-#ifdef CURLDEBUG
-/* When built with CURLDEBUG we define away the sprintf functions since we
-   don't want internal code to be using them */
-# define sprintf sprintf_was_used
-# define vsprintf vsprintf_was_used
-#else
 # define sprintf curl_msprintf
 # define vsprintf curl_mvsprintf
-#endif
 # define snprintf curl_msnprintf
 # define vprintf curl_mvprintf
 # define vfprintf curl_mvfprintf
diff --git a/Utilities/cmcurl/include/curl/multi.h b/Utilities/cmcurl/include/curl/multi.h
index 10d6006..0f1561d 100644
--- a/Utilities/cmcurl/include/curl/multi.h
+++ b/Utilities/cmcurl/include/curl/multi.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -74,6 +74,11 @@ typedef enum {
    curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
 #define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
 
+/* bitmask bits for CURLMOPT_PIPELINING */
+#define CURLPIPE_NOTHING   0L
+#define CURLPIPE_HTTP1     1L
+#define CURLPIPE_MULTIPLEX 2L
+
 typedef enum {
   CURLMSG_NONE, /* first, not used */
   CURLMSG_DONE, /* This easy handle has completed. 'result' contains
@@ -365,6 +370,12 @@ typedef enum {
   /* maximum number of open connections in total */
   CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
 
+   /* This is the server push callback function pointer */
+  CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
+
+  /* This is the argument passed to the server push callback */
+  CINIT(PUSHDATA, OBJECTPOINT, 15),
+
   CURLMOPT_LASTENTRY /* the last unused */
 } CURLMoption;
 
@@ -392,6 +403,31 @@ CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
 CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
                                         curl_socket_t sockfd, void *sockp);
 
+
+/*
+ * Name: curl_push_callback
+ *
+ * Desc: This callback gets called when a new stream is being pushed by the
+ *       server. It approves or denies the new stream.
+ *
+ * Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
+ */
+#define CURL_PUSH_OK   0
+#define CURL_PUSH_DENY 1
+
+struct curl_pushheaders;  /* forward declaration only */
+
+CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
+                                        size_t num);
+CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
+                                         const char *name);
+
+typedef int (*curl_push_callback)(CURL *parent,
+                                  CURL *easy,
+                                  size_t num_headers,
+                                  struct curl_pushheaders *headers,
+                                  void *userp);
+
 #ifdef __cplusplus
 } /* end of extern "C" */
 #endif
diff --git a/Utilities/cmcurl/include/curl/typecheck-gcc.h b/Utilities/cmcurl/include/curl/typecheck-gcc.h
index 69d41a2..13fb0fa 100644
--- a/Utilities/cmcurl/include/curl/typecheck-gcc.h
+++ b/Utilities/cmcurl/include/curl/typecheck-gcc.h
@@ -270,6 +270,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
    (option) == CURLOPT_DNS_LOCAL_IP4 ||                                       \
    (option) == CURLOPT_DNS_LOCAL_IP6 ||                                       \
    (option) == CURLOPT_LOGIN_OPTIONS ||                                       \
+   (option) == CURLOPT_PROXY_SERVICE_NAME ||                                  \
+   (option) == CURLOPT_SERVICE_NAME ||                                        \
    0)
 
 /* evaluates to true if option takes a curl_write_callback argument */
diff --git a/Utilities/cmcurl/lib/CMakeLists.txt b/Utilities/cmcurl/lib/CMakeLists.txt
index a4621c1..0d7b717 100644
--- a/Utilities/cmcurl/lib/CMakeLists.txt
+++ b/Utilities/cmcurl/lib/CMakeLists.txt
@@ -48,25 +48,6 @@ endif()
 # )
 # ENDIF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64)
 
-if(HAVE_FEATURES_H)
-  set_source_files_properties(
-    cookie.c
-    easy.c
-    formdata.c
-    getenv.c
-    nonblock.c
-    hash.c
-    http.c
-    if2ip.c
-    mprintf.c
-    multi.c
-    sendf.c
-    telnet.c
-    transfer.c
-    url.c
-    COMPILE_FLAGS -D_BSD_SOURCE)
-endif(HAVE_FEATURES_H)
-
 
 # The rest of the build
 
@@ -76,7 +57,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
 include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
-if(CURL_USE_ARES)
+if(USE_ARES)
   include_directories(${CARES_INCLUDE_DIR})
 endif()
 
@@ -129,8 +110,6 @@ endif()
 
 set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
 
-setup_curl_dependencies(${LIB_NAME})
-
 if(0) # This code not needed for building within CMake.
 # Remove the "lib" prefix since the library is already named "libcurl".
 set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
@@ -143,5 +122,8 @@ if(WIN32)
   endif()
 endif()
 
-install(TARGETS ${LIB_NAME} DESTINATION lib)
+install(TARGETS ${LIB_NAME}
+  ARCHIVE DESTINATION lib
+  LIBRARY DESTINATION lib
+  RUNTIME DESTINATION bin)
 endif()
diff --git a/Utilities/cmcurl/lib/Makefile.inc b/Utilities/cmcurl/lib/Makefile.inc
index 462d72a..d444a6b 100644
--- a/Utilities/cmcurl/lib/Makefile.inc
+++ b/Utilities/cmcurl/lib/Makefile.inc
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -20,50 +20,52 @@
 #
 ###########################################################################
 
-LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c	\
-  vtls/qssl.c vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c	\
-  vtls/cyassl.c vtls/curl_schannel.c vtls/curl_darwinssl.c vtls/gskit.c
+LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c     \
+  vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c               \
+  vtls/cyassl.c vtls/schannel.c vtls/darwinssl.c vtls/gskit.c
 
-LIB_VTLS_HFILES = vtls/qssl.h vtls/openssl.h vtls/vtls.h vtls/gtls.h	\
-  vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h	\
-  vtls/cyassl.h vtls/curl_schannel.h vtls/curl_darwinssl.h vtls/gskit.h
+LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h                \
+  vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h   \
+  vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h
 
-LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c	\
-  cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c	\
-  ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c		\
-  getinfo.c transfer.c strequal.c easy.c security.c curl_fnmatch.c	\
-  fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c	\
-  strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c	\
-  http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c	\
-  strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c		\
-  inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c	\
-  ssh.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c		\
-  curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c	\
-  pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c	\
-  openldap.c curl_gethostname.c gopher.c idn_win32.c			\
-  http_negotiate_sspi.c http_proxy.c non-ascii.c asyn-ares.c		\
-  asyn-thread.c curl_gssapi.c curl_ntlm.c curl_ntlm_wb.c		\
-  curl_ntlm_core.c curl_ntlm_msgs.c curl_sasl.c curl_multibyte.c	\
-  hostcheck.c bundles.c conncache.c pipeline.c dotdot.c x509asn1.c	\
-  http2.c curl_sasl_sspi.c
+LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c   \
+  cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c       \
+  ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c         \
+  getinfo.c transfer.c strequal.c easy.c security.c curl_fnmatch.c      \
+  fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
+  strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c  \
+  http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c    \
+  strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c         \
+  inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c      \
+  ssh.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c            \
+  curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c    \
+  pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c        \
+  openldap.c curl_gethostname.c gopher.c idn_win32.c                    \
+  http_negotiate_sspi.c http_proxy.c non-ascii.c asyn-ares.c            \
+  asyn-thread.c curl_gssapi.c curl_ntlm.c curl_ntlm_wb.c                \
+  curl_ntlm_core.c curl_ntlm_msgs.c curl_sasl.c curl_multibyte.c        \
+  hostcheck.c conncache.c pipeline.c dotdot.c x509asn1.c                \
+  http2.c curl_sasl_sspi.c smb.c curl_sasl_gssapi.c curl_endian.c       \
+  curl_des.c
 
-LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h	\
-  formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h		\
-  speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h	\
-  strequal.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h		\
-  wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h	\
-  hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h	\
-  http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h		\
-  inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h	\
-  easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h	\
-  socks.h ssh.h curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h	\
-  slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h	\
-  rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h		\
-  curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h		\
-  curl_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h		\
-  curl_ntlm_msgs.h curl_sasl.h curl_multibyte.h hostcheck.h bundles.h	\
-  conncache.h curl_setup_once.h multihandle.h setup-vms.h pipeline.h	\
-  dotdot.h x509asn1.h http2.h sigpipe.h
+LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
+  formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h         \
+  speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h        \
+  strequal.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h         \
+  wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h      \
+  hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
+  http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h         \
+  inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h    \
+  easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h     \
+  socks.h ssh.h curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h      \
+  slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h     \
+  rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h              \
+  curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h           \
+  curl_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h             \
+  curl_ntlm_msgs.h curl_sasl.h curl_multibyte.h hostcheck.h             \
+  conncache.h curl_setup_once.h multihandle.h setup-vms.h pipeline.h    \
+  dotdot.h x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h  \
+  curl_printf.h
 
 LIB_RCFILES = libcurl.rc
 
diff --git a/Utilities/cmcurl/lib/amigaos.c b/Utilities/cmcurl/lib/amigaos.c
index 34f95e9..e3ff85f 100644
--- a/Utilities/cmcurl/lib/amigaos.c
+++ b/Utilities/cmcurl/lib/amigaos.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -71,7 +71,7 @@ bool Curl_amiga_init()
 }
 
 #ifdef __libnix__
-ADD2EXIT(Curl_amiga_cleanup,-50);
+ADD2EXIT(Curl_amiga_cleanup, -50);
 #endif
 
 #endif /* __AMIGA__ && ! __ixemul__ */
diff --git a/Utilities/cmcurl/lib/asyn-ares.c b/Utilities/cmcurl/lib/asyn-ares.c
index 01a9c9b..98ecdfd 100644
--- a/Utilities/cmcurl/lib/asyn-ares.c
+++ b/Utilities/cmcurl/lib/asyn-ares.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -68,9 +68,7 @@
 #include "connect.h"
 #include "select.h"
 #include "progress.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
      (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
@@ -166,7 +164,7 @@ void Curl_resolver_cleanup(void *resolver)
 int Curl_resolver_duphandle(void **to, void *from)
 {
   /* Clone the ares channel for the new handle */
-  if(ARES_SUCCESS != ares_dup((ares_channel*)to,(ares_channel)from))
+  if(ARES_SUCCESS != ares_dup((ares_channel*)to, (ares_channel)from))
     return CURLE_FAILED_INIT;
   return CURLE_OK;
 }
@@ -178,7 +176,7 @@ static void destroy_async_data (struct Curl_async *async);
  */
 void Curl_resolver_cancel(struct connectdata *conn)
 {
-  if(conn && conn->data && conn->data->state.resolver)
+  if(conn->data && conn->data->state.resolver)
     ares_cancel((ares_channel)conn->data->state.resolver);
   destroy_async_data(&conn->async);
 }
@@ -188,8 +186,7 @@ void Curl_resolver_cancel(struct connectdata *conn)
  */
 static void destroy_async_data (struct Curl_async *async)
 {
-  if(async->hostname)
-    free(async->hostname);
+  free(async->hostname);
 
   if(async->os_specific) {
     struct ResolverResults *res = (struct ResolverResults *)async->os_specific;
@@ -315,7 +312,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
   struct SessionHandle *data = conn->data;
   struct ResolverResults *res = (struct ResolverResults *)
     conn->async.os_specific;
-  CURLcode rc = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   *dns = NULL;
 
@@ -329,7 +326,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
     if(!conn->async.dns) {
       failf(data, "Could not resolve: %s (%s)",
             conn->async.hostname, ares_strerror(conn->async.status));
-      rc = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
+      result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
         CURLE_COULDNT_RESOLVE_HOST;
     }
     else
@@ -338,7 +335,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
     destroy_async_data(&conn->async);
   }
 
-  return rc;
+  return result;
 }
 
 /*
@@ -355,7 +352,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
 CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
                                    struct Curl_dns_entry **entry)
 {
-  CURLcode rc=CURLE_OK;
+  CURLcode result = CURLE_OK;
   struct SessionHandle *data = conn->data;
   long timeout;
   struct timeval now = Curl_tvnow();
@@ -388,13 +385,13 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
       timeout_ms = 1000;
 
     waitperform(conn, timeout_ms);
-    Curl_resolver_is_resolved(conn,&temp_entry);
+    Curl_resolver_is_resolved(conn, &temp_entry);
 
     if(conn->async.done)
       break;
 
     if(Curl_pgrsUpdate(conn)) {
-      rc = CURLE_ABORTED_BY_CALLBACK;
+      result = CURLE_ABORTED_BY_CALLBACK;
       timeout = -1; /* trigger the cancel below */
     }
     else {
@@ -403,6 +400,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
       timeout -= timediff?timediff:1; /* always deduct at least 1 */
       now = now2; /* for next loop */
     }
+
     if(timeout < 0) {
       /* our timeout, so we cancel the ares operation */
       ares_cancel((ares_channel)data->state.resolver);
@@ -412,18 +410,17 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
 
   /* Operation complete, if the lookup was successful we now have the entry
      in the cache. */
-
   if(entry)
     *entry = conn->async.dns;
 
-  if(rc)
+  if(result)
     /* close the connection, since we can't return failure here without
        cleaning up this connection properly.
        TODO: remove this action from here, it is not a name resolver decision.
     */
     connclose(conn, "c-ares resolve failed");
 
-  return rc;
+  return result;
 }
 
 /* Connects results to the list */
@@ -536,15 +533,15 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
   bufp = strdup(hostname);
   if(bufp) {
     struct ResolverResults *res = NULL;
-    Curl_safefree(conn->async.hostname);
+    free(conn->async.hostname);
     conn->async.hostname = bufp;
     conn->async.port = port;
     conn->async.done = FALSE;   /* not done */
     conn->async.status = 0;     /* clear */
     conn->async.dns = NULL;     /* clear */
-    res = calloc(sizeof(struct ResolverResults),1);
+    res = calloc(sizeof(struct ResolverResults), 1);
     if(!res) {
-      Curl_safefree(conn->async.hostname);
+      free(conn->async.hostname);
       conn->async.hostname = NULL;
       return NULL;
     }
diff --git a/Utilities/cmcurl/lib/asyn-thread.c b/Utilities/cmcurl/lib/asyn-thread.c
index e4ad32b..bd47d5a 100644
--- a/Utilities/cmcurl/lib/asyn-thread.c
+++ b/Utilities/cmcurl/lib/asyn-thread.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -69,11 +69,9 @@
 #include "inet_ntop.h"
 #include "curl_threads.h"
 #include "connect.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
+
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -192,13 +190,12 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
     free(tsd->mtx);
   }
 
-  if(tsd->hostname)
-    free(tsd->hostname);
+  free(tsd->hostname);
 
   if(tsd->res)
     Curl_freeaddrinfo(tsd->res);
 
-  memset(tsd,0,sizeof(*tsd));
+  memset(tsd, 0, sizeof(*tsd));
 }
 
 /* Initialize resolver thread synchronization data */
@@ -366,9 +363,7 @@ static void destroy_async_data (struct Curl_async *async)
   }
   async->os_specific = NULL;
 
-  if(async->hostname)
-    free(async->hostname);
-
+  free(async->hostname);
   async->hostname = NULL;
 }
 
@@ -398,7 +393,7 @@ static bool init_resolve_thread (struct connectdata *conn,
   if(!init_thread_sync_data(td, hostname, port, hints))
     goto err_exit;
 
-  Curl_safefree(conn->async.hostname);
+  free(conn->async.hostname);
   conn->async.hostname = strdup(hostname);
   if(!conn->async.hostname)
     goto err_exit;
@@ -434,19 +429,21 @@ static bool init_resolve_thread (struct connectdata *conn,
 static CURLcode resolver_error(struct connectdata *conn)
 {
   const char *host_or_proxy;
-  CURLcode rc;
+  CURLcode result;
+
   if(conn->bits.httpproxy) {
     host_or_proxy = "proxy";
-    rc = CURLE_COULDNT_RESOLVE_PROXY;
+    result = CURLE_COULDNT_RESOLVE_PROXY;
   }
   else {
     host_or_proxy = "host";
-    rc = CURLE_COULDNT_RESOLVE_HOST;
+    result = CURLE_COULDNT_RESOLVE_HOST;
   }
 
   failf(conn->data, "Could not resolve %s: %s", host_or_proxy,
         conn->async.hostname);
-  return rc;
+
+  return result;
 }
 
 /*
@@ -463,13 +460,13 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
                                    struct Curl_dns_entry **entry)
 {
   struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
-  CURLcode rc = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   DEBUGASSERT(conn && td);
 
   /* wait for the thread to resolve the name */
   if(Curl_thread_join(&td->thread_hnd))
-    rc = getaddrinfo_complete(conn);
+    result = getaddrinfo_complete(conn);
   else
     DEBUGASSERT(0);
 
@@ -480,14 +477,14 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
 
   if(!conn->async.dns)
     /* a name was not resolved, report error */
-    rc = resolver_error(conn);
+    result = resolver_error(conn);
 
   destroy_async_data(&conn->async);
 
   if(!conn->async.dns)
     connclose(conn, "asynch resolve failed");
 
-  return (rc);
+  return result;
 }
 
 /*
@@ -517,9 +514,9 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
     getaddrinfo_complete(conn);
 
     if(!conn->async.dns) {
-      CURLcode rc = resolver_error(conn);
+      CURLcode result = resolver_error(conn);
       destroy_async_data(&conn->async);
-      return rc;
+      return result;
     }
     destroy_async_data(&conn->async);
     *entry = conn->async.dns;
@@ -541,7 +538,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
       td->poll_interval = 250;
 
     td->interval_end = elapsed + td->poll_interval;
-    Curl_expire_latest(conn->data, td->poll_interval);
+    Curl_expire(conn->data, td->poll_interval);
   }
 
   return CURLE_OK;
@@ -633,7 +630,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
   }
 
   if((pf != PF_INET) && !Curl_ipv6works())
-    /* the stack seems to be a non-ipv6 one */
+    /* The stack seems to be a non-IPv6 one */
     pf = PF_INET;
 
 #endif /* CURLRES_IPV6 */
diff --git a/Utilities/cmcurl/lib/base64.c b/Utilities/cmcurl/lib/base64.c
index bd9ba35..6b87eed 100644
--- a/Utilities/cmcurl/lib/base64.c
+++ b/Utilities/cmcurl/lib/base64.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,17 +23,14 @@
 /* Base64 encoding/decoding */
 
 #include "curl_setup.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "urldata.h" /* for the SessionHandle definition */
 #include "warnless.h"
 #include "curl_base64.h"
-#include "curl_memory.h"
 #include "non-ascii.h"
 
-/* include memdebug.h last */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /* ---- Base64 Encoding/Decoding Table --- */
@@ -49,10 +46,10 @@ static size_t decodeQuantum(unsigned char *dest, const char *src)
 {
   size_t padding = 0;
   const char *s, *p;
-  unsigned long i, v, x = 0;
+  unsigned long i, x = 0;
 
   for(i = 0, s = src; i < 4; i++, s++) {
-    v = 0;
+    unsigned long v = 0;
 
     if(*s == '=') {
       x = (x << 6);
@@ -107,7 +104,6 @@ CURLcode Curl_base64_decode(const char *src,
   size_t length = 0;
   size_t padding = 0;
   size_t i;
-  size_t result;
   size_t numQuantums;
   size_t rawlen = 0;
   unsigned char *pos;
@@ -151,9 +147,9 @@ CURLcode Curl_base64_decode(const char *src,
 
   /* Decode the quantums */
   for(i = 0; i < numQuantums; i++) {
-    result = decodeQuantum(pos, src);
+    size_t result = decodeQuantum(pos, src);
     if(!result) {
-      Curl_safefree(newstr);
+      free(newstr);
 
       return CURLE_BAD_CONTENT_ENCODING;
     }
@@ -256,8 +252,7 @@ static CURLcode base64_encode(const char *table64,
   *output = '\0';
   *outptr = base64data; /* return pointer to new data, allocated memory */
 
-  if(convbuf)
-    free(convbuf);
+  free(convbuf);
 
   *outlen = strlen(base64data); /* return the length of the new data */
 
diff --git a/Utilities/cmcurl/lib/bundles.c b/Utilities/cmcurl/lib/bundles.c
deleted file mode 100644
index aadf026..0000000
--- a/Utilities/cmcurl/lib/bundles.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012, Linus Nielsen Feltzing, <linus at haxx.se>
- * Copyright (C) 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#include <curl/curl.h>
-
-#include "urldata.h"
-#include "url.h"
-#include "progress.h"
-#include "multiif.h"
-#include "bundles.h"
-#include "sendf.h"
-#include "rawstr.h"
-
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-static void conn_llist_dtor(void *user, void *element)
-{
-  struct connectdata *data = element;
-  (void)user;
-
-  data->bundle = NULL;
-}
-
-CURLcode Curl_bundle_create(struct SessionHandle *data,
-                            struct connectbundle **cb_ptr)
-{
-  (void)data;
-  DEBUGASSERT(*cb_ptr == NULL);
-  *cb_ptr = malloc(sizeof(struct connectbundle));
-  if(!*cb_ptr)
-    return CURLE_OUT_OF_MEMORY;
-
-  (*cb_ptr)->num_connections = 0;
-  (*cb_ptr)->server_supports_pipelining = FALSE;
-
-  (*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
-  if(!(*cb_ptr)->conn_list) {
-    Curl_safefree(*cb_ptr);
-    return CURLE_OUT_OF_MEMORY;
-  }
-  return CURLE_OK;
-}
-
-void Curl_bundle_destroy(struct connectbundle *cb_ptr)
-{
-  if(!cb_ptr)
-    return;
-
-  if(cb_ptr->conn_list) {
-    Curl_llist_destroy(cb_ptr->conn_list, NULL);
-    cb_ptr->conn_list = NULL;
-  }
-  Curl_safefree(cb_ptr);
-}
-
-/* Add a connection to a bundle */
-CURLcode Curl_bundle_add_conn(struct connectbundle *cb_ptr,
-                              struct connectdata *conn)
-{
-  if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
-    return CURLE_OUT_OF_MEMORY;
-
-  conn->bundle = cb_ptr;
-
-  cb_ptr->num_connections++;
-  return CURLE_OK;
-}
-
-/* Remove a connection from a bundle */
-int Curl_bundle_remove_conn(struct connectbundle *cb_ptr,
-                            struct connectdata *conn)
-{
-  struct curl_llist_element *curr;
-
-  curr = cb_ptr->conn_list->head;
-  while(curr) {
-    if(curr->ptr == conn) {
-      Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
-      cb_ptr->num_connections--;
-      conn->bundle = NULL;
-      return 1; /* we removed a handle */
-    }
-    curr = curr->next;
-  }
-  return 0;
-}
diff --git a/Utilities/cmcurl/lib/bundles.h b/Utilities/cmcurl/lib/bundles.h
deleted file mode 100644
index 3816c40..0000000
--- a/Utilities/cmcurl/lib/bundles.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef HEADER_CURL_BUNDLES_H
-#define HEADER_CURL_BUNDLES_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012, Linus Nielsen Feltzing, <linus at haxx.se>
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-struct connectbundle {
-  bool server_supports_pipelining; /* TRUE if server supports pipelining,
-                                      set after first response */
-  size_t num_connections;       /* Number of connections in the bundle */
-  struct curl_llist *conn_list; /* The connectdata members of the bundle */
-};
-
-CURLcode Curl_bundle_create(struct SessionHandle *data,
-                            struct connectbundle **cb_ptr);
-
-void Curl_bundle_destroy(struct connectbundle *cb_ptr);
-
-CURLcode Curl_bundle_add_conn(struct connectbundle *cb_ptr,
-                              struct connectdata *conn);
-
-int Curl_bundle_remove_conn(struct connectbundle *cb_ptr,
-                            struct connectdata *conn);
-
-
-#endif /* HEADER_CURL_BUNDLES_H */
-
diff --git a/Utilities/cmcurl/lib/conncache.c b/Utilities/cmcurl/lib/conncache.c
index 5bbcf3c..c712ed7 100644
--- a/Utilities/cmcurl/lib/conncache.c
+++ b/Utilities/cmcurl/lib/conncache.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012, Linus Nielsen Feltzing, <linus at haxx.se>
- * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,66 +31,134 @@
 #include "multiif.h"
 #include "sendf.h"
 #include "rawstr.h"
-#include "bundles.h"
 #include "conncache.h"
+#include "curl_printf.h"
 
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
-static void free_bundle_hash_entry(void *freethis)
+static void conn_llist_dtor(void *user, void *element)
 {
-  struct connectbundle *b = (struct connectbundle *) freethis;
+  struct connectdata *data = element;
+  (void)user;
 
-  Curl_bundle_destroy(b);
+  data->bundle = NULL;
 }
 
-struct conncache *Curl_conncache_init(int size)
+static CURLcode bundle_create(struct SessionHandle *data,
+                              struct connectbundle **cb_ptr)
 {
-  struct conncache *connc;
-
-  connc = calloc(1, sizeof(struct conncache));
-  if(!connc)
-    return NULL;
+  (void)data;
+  DEBUGASSERT(*cb_ptr == NULL);
+  *cb_ptr = malloc(sizeof(struct connectbundle));
+  if(!*cb_ptr)
+    return CURLE_OUT_OF_MEMORY;
+
+  (*cb_ptr)->num_connections = 0;
+  (*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
+
+  (*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
+  if(!(*cb_ptr)->conn_list) {
+    Curl_safefree(*cb_ptr);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  return CURLE_OK;
+}
 
-  connc->hash = Curl_hash_alloc(size, Curl_hash_str,
-                                Curl_str_key_compare, free_bundle_hash_entry);
+static void bundle_destroy(struct connectbundle *cb_ptr)
+{
+  if(!cb_ptr)
+    return;
 
-  if(!connc->hash) {
-    free(connc);
-    return NULL;
+  if(cb_ptr->conn_list) {
+    Curl_llist_destroy(cb_ptr->conn_list, NULL);
+    cb_ptr->conn_list = NULL;
   }
+  free(cb_ptr);
+}
+
+/* Add a connection to a bundle */
+static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
+                              struct connectdata *conn)
+{
+  if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
+    return CURLE_OUT_OF_MEMORY;
+
+  conn->bundle = cb_ptr;
 
-  return connc;
+  cb_ptr->num_connections++;
+  return CURLE_OK;
 }
 
-void Curl_conncache_destroy(struct conncache *connc)
+/* Remove a connection from a bundle */
+static int bundle_remove_conn(struct connectbundle *cb_ptr,
+                              struct connectdata *conn)
 {
-  if(connc) {
-    Curl_hash_destroy(connc->hash);
-    connc->hash = NULL;
-    free(connc);
+  struct curl_llist_element *curr;
+
+  curr = cb_ptr->conn_list->head;
+  while(curr) {
+    if(curr->ptr == conn) {
+      Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
+      cb_ptr->num_connections--;
+      conn->bundle = NULL;
+      return 1; /* we removed a handle */
+    }
+    curr = curr->next;
   }
+  return 0;
 }
 
-struct connectbundle *Curl_conncache_find_bundle(struct conncache *connc,
-                                                 char *hostname)
+static void free_bundle_hash_entry(void *freethis)
 {
-  struct connectbundle *bundle = NULL;
+  struct connectbundle *b = (struct connectbundle *) freethis;
+
+  bundle_destroy(b);
+}
 
+int Curl_conncache_init(struct conncache *connc, int size)
+{
+  return Curl_hash_init(&connc->hash, size, Curl_hash_str,
+                        Curl_str_key_compare, free_bundle_hash_entry);
+}
+
+void Curl_conncache_destroy(struct conncache *connc)
+{
   if(connc)
-    bundle = Curl_hash_pick(connc->hash, hostname, strlen(hostname)+1);
+    Curl_hash_destroy(&connc->hash);
+}
+
+/* returns an allocated key to find a bundle for this connection */
+static char *hashkey(struct connectdata *conn)
+{
+  return aprintf("%s:%d",
+                 conn->bits.proxy?conn->proxy.name:conn->host.name,
+                 conn->localport);
+}
+
+/* Look up the bundle with all the connections to the same host this
+   connectdata struct is setup to use. */
+struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
+                                                 struct conncache *connc)
+{
+  struct connectbundle *bundle = NULL;
+  if(connc) {
+    char *key = hashkey(conn);
+    if(key) {
+      bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
+      free(key);
+    }
+  }
 
   return bundle;
 }
 
 static bool conncache_add_bundle(struct conncache *connc,
-                                 char *hostname,
+                                 char *key,
                                  struct connectbundle *bundle)
 {
-  void *p;
-
-  p = Curl_hash_add(connc->hash, hostname, strlen(hostname)+1, bundle);
+  void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle);
 
   return p?TRUE:FALSE;
 }
@@ -104,14 +172,14 @@ static void conncache_remove_bundle(struct conncache *connc,
   if(!connc)
     return;
 
-  Curl_hash_start_iterate(connc->hash, &iter);
+  Curl_hash_start_iterate(&connc->hash, &iter);
 
   he = Curl_hash_next_element(&iter);
   while(he) {
     if(he->ptr == bundle) {
       /* The bundle is destroyed by the hash destructor function,
          free_bundle_hash_entry() */
-      Curl_hash_delete(connc->hash, he->key, he->key_len);
+      Curl_hash_delete(&connc->hash, he->key, he->key_len);
       return;
     }
 
@@ -127,23 +195,32 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
   struct connectbundle *new_bundle = NULL;
   struct SessionHandle *data = conn->data;
 
-  bundle = Curl_conncache_find_bundle(data->state.conn_cache,
-                                      conn->host.name);
+  bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
   if(!bundle) {
-    result = Curl_bundle_create(data, &new_bundle);
-    if(result != CURLE_OK)
+    char *key;
+    int rc;
+
+    result = bundle_create(data, &new_bundle);
+    if(result)
       return result;
 
-    if(!conncache_add_bundle(data->state.conn_cache,
-                             conn->host.name, new_bundle)) {
-      Curl_bundle_destroy(new_bundle);
+    key = hashkey(conn);
+    if(!key) {
+      bundle_destroy(new_bundle);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
+    free(key);
+    if(!rc) {
+      bundle_destroy(new_bundle);
       return CURLE_OUT_OF_MEMORY;
     }
     bundle = new_bundle;
   }
 
-  result = Curl_bundle_add_conn(bundle, conn);
-  if(result != CURLE_OK) {
+  result = bundle_add_conn(bundle, conn);
+  if(result) {
     if(new_bundle)
       conncache_remove_bundle(data->state.conn_cache, new_bundle);
     return result;
@@ -152,6 +229,10 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
   conn->connection_id = connc->next_connection_id++;
   connc->num_connections++;
 
+  DEBUGF(infof(conn->data, "Added connection %ld. "
+               "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n",
+               conn->connection_id, (curl_off_t) connc->num_connections));
+
   return CURLE_OK;
 }
 
@@ -163,7 +244,7 @@ void Curl_conncache_remove_conn(struct conncache *connc,
   /* The bundle pointer can be NULL, since this function can be called
      due to a failed connection attempt, before being added to a bundle */
   if(bundle) {
-    Curl_bundle_remove_conn(bundle, conn);
+    bundle_remove_conn(bundle, conn);
     if(bundle->num_connections == 0) {
       conncache_remove_bundle(connc, bundle);
     }
@@ -171,8 +252,9 @@ void Curl_conncache_remove_conn(struct conncache *connc,
     if(connc) {
       connc->num_connections--;
 
-      DEBUGF(infof(conn->data, "The cache now contains %d members\n",
-                   connc->num_connections));
+      DEBUGF(infof(conn->data, "The cache now contains %"
+                   CURL_FORMAT_CURL_OFF_TU " members\n",
+                   (curl_off_t) connc->num_connections));
     }
   }
 }
@@ -194,12 +276,11 @@ void Curl_conncache_foreach(struct conncache *connc,
   if(!connc)
     return;
 
-  Curl_hash_start_iterate(connc->hash, &iter);
+  Curl_hash_start_iterate(&connc->hash, &iter);
 
   he = Curl_hash_next_element(&iter);
   while(he) {
     struct connectbundle *bundle;
-    struct connectdata *conn;
 
     bundle = he->ptr;
     he = Curl_hash_next_element(&iter);
@@ -208,7 +289,7 @@ void Curl_conncache_foreach(struct conncache *connc,
     while(curr) {
       /* Yes, we need to update curr before calling func(), because func()
          might decide to remove the connection */
-      conn = curr->ptr;
+      struct connectdata *conn = curr->ptr;
       curr = curr->next;
 
       if(1 == func(conn, param))
@@ -223,14 +304,14 @@ struct connectdata *
 Curl_conncache_find_first_connection(struct conncache *connc)
 {
   struct curl_hash_iterator iter;
-  struct curl_llist_element *curr;
   struct curl_hash_element *he;
   struct connectbundle *bundle;
 
-  Curl_hash_start_iterate(connc->hash, &iter);
+  Curl_hash_start_iterate(&connc->hash, &iter);
 
   he = Curl_hash_next_element(&iter);
   while(he) {
+    struct curl_llist_element *curr;
     bundle = he->ptr;
 
     curr = bundle->conn_list->head;
diff --git a/Utilities/cmcurl/lib/conncache.h b/Utilities/cmcurl/lib/conncache.h
index d793f24..59181bf 100644
--- a/Utilities/cmcurl/lib/conncache.h
+++ b/Utilities/cmcurl/lib/conncache.h
@@ -7,6 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
+ * Copyright (C) 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus at haxx.se>
  *
  * This software is licensed as described in the file COPYING, which
@@ -23,18 +24,30 @@
  ***************************************************************************/
 
 struct conncache {
-  struct curl_hash *hash;
+  struct curl_hash hash;
   size_t num_connections;
   long next_connection_id;
   struct timeval last_cleanup;
 };
 
-struct conncache *Curl_conncache_init(int size);
+#define BUNDLE_NO_MULTIUSE -1
+#define BUNDLE_UNKNOWN     0  /* initial value */
+#define BUNDLE_PIPELINING  1
+#define BUNDLE_MULTIPLEX   2
+
+struct connectbundle {
+  int multiuse;                 /* supports multi-use */
+  size_t num_connections;       /* Number of connections in the bundle */
+  struct curl_llist *conn_list; /* The connectdata members of the bundle */
+};
+
+int Curl_conncache_init(struct conncache *, int size);
 
 void Curl_conncache_destroy(struct conncache *connc);
 
-struct connectbundle *Curl_conncache_find_bundle(struct conncache *connc,
-                                                 char *hostname);
+/* return the correct bundle, to a host or a proxy */
+struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
+                                                 struct conncache *connc);
 
 CURLcode Curl_conncache_add_conn(struct conncache *connc,
                                  struct connectdata *conn);
diff --git a/Utilities/cmcurl/lib/connect.c b/Utilities/cmcurl/lib/connect.c
index fb315fc..18ac32c 100644
--- a/Utilities/cmcurl/lib/connect.c
+++ b/Utilities/cmcurl/lib/connect.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -56,15 +56,12 @@
 #include <inet.h>
 #endif
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "urldata.h"
 #include "sendf.h"
 #include "if2ip.h"
 #include "strerror.h"
 #include "connect.h"
-#include "curl_memory.h"
 #include "select.h"
 #include "url.h" /* for Curl_safefree() */
 #include "multiif.h"
@@ -77,7 +74,8 @@
 #include "conncache.h"
 #include "multihandle.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #ifdef __SYMBIAN32__
@@ -238,7 +236,7 @@ long Curl_timeleft(struct SessionHandle *data,
 }
 
 static CURLcode bindlocal(struct connectdata *conn,
-                          curl_socket_t sockfd, int af)
+                          curl_socket_t sockfd, int af, unsigned int scope)
 {
   struct SessionHandle *data = conn->data;
 
@@ -257,12 +255,6 @@ static CURLcode bindlocal(struct connectdata *conn,
   int portnum = data->set.localportrange;
   const char *dev = data->set.str[STRING_DEVICE];
   int error;
-  char myhost[256] = "";
-  int done = 0; /* -1 for error, 1 for address found */
-  bool is_interface = FALSE;
-  bool is_host = FALSE;
-  static const char *if_prefix = "if!";
-  static const char *host_prefix = "host!";
 
   /*************************************************************
    * Select device to bind socket to
@@ -274,6 +266,13 @@ static CURLcode bindlocal(struct connectdata *conn,
   memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
 
   if(dev && (strlen(dev)<255) ) {
+    char myhost[256] = "";
+    int done = 0; /* -1 for error, 1 for address found */
+    bool is_interface = FALSE;
+    bool is_host = FALSE;
+    static const char *if_prefix = "if!";
+    static const char *host_prefix = "host!";
+
     if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) {
       dev += strlen(if_prefix);
       is_interface = TRUE;
@@ -285,7 +284,8 @@ static CURLcode bindlocal(struct connectdata *conn,
 
     /* interface */
     if(!is_host) {
-      switch(Curl_if2ip(af, conn->scope, dev, myhost, sizeof(myhost))) {
+      switch(Curl_if2ip(af, scope, conn->scope_id, dev,
+                        myhost, sizeof(myhost))) {
         case IF2IP_NOT_FOUND:
           if(is_interface) {
             /* Do not fall back to treating it as a host name */
@@ -374,7 +374,7 @@ static CURLcode bindlocal(struct connectdata *conn,
 
     if(done > 0) {
 #ifdef ENABLE_IPV6
-      /* ipv6 address */
+      /* IPv6 address */
       if(af == AF_INET6) {
 #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
         char *scope_ptr = strchr(myhost, '%');
@@ -397,7 +397,7 @@ static CURLcode bindlocal(struct connectdata *conn,
       }
       else
 #endif
-      /* ipv4 address */
+      /* IPv4 address */
       if((af == AF_INET) &&
          (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) {
         si4->sin_family = AF_INET;
@@ -540,7 +540,8 @@ static CURLcode trynextip(struct connectdata *conn,
                           int sockindex,
                           int tempindex)
 {
-  CURLcode rc = CURLE_COULDNT_CONNECT;
+  const int other = tempindex ^ 1;
+  CURLcode result = CURLE_COULDNT_CONNECT;
 
   /* First clean up after the failed socket.
      Don't close it yet to ensure that the next IP's socket gets a different
@@ -558,27 +559,29 @@ static CURLcode trynextip(struct connectdata *conn,
       family = conn->tempaddr[tempindex]->ai_family;
       ai = conn->tempaddr[tempindex]->ai_next;
     }
+#ifdef ENABLE_IPV6
     else if(conn->tempaddr[0]) {
       /* happy eyeballs - try the other protocol family */
       int firstfamily = conn->tempaddr[0]->ai_family;
-#ifdef ENABLE_IPV6
       family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
-#else
-      family = firstfamily;
-#endif
       ai = conn->tempaddr[0]->ai_next;
     }
+#endif
 
     while(ai) {
-      while(ai && ai->ai_family != family)
-        ai = ai->ai_next;
+      if(conn->tempaddr[other]) {
+        /* we can safely skip addresses of the other protocol family */
+        while(ai && ai->ai_family != family)
+          ai = ai->ai_next;
+      }
 
       if(ai) {
-        rc = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
-        if(rc == CURLE_COULDNT_CONNECT) {
+        result = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
+        if(result == CURLE_COULDNT_CONNECT) {
           ai = ai->ai_next;
           continue;
         }
+
         conn->tempaddr[tempindex] = ai;
       }
       break;
@@ -588,7 +591,7 @@ static CURLcode trynextip(struct connectdata *conn,
   if(fd_to_close != CURL_SOCKET_BAD)
     Curl_closesocket(conn, fd_to_close);
 
-  return rc;
+  return result;
 }
 
 /* Copies connection info into the session handle to make it available
@@ -656,7 +659,6 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr,
    connection */
 void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
 {
-  int error;
   curl_socklen_t len;
   struct Curl_sockaddr_storage ssrem;
   struct Curl_sockaddr_storage ssloc;
@@ -667,6 +669,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
     return;
 
   if(!conn->bits.reuse) {
+    int error;
 
     len = sizeof(struct Curl_sockaddr_storage);
     if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
@@ -677,6 +680,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
     }
 
     len = sizeof(struct Curl_sockaddr_storage);
+    memset(&ssloc, 0, sizeof(ssloc));
     if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
       error = SOCKERRNO;
       failf(data, "getsockname() failed with errno %d: %s",
@@ -716,11 +720,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
                            bool *connected)
 {
   struct SessionHandle *data = conn->data;
-  CURLcode code = CURLE_OK;
+  CURLcode result = CURLE_OK;
   long allow;
   int error = 0;
   struct timeval now;
-  int result;
+  int rc;
   int i;
 
   DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
@@ -745,6 +749,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
   }
 
   for(i=0; i<2; i++) {
+    const int other = i ^ 1;
     if(conn->tempsock[i] == CURL_SOCKET_BAD)
       continue;
 
@@ -756,9 +761,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
 #endif
 
     /* check socket for connect */
-    result = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
+    rc = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
 
-    if(result == 0) { /* no connection yet */
+    if(rc == 0) { /* no connection yet */
       if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
         infof(data, "After %ldms connect time, move on!\n",
               conn->timeoutms_per_addr);
@@ -771,10 +776,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
         trynextip(conn, sockindex, 1);
       }
     }
-    else if(result == CURL_CSELECT_OUT) {
+    else if(rc == CURL_CSELECT_OUT) {
       if(verifyconnect(conn->tempsock[i], &error)) {
         /* we are connected with TCP, awesome! */
-        int other = i ^ 1;
 
         /* use this socket from now on */
         conn->sock[sockindex] = conn->tempsock[i];
@@ -788,9 +792,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
         }
 
         /* see if we need to do any proxy magic first once we connected */
-        code = Curl_connected_proxy(conn, sockindex);
-        if(code)
-          return code;
+        result = Curl_connected_proxy(conn, sockindex);
+        if(result)
+          return result;
 
         conn->bits.tcpconnect[sockindex] = TRUE;
 
@@ -805,7 +809,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
       else
         infof(data, "Connection failed\n");
     }
-    else if(result & CURL_CSELECT_ERR)
+    else if(rc & CURL_CSELECT_ERR)
       (void)verifyconnect(conn->tempsock[i], &error);
 
     /*
@@ -813,10 +817,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
      * address" for the given host. But first remember the latest error.
      */
     if(error) {
-      char ipaddress[MAX_IPADR_LEN];
       data->state.os_errno = error;
       SET_SOCKERRNO(error);
       if(conn->tempaddr[i]) {
+        CURLcode status;
+        char ipaddress[MAX_IPADR_LEN];
         Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
         infof(data, "connect to %s port %ld failed: %s\n",
               ipaddress, conn->port, Curl_strerror(conn, error));
@@ -824,21 +829,24 @@ CURLcode Curl_is_connected(struct connectdata *conn,
         conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
                                    allow : allow / 2;
 
-        code = trynextip(conn, sockindex, i);
+        status = trynextip(conn, sockindex, i);
+        if(status != CURLE_COULDNT_CONNECT
+            || conn->tempsock[other] == CURL_SOCKET_BAD)
+          /* the last attempt failed and no other sockets remain open */
+          result = status;
       }
     }
   }
 
-  if(code) {
+  if(result) {
     /* no more addresses to try */
 
     /* if the first address family runs out of addresses to try before
        the happy eyeball timeout, go ahead and try the next family now */
     if(conn->tempaddr[1] == NULL) {
-      int rc;
-      rc = trynextip(conn, sockindex, 1);
-      if(rc == CURLE_OK)
-        return CURLE_OK;
+      result = trynextip(conn, sockindex, 1);
+      if(!result)
+        return result;
     }
 
     failf(data, "Failed to connect to %s port %ld: %s",
@@ -846,7 +854,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
           conn->port, Curl_strerror(conn, error));
   }
 
-  return code;
+  return result;
 }
 
 static void tcpnodelay(struct connectdata *conn,
@@ -875,7 +883,7 @@ static void tcpnodelay(struct connectdata *conn,
     infof(data, "Could not set TCP_NODELAY: %s\n",
           Curl_strerror(conn, SOCKERRNO));
   else
-    infof(data,"TCP_NODELAY set\n");
+    infof(data, "TCP_NODELAY set\n");
 #else
   (void)conn;
   (void)sockfd;
@@ -941,16 +949,21 @@ void Curl_sndbufset(curl_socket_t sockfd)
         detectOsState = DETECT_OS_VISTA_OR_LATER;
     }
 #else
-    ULONGLONG majorVersionMask;
+    ULONGLONG cm;
     OSVERSIONINFOEX osver;
 
     memset(&osver, 0, sizeof(osver));
     osver.dwOSVersionInfoSize = sizeof(osver);
     osver.dwMajorVersion = majorVersion;
-    majorVersionMask = VerSetConditionMask(0, VER_MAJORVERSION,
-                                           VER_GREATER_EQUAL);
 
-    if(VerifyVersionInfo(&osver, VER_MAJORVERSION, majorVersionMask))
+    cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+
+    if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
+                                  VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
+                         cm))
       detectOsState = DETECT_OS_VISTA_OR_LATER;
     else
       detectOsState = DETECT_OS_PREVISTA;
@@ -977,10 +990,9 @@ void Curl_sndbufset(curl_socket_t sockfd)
  * singleipconnect() connects to the given IP only, and it may return without
  * having connected.
  */
-static CURLcode
-singleipconnect(struct connectdata *conn,
-                const Curl_addrinfo *ai,
-                curl_socket_t *sockp)
+static CURLcode singleipconnect(struct connectdata *conn,
+                                const Curl_addrinfo *ai,
+                                curl_socket_t *sockp)
 {
   struct Curl_sockaddr_ex addr;
   int rc;
@@ -988,14 +1000,15 @@ singleipconnect(struct connectdata *conn,
   bool isconnected = FALSE;
   struct SessionHandle *data = conn->data;
   curl_socket_t sockfd;
-  CURLcode res = CURLE_OK;
+  CURLcode result;
   char ipaddress[MAX_IPADR_LEN];
   long port;
+  bool is_tcp;
 
   *sockp = CURL_SOCKET_BAD;
 
-  res = Curl_socket(conn, ai, &addr, &sockfd);
-  if(res)
+  result = Curl_socket(conn, ai, &addr, &sockfd);
+  if(result)
     /* Failed to create the socket, but still return OK since we signal the
        lack of socket as well. This allows the parent function to keep looping
        over alternative addresses/socket families etc. */
@@ -1013,14 +1026,20 @@ singleipconnect(struct connectdata *conn,
   }
   infof(data, "  Trying %s...\n", ipaddress);
 
-  if(data->set.tcp_nodelay)
+#ifdef ENABLE_IPV6
+  is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
+    addr.socktype == SOCK_STREAM;
+#else
+  is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM;
+#endif
+  if(is_tcp && data->set.tcp_nodelay)
     tcpnodelay(conn, sockfd);
 
   nosigpipe(conn, sockfd);
 
   Curl_sndbufset(sockfd);
 
-  if(data->set.tcp_keepalive)
+  if(is_tcp && data->set.tcp_keepalive)
     tcpkeepalive(data, sockfd);
 
   if(data->set.fsockopt) {
@@ -1038,19 +1057,26 @@ singleipconnect(struct connectdata *conn,
   }
 
   /* possibly bind the local end to an IP, interface or port */
-  res = bindlocal(conn, sockfd, addr.family);
-  if(res) {
-    Curl_closesocket(conn, sockfd); /* close socket and bail out */
-    if(res == CURLE_UNSUPPORTED_PROTOCOL) {
-      /* The address family is not supported on this interface.
-         We can continue trying addresses */
-      return CURLE_OK;
+  if(addr.family == AF_INET
+#ifdef ENABLE_IPV6
+     || addr.family == AF_INET6
+#endif
+    ) {
+    result = bindlocal(conn, sockfd, addr.family,
+                       Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr));
+    if(result) {
+      Curl_closesocket(conn, sockfd); /* close socket and bail out */
+      if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+        /* The address family is not supported on this interface.
+           We can continue trying addresses */
+        return CURLE_COULDNT_CONNECT;
+      }
+      return result;
     }
-    return res;
   }
 
   /* set socket non-blocking */
-  curlx_nonblock(sockfd, TRUE);
+  (void)curlx_nonblock(sockfd, TRUE);
 
   conn->connecttime = Curl_tvnow();
   if(conn->num_addr > 1)
@@ -1084,25 +1110,25 @@ singleipconnect(struct connectdata *conn,
     case EAGAIN:
 #endif
 #endif
-      res = CURLE_OK;
+      result = CURLE_OK;
       break;
 
     default:
       /* unknown error, fallthrough and try another address! */
       infof(data, "Immediate connect fail for %s: %s\n",
-            ipaddress, Curl_strerror(conn,error));
+            ipaddress, Curl_strerror(conn, error));
       data->state.os_errno = error;
 
       /* connect failed */
       Curl_closesocket(conn, sockfd);
-      res = CURLE_COULDNT_CONNECT;
+      result = CURLE_COULDNT_CONNECT;
     }
   }
 
-  if(!res)
+  if(!result)
     *sockp = sockfd;
 
-  return res;
+  return result;
 }
 
 /*
@@ -1116,7 +1142,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
 {
   struct SessionHandle *data = conn->data;
   struct timeval before = Curl_tvnow();
-  CURLcode res = CURLE_COULDNT_CONNECT;
+  CURLcode result = CURLE_COULDNT_CONNECT;
 
   long timeout_ms = Curl_timeleft(data, &before, TRUE);
 
@@ -1139,14 +1165,17 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
 
   /* start connecting to first IP */
   while(conn->tempaddr[0]) {
-    res = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
-    if(res == CURLE_OK)
-        break;
+    result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
+    if(!result)
+      break;
     conn->tempaddr[0] = conn->tempaddr[0]->ai_next;
   }
 
-  if(conn->tempsock[0] == CURL_SOCKET_BAD)
-    return res;
+  if(conn->tempsock[0] == CURL_SOCKET_BAD) {
+    if(!result)
+      result = CURLE_COULDNT_CONNECT;
+    return result;
+  }
 
   data->info.numconnects++; /* to track the number of connections made */
 
@@ -1181,15 +1210,20 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
 
   DEBUGASSERT(data);
 
-  /* this only works for an easy handle that has been used for
-     curl_easy_perform()! */
-  if(data->state.lastconnect && data->multi_easy) {
+  /* this works for an easy handle:
+   * - that has been used for curl_easy_perform()
+   * - that is associated with a multi handle, and whose connection
+   *   was detached with CURLOPT_CONNECT_ONLY
+   */
+  if(data->state.lastconnect && (data->multi_easy || data->multi)) {
     struct connectdata *c = data->state.lastconnect;
     struct connfind find;
     find.tofind = data->state.lastconnect;
     find.found = FALSE;
 
-    Curl_conncache_foreach(data->multi_easy->conn_cache, &find, conn_is_conn);
+    Curl_conncache_foreach(data->multi_easy?
+                           &data->multi_easy->conn_cache:
+                           &data->multi->conn_cache, &find, conn_is_conn);
 
     if(!find.found) {
       data->state.lastconnect = NULL;
@@ -1240,15 +1274,18 @@ int Curl_closesocket(struct connectdata *conn,
          accept, then we MUST NOT call the callback but clear the accepted
          status */
       conn->sock_accepted[SECONDARYSOCKET] = FALSE;
-    else
+    else {
+      Curl_multi_closed(conn, sock);
       return conn->fclosesocket(conn->closesocket_client, sock);
+    }
   }
-  sclose(sock);
 
   if(conn)
     /* tell the multi-socket code about this */
     Curl_multi_closed(conn, sock);
 
+  sclose(sock);
+
   return 0;
 }
 
@@ -1312,9 +1349,9 @@ CURLcode Curl_socket(struct connectdata *conn,
     return CURLE_COULDNT_CONNECT;
 
 #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
-  if(conn->scope && (addr->family == AF_INET6)) {
+  if(conn->scope_id && (addr->family == AF_INET6)) {
     struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
-    sa6->sin6_scope_id = conn->scope;
+    sa6->sin6_scope_id = conn->scope_id;
   }
 #endif
 
@@ -1325,16 +1362,22 @@ CURLcode Curl_socket(struct connectdata *conn,
 #ifdef CURLDEBUG
 /*
  * Curl_conncontrol() is used to set the conn->bits.close bit on or off. It
- * MUST be called with the connclose() or connclose() macros with a stated
+ * MUST be called with the connclose() or connkeep() macros with a stated
  * reason. The reason is only shown in debug builds but helps to figure out
  * decision paths when connections are or aren't re-used as expected.
  */
 void Curl_conncontrol(struct connectdata *conn, bool closeit,
                       const char *reason)
 {
-  infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
-        reason);
-  conn->bits.close = closeit; /* the only place in the source code that should
-                                 assign this bit */
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) reason;
+#endif
+  if(closeit != conn->bits.close) {
+    infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
+          reason);
+
+    conn->bits.close = closeit; /* the only place in the source code that
+                                   should assign this bit */
+  }
 }
 #endif
diff --git a/Utilities/cmcurl/lib/connect.h b/Utilities/cmcurl/lib/connect.h
index 7bc391b..91646c7 100644
--- a/Utilities/cmcurl/lib/connect.h
+++ b/Utilities/cmcurl/lib/connect.h
@@ -41,7 +41,7 @@ long Curl_timeleft(struct SessionHandle *data,
 
 #define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
 #define HAPPY_EYEBALLS_TIMEOUT     200 /* milliseconds to wait between
-                                          ipv4/ipv6 connection attempts */
+                                          IPv4/IPv6 connection attempts */
 
 /*
  * Used to extract socket and connectdata struct for the most recent
diff --git a/Utilities/cmcurl/lib/cookie.c b/Utilities/cmcurl/lib/cookie.c
index 375485f..22730cf 100644
--- a/Utilities/cmcurl/lib/cookie.c
+++ b/Utilities/cmcurl/lib/cookie.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,14 +26,17 @@
 RECEIVING COOKIE INFORMATION
 ============================
 
-struct CookieInfo *cookie_init(char *file);
+struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
+                    const char *file, struct CookieInfo *inc, bool newsession);
 
         Inits a cookie struct to store data in a local file. This is always
         called before any cookies are set.
 
-int cookies_set(struct CookieInfo *cookie, char *cookie_line);
+struct Cookie *Curl_cookie_add(struct SessionHandle *data,
+                 struct CookieInfo *c, bool httpheader, char *lineptr,
+                 const char *domain, const char *path);
 
-        The 'cookie_line' parameter is a full "Set-cookie:" line as
+        The 'lineptr' parameter is a full "Set-cookie:" line as
         received from a server.
 
         The function need to replace previously stored lines that this new
@@ -47,8 +50,8 @@ int cookies_set(struct CookieInfo *cookie, char *cookie_line);
 SENDING COOKIE INFORMATION
 ==========================
 
-struct Cookies *cookie_getlist(struct CookieInfo *cookie,
-                               char *host, char *path, bool secure);
+struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie,
+                                    char *host, char *path, bool secure);
 
         For a given host and path, return a linked list of cookies that
         the client should send to the server if used now. The secure
@@ -81,44 +84,33 @@ Example set of cookies:
 
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
 
-#define _MPRINTF_REPLACE
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "urldata.h"
 #include "cookie.h"
 #include "strequal.h"
 #include "strtok.h"
 #include "sendf.h"
 #include "slist.h"
-#include "curl_memory.h"
 #include "share.h"
 #include "strtoofft.h"
 #include "rawstr.h"
 #include "curl_memrchr.h"
 #include "inet_pton.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 static void freecookie(struct Cookie *co)
 {
-  if(co->expirestr)
-    free(co->expirestr);
-  if(co->domain)
-    free(co->domain);
-  if(co->path)
-    free(co->path);
-  if(co->spath)
-    free(co->spath);
-  if(co->name)
-    free(co->name);
-  if(co->value)
-    free(co->value);
-  if(co->maxage)
-    free(co->maxage);
-  if(co->version)
-    free(co->version);
-
+  free(co->expirestr);
+  free(co->domain);
+  free(co->path);
+  free(co->spath);
+  free(co->name);
+  free(co->value);
+  free(co->maxage);
+  free(co->version);
   free(co);
 }
 
@@ -233,11 +225,14 @@ static char *sanitize_cookie_path(const char *cookie_path)
     return NULL;
 
   /* some stupid site sends path attribute with '"'. */
+  len = strlen(new_path);
   if(new_path[0] == '\"') {
-    memmove((void *)new_path, (const void *)(new_path + 1), strlen(new_path));
+    memmove((void *)new_path, (const void *)(new_path + 1), len);
+    len--;
   }
-  if(new_path[strlen(new_path) - 1] == '\"') {
-    new_path[strlen(new_path) - 1] = 0x0;
+  if(len && (new_path[len - 1] == '\"')) {
+    new_path[len - 1] = 0x0;
+    len--;
   }
 
   /* RFC6265 5.2.4 The Path Attribute */
@@ -249,8 +244,7 @@ static char *sanitize_cookie_path(const char *cookie_path)
   }
 
   /* convert /hoge/ to /hoge */
-  len = strlen(new_path);
-  if(1 < len && new_path[len - 1] == '/') {
+  if(len && new_path[len - 1] == '/') {
     new_path[len - 1] = 0x0;
   }
 
@@ -259,6 +253,8 @@ static char *sanitize_cookie_path(const char *cookie_path)
 
 /*
  * Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
+ *
+ * NOTE: OOM or cookie parsing failures are ignored.
  */
 void Curl_cookie_loadfiles(struct SessionHandle *data)
 {
@@ -266,10 +262,17 @@ void Curl_cookie_loadfiles(struct SessionHandle *data)
   if(list) {
     Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
     while(list) {
-      data->cookies = Curl_cookie_init(data,
-                                       list->data,
-                                       data->cookies,
-                                       data->set.cookiesession);
+      struct CookieInfo *newcookies = Curl_cookie_init(data,
+                                        list->data,
+                                        data->cookies,
+                                        data->set.cookiesession);
+      if(!newcookies)
+        /* Failure may be due to OOM or a bad cookie; both are ignored
+         * but only the first should be
+         */
+        infof(data, "ignoring failed cookie_init for %s\n", list->data);
+      else
+        data->cookies = newcookies;
       list = list->next;
     }
     curl_slist_free_all(data->change.cookielist); /* clean up list */
@@ -286,8 +289,7 @@ void Curl_cookie_loadfiles(struct SessionHandle *data)
  */
 static void strstore(char **str, const char *newstr)
 {
-  if(*str)
-    free(*str);
+  free(*str);
   *str = strdup(newstr);
 }
 
@@ -351,6 +353,8 @@ static bool isip(const char *domain)
  * Be aware that sometimes we get an IP-only host name, and that might also be
  * a numerical IPv6 address.
  *
+ * Returns NULL on out of memory or invalid cookie. This is suboptimal,
+ * as they should be treated separately.
  ***************************************************************************/
 
 struct Cookie *
@@ -405,7 +409,7 @@ Curl_cookie_add(struct SessionHandle *data,
     do {
       /* we have a <what>=<this> pair or a stand-alone word here */
       name[0]=what[0]=0; /* init the buffers */
-      if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n =]=%"
+      if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n =] =%"
                      MAX_COOKIE_LINE_TXT "[^;\r\n]",
                      name, what)) {
         /* Use strstore() below to properly deal with received cookie
@@ -820,21 +824,13 @@ Curl_cookie_add(struct SessionHandle *data,
 
         /* then free all the old pointers */
         free(clist->name);
-        if(clist->value)
-          free(clist->value);
-        if(clist->domain)
-          free(clist->domain);
-        if(clist->path)
-          free(clist->path);
-        if(clist->spath)
-          free(clist->spath);
-        if(clist->expirestr)
-          free(clist->expirestr);
-
-        if(clist->version)
-          free(clist->version);
-        if(clist->maxage)
-          free(clist->maxage);
+        free(clist->value);
+        free(clist->domain);
+        free(clist->path);
+        free(clist->spath);
+        free(clist->expirestr);
+        free(clist->version);
+        free(clist->maxage);
 
         *clist = *co;  /* then store all the new data */
 
@@ -882,6 +878,7 @@ Curl_cookie_add(struct SessionHandle *data,
  *
  * If 'newsession' is TRUE, discard all "session cookies" on read from file.
  *
+ * Returns NULL on out of memory. Invalid cookies are ignored.
  ****************************************************************************/
 struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
                                     const char *file,
@@ -889,8 +886,9 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
                                     bool newsession)
 {
   struct CookieInfo *c;
-  FILE *fp;
+  FILE *fp = NULL;
   bool fromfile=TRUE;
+  char *line = NULL;
 
   if(NULL == inc) {
     /* we didn't get a struct, create one */
@@ -898,6 +896,8 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
     if(!c)
       return NULL; /* failed to get memory */
     c->filename = strdup(file?file:"none"); /* copy the name just in case */
+    if(!c->filename)
+      goto fail; /* failed to get memory */
   }
   else {
     /* we got an already existing one, use that */
@@ -914,7 +914,7 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
     fp = NULL;
   }
   else
-    fp = file?fopen(file, "r"):NULL;
+    fp = file?fopen(file, FOPEN_READTEXT):NULL;
 
   c->newsession = newsession; /* new session? */
 
@@ -922,25 +922,26 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
     char *lineptr;
     bool headerline;
 
-    char *line = malloc(MAX_COOKIE_LINE);
-    if(line) {
-      while(fgets(line, MAX_COOKIE_LINE, fp)) {
-        if(checkprefix("Set-Cookie:", line)) {
-          /* This is a cookie line, get it! */
-          lineptr=&line[11];
-          headerline=TRUE;
-        }
-        else {
-          lineptr=line;
-          headerline=FALSE;
-        }
-        while(*lineptr && ISBLANK(*lineptr))
-          lineptr++;
-
-        Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
+    line = malloc(MAX_COOKIE_LINE);
+    if(!line)
+      goto fail;
+    while(fgets(line, MAX_COOKIE_LINE, fp)) {
+      if(checkprefix("Set-Cookie:", line)) {
+        /* This is a cookie line, get it! */
+        lineptr=&line[11];
+        headerline=TRUE;
+      }
+      else {
+        lineptr=line;
+        headerline=FALSE;
       }
-      free(line); /* free the line buffer */
+      while(*lineptr && ISBLANK(*lineptr))
+        lineptr++;
+
+      Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
     }
+    free(line); /* free the line buffer */
+
     if(fromfile)
       fclose(fp);
   }
@@ -948,6 +949,16 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
   c->running = TRUE;          /* now, we're running */
 
   return c;
+
+fail:
+  free(line);
+  if(!inc)
+    /* Only clean up if we allocated it here, as the original could still be in
+     * use by a share handle */
+    Curl_cookie_cleanup(c);
+  if(fromfile && fp)
+    fclose(fp);
+  return NULL; /* out of memory */
 }
 
 /* sort this so that the longest path gets before the shorter path */
@@ -1127,16 +1138,14 @@ void Curl_cookie_clearall(struct CookieInfo *cookies)
 void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
 {
   struct Cookie *next;
-  if(co) {
-    while(co) {
-      next = co->next;
-      if(cookiestoo)
-        freecookie(co);
-      else
-        free(co); /* we only free the struct since the "members" are all just
-                     pointed out in the main cookie list! */
-      co = next;
-    }
+  while(co) {
+    next = co->next;
+    if(cookiestoo)
+      freecookie(co);
+    else
+      free(co); /* we only free the struct since the "members" are all just
+                   pointed out in the main cookie list! */
+    co = next;
   }
 }
 
@@ -1183,23 +1192,14 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies)
  *
  * Curl_cookie_cleanup()
  *
- * Free a "cookie object" previous created with cookie_init().
+ * Free a "cookie object" previous created with Curl_cookie_init().
  *
  ****************************************************************************/
 void Curl_cookie_cleanup(struct CookieInfo *c)
 {
-  struct Cookie *co;
-  struct Cookie *next;
   if(c) {
-    if(c->filename)
-      free(c->filename);
-    co = c->cookies;
-
-    while(co) {
-      next = co->next;
-      freecookie(co);
-      co = next;
-    }
+    free(c->filename);
+    Curl_cookie_freelist(c->cookies, TRUE);
     free(c); /* free the base struct as well */
   }
 }
@@ -1262,7 +1262,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
     use_stdout=TRUE;
   }
   else {
-    out = fopen(dumphere, "w");
+    out = fopen(dumphere, FOPEN_WRITETEXT);
     if(!out)
       return 1; /* failure */
   }
@@ -1274,9 +1274,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
           "# http://curl.haxx.se/docs/http-cookies.html\n"
           "# This file was generated by libcurl! Edit at your own risk.\n\n",
           out);
-    co = c->cookies;
 
-    while(co) {
+    for(co = c->cookies; co; co = co->next) {
+      if(!co->domain)
+        continue;
       format_ptr = get_netscape_format(co);
       if(format_ptr == NULL) {
         fprintf(out, "#\n# Fatal libcurl error\n");
@@ -1286,7 +1287,6 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
       }
       fprintf(out, "%s\n", format_ptr);
       free(format_ptr);
-      co=co->next;
     }
   }
 
@@ -1307,10 +1307,9 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
       (data->cookies->numcookies == 0))
     return NULL;
 
-  c = data->cookies->cookies;
-
-  while(c) {
-    /* fill the list with _all_ the cookies we know */
+  for(c = data->cookies->cookies; c; c = c->next) {
+    if(!c->domain)
+      continue;
     line = get_netscape_format(c);
     if(!line) {
       curl_slist_free_all(list);
@@ -1323,7 +1322,6 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
       return NULL;
     }
     list = beg;
-    c = c->next;
   }
 
   return list;
diff --git a/Utilities/cmcurl/lib/curl_addrinfo.c b/Utilities/cmcurl/lib/curl_addrinfo.c
index 10652c6..6627a6b 100644
--- a/Utilities/cmcurl/lib/curl_addrinfo.c
+++ b/Utilities/cmcurl/lib/curl_addrinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -33,6 +33,9 @@
 #ifdef HAVE_ARPA_INET_H
 #  include <arpa/inet.h>
 #endif
+#ifdef HAVE_SYS_UN_H
+#  include <sys/un.h>
+#endif
 
 #ifdef __VMS
 #  include <in.h>
@@ -47,15 +50,12 @@
 #include "curl_addrinfo.h"
 #include "inet_pton.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
+
 /* The last #include file should be: */
 #include "memdebug.h"
 
-
 /*
  * Curl_freeaddrinfo()
  *
@@ -80,13 +80,8 @@ Curl_freeaddrinfo(Curl_addrinfo *cahead)
   Curl_addrinfo *ca;
 
   for(ca = cahead; ca != NULL; ca = canext) {
-
-    if(ca->ai_addr)
-      free(ca->ai_addr);
-
-    if(ca->ai_canonname)
-      free(ca->ai_canonname);
-
+    free(ca->ai_addr);
+    free(ca->ai_canonname);
     canext = ca->ai_next;
 
     free(ca);
@@ -354,7 +349,7 @@ Curl_he2ai(const struct hostent *he, int port)
     prevai = ai;
   }
 
-  if(result != CURLE_OK) {
+  if(result) {
     Curl_freeaddrinfo(firstai);
     firstai = NULL;
   }
@@ -477,6 +472,42 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
   return NULL; /* bad input format */
 }
 
+#ifdef USE_UNIX_SOCKETS
+/**
+ * Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo
+ * struct initialized with this path.
+ */
+Curl_addrinfo *Curl_unix2addr(const char *path)
+{
+  Curl_addrinfo *ai;
+  struct sockaddr_un *sa_un;
+  size_t path_len;
+
+  ai = calloc(1, sizeof(Curl_addrinfo));
+  if(!ai)
+    return NULL;
+  if((ai->ai_addr = calloc(1, sizeof(struct sockaddr_un))) == NULL) {
+    free(ai);
+    return NULL;
+  }
+  /* sun_path must be able to store the NUL-terminated path */
+  path_len = strlen(path);
+  if(path_len >= sizeof(sa_un->sun_path)) {
+    free(ai->ai_addr);
+    free(ai);
+    return NULL;
+  }
+
+  ai->ai_family = AF_UNIX;
+  ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
+  ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
+  sa_un = (void *) ai->ai_addr;
+  sa_un->sun_family = AF_UNIX;
+  memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */
+  return ai;
+}
+#endif
+
 #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
 /*
  * curl_dofreeaddrinfo()
diff --git a/Utilities/cmcurl/lib/curl_addrinfo.h b/Utilities/cmcurl/lib/curl_addrinfo.h
index 6d2b753..4ef8827 100644
--- a/Utilities/cmcurl/lib/curl_addrinfo.h
+++ b/Utilities/cmcurl/lib/curl_addrinfo.h
@@ -79,6 +79,10 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
 
 Curl_addrinfo *Curl_str2addr(char *dotted, int port);
 
+#ifdef USE_UNIX_SOCKETS
+Curl_addrinfo *Curl_unix2addr(const char *path);
+#endif
+
 #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
 void
 curl_dofreeaddrinfo(struct addrinfo *freethis,
diff --git a/Utilities/cmcurl/lib/curl_config.h.cmake b/Utilities/cmcurl/lib/curl_config.h.cmake
index a561c3d..06201ec 100644
--- a/Utilities/cmcurl/lib/curl_config.h.cmake
+++ b/Utilities/cmcurl/lib/curl_config.h.cmake
@@ -47,7 +47,7 @@
 #endif
 
 /* Use Windows LDAP implementation */
-#cmakedefine CURL_LDAP_WIN 1
+#cmakedefine USE_WIN32_LDAP 1
 
 /* when not building a shared library */
 #cmakedefine CURL_STATICLIB 1
@@ -461,6 +461,9 @@
 /* Define to 1 if you have a working POSIX-style strerror_r function. */
 #cmakedefine HAVE_POSIX_STRERROR_R 1
 
+/* Define to 1 if you have the <pthread.h> header file */
+#cmakedefine HAVE_PTHREAD_H 1
+
 /* Define to 1 if you have the <pwd.h> header file. */
 #cmakedefine HAVE_PWD_H 1
 
@@ -873,6 +876,9 @@
 /* Define if you want to enable c-ares support */
 #cmakedefine USE_ARES 1
 
+/* Define if you want to enable POSIX threaded DNS lookup */
+#cmakedefine USE_THREADS_POSIX 1
+
 /* Define to disable non-blocking sockets. */
 #cmakedefine USE_BLOCKING_SOCKETS 1
 
@@ -897,8 +903,8 @@
 /* if OpenSSL is in use */
 #cmakedefine USE_OPENSSL 1
 
-/* if SSL is enabled */
-#cmakedefine USE_SSLEAY 1
+/* if Unix domain sockets are enabled  */
+#cmakedefine USE_UNIX_SOCKETS
 
 /* to enable SSPI support */
 #cmakedefine USE_WINDOWS_SSPI 1
diff --git a/Utilities/cmcurl/lib/curl_des.c b/Utilities/cmcurl/lib/curl_des.c
new file mode 100644
index 0000000..42c1df9
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_des.c
@@ -0,0 +1,63 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Steve Holme, <steve_holme at hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && (!defined(USE_OPENSSL) || defined(HAVE_BORINGSSL))
+
+#include "curl_des.h"
+
+/*
+ * Curl_des_set_odd_parity()
+ *
+ * This is used to apply odd parity to the given byte array. It is typically
+ * used by when a cryptography engines doesn't have it's own version.
+ *
+ * The function is a port of the Java based oddParity() function over at:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ *
+ * Parameters:
+ *
+ * bytes       [in/out] - The data whose parity bits are to be adjusted for
+ *                        odd parity.
+ * len         [out]    - The length of the data.
+ */
+void Curl_des_set_odd_parity(unsigned char *bytes, size_t len)
+{
+  size_t i;
+
+  for(i = 0; i < len; i++) {
+    unsigned char b = bytes[i];
+
+    bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^
+                          (b >> 4) ^ (b >> 3) ^ (b >> 2) ^
+                          (b >> 1)) & 0x01) == 0;
+
+    if(needs_parity)
+      bytes[i] |= 0x01;
+    else
+      bytes[i] &= 0xfe;
+  }
+}
+
+#endif /* USE_NTLM && (!USE_OPENSSL || HAVE_BORINGSSL) */
diff --git a/Utilities/cmcurl/lib/curl_des.h b/Utilities/cmcurl/lib/curl_des.h
new file mode 100644
index 0000000..b855db4
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_des.h
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_DES_H
+#define HEADER_CURL_DES_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Steve Holme, <steve_holme at hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && (!defined(USE_OPENSSL) || defined(HAVE_BORINGSSL))
+
+/* Applies odd parity to the given byte array */
+void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);
+
+#endif /* USE_NTLM && (!USE_OPENSSL || HAVE_BORINGSSL) */
+
+#endif /* HEADER_CURL_DES_H */
diff --git a/Utilities/cmcurl/lib/curl_endian.c b/Utilities/cmcurl/lib/curl_endian.c
new file mode 100644
index 0000000..bcd66ed
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_endian.c
@@ -0,0 +1,236 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "curl_endian.h"
+
+/*
+ * Curl_read16_le()
+ *
+ * This function converts a 16-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 2 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned short Curl_read16_le(unsigned char *buf)
+{
+  return (unsigned short)(((unsigned short)buf[0]) |
+                          ((unsigned short)buf[1] << 8));
+}
+
+/*
+ * Curl_read32_le()
+ *
+ * This function converts a 32-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 4 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned int Curl_read32_le(unsigned char *buf)
+{
+  return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
+         ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_read64_le()
+ *
+ * This function converts a 64-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 8 byte buffer.
+ *
+ * Returns the integer.
+ */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_le(unsigned char *buf)
+{
+  return ((unsigned long long)buf[0]) |
+         ((unsigned long long)buf[1] << 8) |
+         ((unsigned long long)buf[2] << 16) |
+         ((unsigned long long)buf[3] << 24) |
+         ((unsigned long long)buf[4] << 32) |
+         ((unsigned long long)buf[5] << 40) |
+         ((unsigned long long)buf[6] << 48) |
+         ((unsigned long long)buf[7] << 56);
+}
+#else
+unsigned __int64 Curl_read64_le(unsigned char *buf)
+{
+  return ((unsigned __int64)buf[0]) | ((unsigned __int64)buf[1] << 8) |
+         ((unsigned __int64)buf[2] << 16) | ((unsigned __int64)buf[3] << 24) |
+         ((unsigned __int64)buf[4] << 32) | ((unsigned __int64)buf[5] << 40) |
+         ((unsigned __int64)buf[6] << 48) | ((unsigned __int64)buf[7] << 56);
+}
+#endif
+
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
+
+/*
+ * Curl_read16_be()
+ *
+ * This function converts a 16-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 2 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned short Curl_read16_be(unsigned char *buf)
+{
+  return (unsigned short)(((unsigned short)buf[0] << 8) |
+                          ((unsigned short)buf[1]));
+}
+
+/*
+ * Curl_read32_be()
+ *
+ * This function converts a 32-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 4 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned int Curl_read32_be(unsigned char *buf)
+{
+  return ((unsigned int)buf[0] << 24) | ((unsigned int)buf[1] << 16) |
+         ((unsigned int)buf[2] << 8) | ((unsigned int)buf[3]);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_read64_be()
+ *
+ * This function converts a 64-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 8 byte buffer.
+ *
+ * Returns the integer.
+ */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_be(unsigned char *buf)
+{
+  return ((unsigned long long)buf[0] << 56) |
+         ((unsigned long long)buf[1] << 48) |
+         ((unsigned long long)buf[2] << 40) |
+         ((unsigned long long)buf[3] << 32) |
+         ((unsigned long long)buf[4] << 24) |
+         ((unsigned long long)buf[5] << 16) |
+         ((unsigned long long)buf[6] << 8) |
+         ((unsigned long long)buf[7]);
+}
+#else
+unsigned __int64 Curl_read64_be(unsigned char *buf)
+{
+  return ((unsigned __int64)buf[0] << 56) | ((unsigned __int64)buf[1] << 48) |
+         ((unsigned __int64)buf[2] << 40) | ((unsigned __int64)buf[3] << 32) |
+         ((unsigned __int64)buf[4] << 24) | ((unsigned __int64)buf[5] << 16) |
+         ((unsigned __int64)buf[6] << 8) | ((unsigned __int64)buf[7]);
+}
+#endif
+
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
+
+/*
+ * Curl_write16_le()
+ *
+ * This function converts a 16-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value    [in]     - The 16-bit integer value.
+ * buffer   [in]     - A pointer to the output buffer.
+ */
+void Curl_write16_le(const short value, unsigned char *buffer)
+{
+  buffer[0] = (char)(value & 0x00FF);
+  buffer[1] = (char)((value & 0xFF00) >> 8);
+}
+
+/*
+ * Curl_write32_le()
+ *
+ * This function converts a 32-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value    [in]     - The 32-bit integer value.
+ * buffer   [in]     - A pointer to the output buffer.
+ */
+void Curl_write32_le(const int value, unsigned char *buffer)
+{
+  buffer[0] = (char)(value & 0x000000FF);
+  buffer[1] = (char)((value & 0x0000FF00) >> 8);
+  buffer[2] = (char)((value & 0x00FF0000) >> 16);
+  buffer[3] = (char)((value & 0xFF000000) >> 24);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_write64_le()
+ *
+ * This function converts a 64-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value    [in]     - The 64-bit integer value.
+ * buffer   [in]     - A pointer to the output buffer.
+ */
+#if defined(HAVE_LONGLONG)
+void Curl_write64_le(const long long value, unsigned char *buffer)
+#else
+void Curl_write64_le(const __int64 value, unsigned char *buffer)
+#endif
+{
+  Curl_write32_le((int)value, buffer);
+  Curl_write32_le((int)(value >> 32), buffer + 4);
+}
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
diff --git a/Utilities/cmcurl/lib/curl_endian.h b/Utilities/cmcurl/lib/curl_endian.h
new file mode 100644
index 0000000..e384279
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_endian.h
@@ -0,0 +1,70 @@
+#ifndef HEADER_CURL_ENDIAN_H
+#define HEADER_CURL_ENDIAN_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Converts a 16-bit integer from little endian */
+unsigned short Curl_read16_le(unsigned char *buf);
+
+/* Converts a 32-bit integer from little endian */
+unsigned int Curl_read32_le(unsigned char *buf);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer from little endian */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_le(unsigned char *buf);
+#else
+unsigned __int64 Curl_read64_le(unsigned char *buf);
+#endif
+#endif
+
+/* Converts a 16-bit integer from big endian */
+unsigned short Curl_read16_be(unsigned char *buf);
+
+/* Converts a 32-bit integer from big endian */
+unsigned int Curl_read32_be(unsigned char *buf);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer from big endian */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_be(unsigned char *buf);
+#else
+unsigned __int64 Curl_read64_be(unsigned char *buf);
+#endif
+#endif
+
+/* Converts a 16-bit integer to little endian */
+void Curl_write16_le(const short value, unsigned char *buffer);
+
+/* Converts a 32-bit integer to little endian */
+void Curl_write32_le(const int value, unsigned char *buffer);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer to little endian */
+#if defined(HAVE_LONGLONG)
+void Curl_write64_le(const long long value, unsigned char *buffer);
+#else
+void Curl_write64_le(const __int64 value, unsigned char *buffer);
+#endif
+#endif
+
+#endif /* HEADER_CURL_ENDIAN_H */
diff --git a/Utilities/cmcurl/lib/curl_fnmatch.c b/Utilities/cmcurl/lib/curl_fnmatch.c
index 63f67b9..1e53918 100644
--- a/Utilities/cmcurl/lib/curl_fnmatch.c
+++ b/Utilities/cmcurl/lib/curl_fnmatch.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,11 +23,8 @@
 #include "curl_setup.h"
 
 #include "curl_fnmatch.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
+
 /* The last #include file should be: */
 #include "memdebug.h"
 
diff --git a/Utilities/cmcurl/lib/curl_gssapi.c b/Utilities/cmcurl/lib/curl_gssapi.c
index 232b3ef..9baece5 100644
--- a/Utilities/cmcurl/lib/curl_gssapi.c
+++ b/Utilities/cmcurl/lib/curl_gssapi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2011 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,9 +27,9 @@
 #include "curl_gssapi.h"
 #include "sendf.h"
 
-static const char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
+static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
 gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
-static const char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
+static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
 gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
 
 OM_uint32 Curl_gss_init_sec_context(
@@ -41,9 +41,13 @@ OM_uint32 Curl_gss_init_sec_context(
     gss_channel_bindings_t input_chan_bindings,
     gss_buffer_t input_token,
     gss_buffer_t output_token,
+    const bool mutual_auth,
     OM_uint32 *ret_flags)
 {
-  OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
+  OM_uint32 req_flags = GSS_C_REPLAY_FLAG;
+
+  if(mutual_auth)
+    req_flags |= GSS_C_MUTUAL_FLAG;
 
   if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
 #ifdef GSS_C_DELEG_POLICY_FLAG
@@ -72,4 +76,45 @@ OM_uint32 Curl_gss_init_sec_context(
                               NULL /* time_rec */);
 }
 
+/*
+ * Curl_gss_log_error()
+ *
+ * This is used to log a GSS-API error status.
+ *
+ * Parameters:
+ *
+ * data    [in] - The session handle.
+ * status  [in] - The status code.
+ * prefix  [in] - The prefix of the log message.
+ */
+void Curl_gss_log_error(struct SessionHandle *data, OM_uint32 status,
+                        const char *prefix)
+{
+  OM_uint32 maj_stat;
+  OM_uint32 min_stat;
+  OM_uint32 msg_ctx = 0;
+  gss_buffer_desc status_string;
+  char buf[1024];
+  size_t len;
+
+  snprintf(buf, sizeof(buf), "%s", prefix);
+  len = strlen(buf);
+  do {
+    maj_stat = gss_display_status(&min_stat,
+                                  status,
+                                  GSS_C_MECH_CODE,
+                                  GSS_C_NO_OID,
+                                  &msg_ctx,
+                                  &status_string);
+    if(sizeof(buf) > len + status_string.length + 1) {
+      snprintf(buf + len, sizeof(buf) - len,
+        ": %s", (char*)status_string.value);
+      len += status_string.length;
+    }
+    gss_release_buffer(&min_stat, &status_string);
+  } while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
+
+  infof(data, "%s\n", buf);
+}
+
 #endif /* HAVE_GSSAPI */
diff --git a/Utilities/cmcurl/lib/curl_gssapi.h b/Utilities/cmcurl/lib/curl_gssapi.h
index b91bd7e..19aab64 100644
--- a/Utilities/cmcurl/lib/curl_gssapi.h
+++ b/Utilities/cmcurl/lib/curl_gssapi.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -43,7 +43,6 @@ extern gss_OID_desc Curl_spnego_mech_oid;
 extern gss_OID_desc Curl_krb5_mech_oid;
 
 /* Common method for using GSS-API */
-
 OM_uint32 Curl_gss_init_sec_context(
     struct SessionHandle *data,
     OM_uint32 *minor_status,
@@ -53,8 +52,24 @@ OM_uint32 Curl_gss_init_sec_context(
     gss_channel_bindings_t input_chan_bindings,
     gss_buffer_t input_token,
     gss_buffer_t output_token,
+    const bool mutual_auth,
     OM_uint32 *ret_flags);
 
+/* Helper to log a GSS-API error status */
+void Curl_gss_log_error(struct SessionHandle *data, OM_uint32 status,
+                        const char *prefix);
+
+/* Provide some definitions missing in old headers */
+#ifdef HAVE_OLD_GSSMIT
+#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
+#define NCOMPAT 1
+#endif
+
+/* Define our privacy and integrity protection values */
+#define GSSAUTH_P_NONE      1
+#define GSSAUTH_P_INTEGRITY 2
+#define GSSAUTH_P_PRIVACY   4
+
 #endif /* HAVE_GSSAPI */
 
 #endif /* HEADER_CURL_GSSAPI_H */
diff --git a/Utilities/cmcurl/lib/curl_md4.h b/Utilities/cmcurl/lib/curl_md4.h
index b0be9cf..13c7903 100644
--- a/Utilities/cmcurl/lib/curl_md4.h
+++ b/Utilities/cmcurl/lib/curl_md4.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,10 +24,12 @@
 
 #include "curl_setup.h"
 
-/* NSS crypto library does not provide the MD4 hash algorithm, so that we have
- * a local implementation of it */
-#ifdef USE_NSS
+/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so
+ * that we have a local implementation of it */
+#if defined(USE_NSS) || defined(USE_OS400CRYPTO)
+
 void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
-#endif /* USE_NSS */
+
+#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */
 
 #endif /* HEADER_CURL_MD4_H */
diff --git a/Utilities/cmcurl/lib/curl_memory.h b/Utilities/cmcurl/lib/curl_memory.h
index e3cdc72..bc744cc 100644
--- a/Utilities/cmcurl/lib/curl_memory.h
+++ b/Utilities/cmcurl/lib/curl_memory.h
@@ -28,6 +28,9 @@
  * File curl_memory.h must be included by _all_ *.c source files
  * that use memory related functions strdup, malloc, calloc, realloc
  * or free, and given source file is used to build libcurl library.
+ * It should be included immediately before memdebug.h as the last files
+ * included to avoid undesired interaction with other memory function
+ * headers in dependent libraries.
  *
  * There is nearly no exception to above rule. All libcurl source
  * files in 'lib' subdirectory as well as those living deep inside
diff --git a/Utilities/cmcurl/lib/curl_memrchr.c b/Utilities/cmcurl/lib/curl_memrchr.c
index a71c2bb..6722c6a 100644
--- a/Utilities/cmcurl/lib/curl_memrchr.c
+++ b/Utilities/cmcurl/lib/curl_memrchr.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -21,13 +21,9 @@
  ***************************************************************************/
 
 #include "curl_setup.h"
-
 #include "curl_memrchr.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
+
 /* The last #include file should be: */
 #include "memdebug.h"
 
diff --git a/Utilities/cmcurl/lib/curl_multibyte.c b/Utilities/cmcurl/lib/curl_multibyte.c
index 6c02239..403d005 100644
--- a/Utilities/cmcurl/lib/curl_multibyte.c
+++ b/Utilities/cmcurl/lib/curl_multibyte.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,18 +22,16 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_WIN32_IDN) || (defined(USE_WINDOWS_SSPI) && defined(UNICODE))
+#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
+                                defined(USE_WIN32_LDAP)) && defined(UNICODE))
 
  /*
   * MultiByte conversions using Windows kernel32 library.
   */
 
 #include "curl_multibyte.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
+
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -49,7 +47,8 @@ wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
       if(str_w) {
         if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
                                str_w_len) == 0) {
-          Curl_safefree(str_w);
+          free(str_w);
+          return NULL;
         }
       }
     }
@@ -70,7 +69,8 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
       if(str_utf8) {
         if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
                                NULL, FALSE) == 0) {
-          Curl_safefree(str_utf8);
+          free(str_utf8);
+          return NULL;
         }
       }
     }
@@ -79,4 +79,4 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
   return str_utf8;
 }
 
-#endif /* USE_WIN32_IDN || (USE_WINDOWS_SSPI && UNICODE) */
+#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
diff --git a/Utilities/cmcurl/lib/curl_multibyte.h b/Utilities/cmcurl/lib/curl_multibyte.h
index 7ee5eae..dc7ed4c 100644
--- a/Utilities/cmcurl/lib/curl_multibyte.h
+++ b/Utilities/cmcurl/lib/curl_multibyte.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,7 +23,8 @@
  ***************************************************************************/
 #include "curl_setup.h"
 
-#if defined(USE_WIN32_IDN) || (defined(USE_WINDOWS_SSPI) && defined(UNICODE))
+#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
+                                defined(USE_WIN32_LDAP)) && defined(UNICODE))
 
  /*
   * MultiByte conversions using Windows kernel32 library.
@@ -32,10 +33,11 @@
 wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
 char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
 
-#endif /* USE_WIN32_IDN || (USE_WINDOWS_SSPI && UNICODE) */
+#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
 
 
-#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI)
+#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \
+    defined(USE_WIN32_LDAP)
 
 /*
  * Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8()
@@ -85,6 +87,6 @@ typedef union {
 
 #endif /* UNICODE */
 
-#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI */
+#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */
 
 #endif /* HEADER_CURL_MULTIBYTE_H */
diff --git a/Utilities/cmcurl/lib/curl_ntlm.c b/Utilities/cmcurl/lib/curl_ntlm.c
index 8c02aba..f9ddf50 100644
--- a/Utilities/cmcurl/lib/curl_ntlm.c
+++ b/Utilities/cmcurl/lib/curl_ntlm.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,7 +22,7 @@
 
 #include "curl_setup.h"
 
-#ifdef USE_NTLM
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
 
 /*
  * NTLM details:
@@ -39,11 +39,9 @@
 #include "curl_ntlm.h"
 #include "curl_ntlm_msgs.h"
 #include "curl_ntlm_wb.h"
+#include "curl_sasl.h"
 #include "url.h"
-#include "curl_memory.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #if defined(USE_NSS)
 #include "vtls/nssg.h"
@@ -51,7 +49,8 @@
 #include "curl_sspi.h"
 #endif
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #if DEBUG_ME
@@ -69,12 +68,6 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
   struct ntlmdata *ntlm;
   CURLcode result = CURLE_OK;
 
-#ifdef USE_NSS
-  result = Curl_nss_force_init(conn->data);
-  if(result)
-    return result;
-#endif
-
   ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
 
   if(checkprefix("NTLM", header)) {
@@ -84,14 +77,18 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
       header++;
 
     if(*header) {
-      result = Curl_ntlm_decode_type2_message(conn->data, header, ntlm);
-      if(CURLE_OK != result)
+      result = Curl_sasl_decode_ntlm_type2_message(conn->data, header, ntlm);
+      if(result)
         return result;
 
       ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
     }
     else {
-      if(ntlm->state == NTLMSTATE_TYPE3) {
+      if(ntlm->state == NTLMSTATE_LAST) {
+        infof(conn->data, "NTLM auth restarted\n");
+        Curl_http_ntlm_cleanup(conn);
+      }
+      else if(ntlm->state == NTLMSTATE_TYPE3) {
         infof(conn->data, "NTLM handshake rejected\n");
         Curl_http_ntlm_cleanup(conn);
         ntlm->state = NTLMSTATE_NONE;
@@ -112,12 +109,11 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
 /*
  * This is for creating ntlm header output
  */
-CURLcode Curl_output_ntlm(struct connectdata *conn,
-                          bool proxy)
+CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
 {
   char *base64 = NULL;
   size_t len = 0;
-  CURLcode error;
+  CURLcode result;
 
   /* point to the address of the pointer that holds the string to send to the
      server, which is for a plain host or for a HTTP proxy */
@@ -175,38 +171,40 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
   case NTLMSTATE_TYPE1:
   default: /* for the weird cases we (re)start here */
     /* Create a type-1 message */
-    error = Curl_ntlm_create_type1_message(userp, passwdp, ntlm, &base64,
-                                           &len);
-    if(error)
-      return error;
+    result = Curl_sasl_create_ntlm_type1_message(userp, passwdp, ntlm, &base64,
+                                                 &len);
+    if(result)
+      return result;
 
     if(base64) {
-      Curl_safefree(*allocuserpwd);
+      free(*allocuserpwd);
       *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
                               proxy ? "Proxy-" : "",
                               base64);
       free(base64);
       if(!*allocuserpwd)
         return CURLE_OUT_OF_MEMORY;
+
       DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
     }
     break;
 
   case NTLMSTATE_TYPE2:
     /* We already received the type-2 message, create a type-3 message */
-    error = Curl_ntlm_create_type3_message(conn->data, userp, passwdp,
-                                           ntlm, &base64, &len);
-    if(error)
-      return error;
+    result = Curl_sasl_create_ntlm_type3_message(conn->data, userp, passwdp,
+                                                 ntlm, &base64, &len);
+    if(result)
+      return result;
 
     if(base64) {
-      Curl_safefree(*allocuserpwd);
+      free(*allocuserpwd);
       *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
                               proxy ? "Proxy-" : "",
                               base64);
       free(base64);
       if(!*allocuserpwd)
         return CURLE_OUT_OF_MEMORY;
+
       DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
 
       ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */
@@ -217,6 +215,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
   case NTLMSTATE_TYPE3:
     /* connection is already authenticated,
      * don't send a header in future requests */
+    ntlm->state = NTLMSTATE_LAST;
+
+  case NTLMSTATE_LAST:
     Curl_safefree(*allocuserpwd);
     authp->done = TRUE;
     break;
@@ -227,22 +228,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
 
 void Curl_http_ntlm_cleanup(struct connectdata *conn)
 {
-#ifdef USE_WINDOWS_SSPI
-  Curl_ntlm_sspi_cleanup(&conn->ntlm);
-  Curl_ntlm_sspi_cleanup(&conn->proxyntlm);
-#elif defined(NTLM_WB_ENABLED)
-  Curl_ntlm_wb_cleanup(conn);
-#else
-  (void)conn;
-#endif
+  Curl_sasl_ntlm_cleanup(&conn->ntlm);
+  Curl_sasl_ntlm_cleanup(&conn->proxyntlm);
 
-#ifndef USE_WINDOWS_SSPI
-  Curl_safefree(conn->ntlm.target_info);
-  conn->ntlm.target_info_len = 0;
-
-  Curl_safefree(conn->proxyntlm.target_info);
-  conn->proxyntlm.target_info_len = 0;
+#if defined(NTLM_WB_ENABLED)
+  Curl_ntlm_wb_cleanup(conn);
 #endif
 }
 
-#endif /* USE_NTLM */
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
diff --git a/Utilities/cmcurl/lib/curl_ntlm.h b/Utilities/cmcurl/lib/curl_ntlm.h
index 21a9e9e..947eac2 100644
--- a/Utilities/cmcurl/lib/curl_ntlm.h
+++ b/Utilities/cmcurl/lib/curl_ntlm.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,7 +24,7 @@
 
 #include "curl_setup.h"
 
-#ifdef USE_NTLM
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
 
 /* this is for ntlm header input */
 CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
@@ -35,10 +35,6 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
 
 void Curl_http_ntlm_cleanup(struct connectdata *conn);
 
-#else
-
-#define Curl_http_ntlm_cleanup(a) Curl_nop_stmt
-
-#endif
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
 
 #endif /* HEADER_CURL_NTLM_H */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_core.c b/Utilities/cmcurl/lib/curl_ntlm_core.c
index b011626..2e5b573 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_core.c
+++ b/Utilities/cmcurl/lib/curl_ntlm_core.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,7 +22,7 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
+#if defined(USE_NTLM)
 
 /*
  * NTLM details:
@@ -31,7 +31,9 @@
  * http://www.innovation.ch/java/ntlm.html
  */
 
-#ifdef USE_SSLEAY
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#ifdef USE_OPENSSL
 
 #  ifdef USE_OPENSSL
 #    include <openssl/des.h>
@@ -87,6 +89,11 @@
 #  include <CommonCrypto/CommonCryptor.h>
 #  include <CommonCrypto/CommonDigest.h>
 
+#elif defined(USE_OS400CRYPTO)
+#  include "cipher.mih"  /* mih/cipher */
+#  include "curl_md4.h"
+#elif defined(USE_WIN32_CRYPTO)
+#  include <wincrypt.h>
 #else
 #  error "Can't compile NTLM support without a crypto library."
 #endif
@@ -94,32 +101,27 @@
 #include "urldata.h"
 #include "non-ascii.h"
 #include "rawstr.h"
-#include "curl_memory.h"
 #include "curl_ntlm_core.h"
 #include "curl_md5.h"
 #include "curl_hmac.h"
 #include "warnless.h"
+#include "curl_endian.h"
+#include "curl_des.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #define NTLM_HMAC_MD5_LEN     (16)
 #define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
 #define NTLMv2_BLOB_LEN       (44 -16 + ntlm->target_info_len + 4)
 
-#ifdef USE_SSLEAY
 /*
- * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
- * key schedule ks is also set.
- */
-static void setup_des_key(const unsigned char *key_56,
-                          DES_key_schedule DESKEYARG(ks))
+* Turns a 56-bit key into being 64-bit wide.
+*/
+static void extend_key_56_to_64(const unsigned char *key_56, char *key)
 {
-  DES_cblock key;
-
   key[0] = key_56[0];
   key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
   key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
@@ -128,36 +130,47 @@ static void setup_des_key(const unsigned char *key_56,
   key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
   key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
   key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
-
-  DES_set_odd_parity(&key);
-  DES_set_key(&key, ks);
 }
 
-#else /* defined(USE_SSLEAY) */
-
+#ifdef USE_OPENSSL
 /*
- * Turns a 56 bit key into the 64 bit, odd parity key.  Used by GnuTLS and NSS.
+ * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
+ * key schedule ks is also set.
  */
-static void extend_key_56_to_64(const unsigned char *key_56, char *key)
+static void setup_des_key(const unsigned char *key_56,
+                          DES_key_schedule DESKEYARG(ks))
 {
-  key[0] = key_56[0];
-  key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
-  key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
-  key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
-  key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
-  key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
-  key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
-  key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
+  DES_cblock key;
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, (char *) key);
+
+  /* Set the key parity to odd */
+#if defined(HAVE_BORINGSSL)
+  Curl_des_set_odd_parity((unsigned char *) &key, sizeof(key));
+#else
+  DES_set_odd_parity(&key);
+#endif
+
+  /* Set the key */
+  DES_set_key(&key, ks);
 }
 
-#if defined(USE_GNUTLS_NETTLE)
+#elif defined(USE_GNUTLS_NETTLE)
 
 static void setup_des_key(const unsigned char *key_56,
                           struct des_ctx *des)
 {
   char key[8];
+
+  /* Expand the 56-bit key to 64-bits */
   extend_key_56_to_64(key_56, key);
-  des_set_key(des, (const uint8_t*)key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Set the key */
+  des_set_key(des, (const uint8_t *) key);
 }
 
 #elif defined(USE_GNUTLS)
@@ -169,8 +182,15 @@ static void setup_des_key(const unsigned char *key_56,
                           gcry_cipher_hd_t *des)
 {
   char key[8];
+
+  /* Expand the 56-bit key to 64-bits */
   extend_key_56_to_64(key_56, key);
-  gcry_cipher_setkey(*des, key, 8);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Set the key */
+  gcry_cipher_setkey(*des, key, sizeof(key));
 }
 
 #elif defined(USE_NSS)
@@ -198,16 +218,21 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
   if(!slot)
     return FALSE;
 
-  /* expand the 56 bit key to 64 bit and wrap by NSS */
+  /* Expand the 56-bit key to 64-bits */
   extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Import the key */
   key_item.data = (unsigned char *)key;
-  key_item.len = /* hard-wired */ 8;
+  key_item.len = sizeof(key);
   symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
                              &key_item, NULL);
   if(!symkey)
     goto fail;
 
-  /* create DES encryption context */
+  /* Create the DES encryption context */
   param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
   if(!param)
     goto fail;
@@ -215,7 +240,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
   if(!ctx)
     goto fail;
 
-  /* perform the encryption */
+  /* Perform the encryption */
   if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
                                  (unsigned char *)in, /* inbuflen */ 8)
       && SECSuccess == PK11_Finalize(ctx))
@@ -242,16 +267,95 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
   size_t out_len;
   CCCryptorStatus err;
 
+  /* Expand the 56-bit key to 64-bits */
   extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Perform the encryption */
   err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
                 kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
                 8 /* outbuflen */, &out_len);
+
   return err == kCCSuccess;
 }
 
-#endif /* defined(USE_DARWINSSL) */
+#elif defined(USE_OS400CRYPTO)
 
-#endif /* defined(USE_SSLEAY) */
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  char key[8];
+  _CIPHER_Control_T ctl;
+
+  /* Setup the cipher control structure */
+  ctl.Func_ID = ENCRYPT_ONLY;
+  ctl.Data_Len = sizeof(key);
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, ctl.Crypto_Key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
+
+  /* Perform the encryption */
+  _CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
+
+  return TRUE;
+}
+
+#elif defined(USE_WIN32_CRYPTO)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  HCRYPTPROV hprov;
+  HCRYPTKEY hkey;
+  struct {
+    BLOBHEADER hdr;
+    unsigned int len;
+    char key[8];
+  } blob;
+  DWORD len = 8;
+
+  /* Acquire the crypto provider */
+  if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
+                          CRYPT_VERIFYCONTEXT))
+    return FALSE;
+
+  /* Setup the key blob structure */
+  memset(&blob, 0, sizeof(blob));
+  blob.hdr.bType = PLAINTEXTKEYBLOB;
+  blob.hdr.bVersion = 2;
+  blob.hdr.aiKeyAlg = CALG_DES;
+  blob.len = sizeof(blob.key);
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, blob.key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
+
+  /* Import the key */
+  if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
+    CryptReleaseContext(hprov, 0);
+
+    return FALSE;
+  }
+
+  memcpy(out, in, 8);
+
+  /* Perform the encryption */
+  CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len);
+
+  CryptDestroyKey(hkey);
+  CryptReleaseContext(hprov, 0);
+
+  return TRUE;
+}
+
+#endif /* defined(USE_WIN32_CRYPTO) */
 
  /*
   * takes a 21 byte array and treats it as 3 56-bit DES keys. The
@@ -262,7 +366,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
                             const unsigned char *plaintext,
                             unsigned char *results)
 {
-#ifdef USE_SSLEAY
+#ifdef USE_OPENSSL
   DES_key_schedule ks;
 
   setup_des_key(keys, DESKEY(ks));
@@ -301,7 +405,8 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
   setup_des_key(keys + 14, &des);
   gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
   gcry_cipher_close(des);
-#elif defined(USE_NSS) || defined(USE_DARWINSSL)
+#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
+  || defined(USE_WIN32_CRYPTO)
   encrypt_des(plaintext, results, keys);
   encrypt_des(plaintext, results + 8, keys + 7);
   encrypt_des(plaintext, results + 16, keys + 14);
@@ -311,11 +416,11 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
 /*
  * Set up lanmanager hashed password
  */
-void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
-                               const char *password,
-                               unsigned char *lmbuffer /* 21 bytes */)
+CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
+                                   const char *password,
+                                   unsigned char *lmbuffer /* 21 bytes */)
 {
-  CURLcode res;
+  CURLcode result;
   unsigned char pw[14];
   static const unsigned char magic[] = {
     0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
@@ -329,14 +434,14 @@ void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
    * The LanManager hashed password needs to be created using the
    * password in the network encoding not the host encoding.
    */
-  res = Curl_convert_to_network(data, (char *)pw, 14);
-  if(res)
-    return;
+  result = Curl_convert_to_network(data, (char *)pw, 14);
+  if(result)
+    return result;
 
   {
     /* Create LanManager hashed password. */
 
-#ifdef USE_SSLEAY
+#ifdef USE_OPENSSL
     DES_key_schedule ks;
 
     setup_des_key(pw, DESKEY(ks));
@@ -364,13 +469,16 @@ void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
     setup_des_key(pw + 7, &des);
     gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
     gcry_cipher_close(des);
-#elif defined(USE_NSS) || defined(USE_DARWINSSL)
+#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
+  || defined(USE_WIN32_CRYPTO)
     encrypt_des(magic, lmbuffer, pw);
     encrypt_des(magic, lmbuffer + 8, pw + 7);
 #endif
 
     memset(lmbuffer + 16, 0, 21 - 16);
   }
+
+  return CURLE_OK;
 }
 
 #if USE_NTRESPONSES
@@ -384,6 +492,8 @@ static void ascii_to_unicode_le(unsigned char *dest, const char *src,
   }
 }
 
+#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+
 static void ascii_uppercase_to_unicode_le(unsigned char *dest,
                                           const char *src, size_t srclen)
 {
@@ -394,26 +504,11 @@ static void ascii_uppercase_to_unicode_le(unsigned char *dest,
   }
 }
 
-static void write32_le(const int value, unsigned char *buffer)
-{
-  buffer[0] = (char)(value & 0x000000FF);
-  buffer[1] = (char)((value & 0x0000FF00) >> 8);
-  buffer[2] = (char)((value & 0x00FF0000) >> 16);
-  buffer[3] = (char)((value & 0xFF000000) >> 24);
-}
-
-#if defined(HAVE_LONGLONG)
-static void write64_le(const long long value, unsigned char *buffer)
-#else
-static void write64_le(const __int64 value, unsigned char *buffer)
-#endif
-{
-  write32_le((int)value, buffer);
-  write32_le((int)(value >> 32), buffer + 4);
-}
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
 
 /*
  * Set up nt hashed passwords
+ * @unittest: 1600
  */
 CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
                                    const char *password,
@@ -437,7 +532,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
 
   {
     /* Create NT hashed password. */
-#ifdef USE_SSLEAY
+#ifdef USE_OPENSSL
     MD4_CTX MD4pw;
     MD4_Init(&MD4pw);
     MD4_Update(&MD4pw, pw, 2 * len);
@@ -453,10 +548,23 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
     gcry_md_write(MD4pw, pw, 2 * len);
     memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
     gcry_md_close(MD4pw);
-#elif defined(USE_NSS)
+#elif defined(USE_NSS) || defined(USE_OS400CRYPTO)
     Curl_md4it(ntbuffer, pw, 2 * len);
 #elif defined(USE_DARWINSSL)
     (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
+#elif defined(USE_WIN32_CRYPTO)
+    HCRYPTPROV hprov;
+    if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
+                           CRYPT_VERIFYCONTEXT)) {
+      HCRYPTHASH hhash;
+      if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) {
+        DWORD length = 16;
+        CryptHashData(hhash, pw, (unsigned int)len * 2, 0);
+        CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0);
+        CryptDestroyHash(hhash);
+      }
+      CryptReleaseContext(hprov, 0);
+    }
 #endif
 
     memset(ntbuffer + 16, 0, 21 - 16);
@@ -467,6 +575,8 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
   return CURLE_OK;
 }
 
+#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+
 /* This returns the HMAC MD5 digest */
 CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
                        const unsigned char *data, unsigned int datalen,
@@ -497,7 +607,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
   /* Unicode representation */
   size_t identity_len = (userlen + domlen) * 2;
   unsigned char *identity = malloc(identity_len);
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   if(!identity)
     return CURLE_OUT_OF_MEMORY;
@@ -505,12 +615,12 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
   ascii_uppercase_to_unicode_le(identity, user, userlen);
   ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
 
-  res = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
-                      ntlmv2hash);
+  result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
+                         ntlmv2hash);
 
-  Curl_safefree(identity);
+  free(identity);
 
-  return res;
+  return result;
 }
 
 /*
@@ -559,7 +669,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
 #else
   __int64 tw;
 #endif
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   /* Calculate the timestamp */
 #ifdef DEBUGBUILD
@@ -586,17 +696,17 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
            "%c%c%c%c",  /* Reserved = 0 */
            0, 0, 0, 0);
 
-  write64_le(tw, ptr + 24);
+  Curl_write64_le(tw, ptr + 24);
   memcpy(ptr + 32, challenge_client, 8);
   memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
 
   /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
   memcpy(ptr + 8, &ntlm->nonce[0], 8);
-  res = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
-                      NTLMv2_BLOB_LEN + 8, hmac_output);
-  if(res) {
-    Curl_safefree(ptr);
-    return res;
+  result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
+                         NTLMv2_BLOB_LEN + 8, hmac_output);
+  if(result) {
+    free(ptr);
+    return result;
   }
 
   /* Concatenate the HMAC MD5 output  with the BLOB */
@@ -606,7 +716,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
   *ntresp = ptr;
   *ntresp_len = len;
 
-  return res;
+  return result;
 }
 
 /*
@@ -630,22 +740,26 @@ CURLcode  Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
 {
   unsigned char data[16];
   unsigned char hmac_output[16];
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   memcpy(&data[0], challenge_server, 8);
   memcpy(&data[8], challenge_client, 8);
 
-  res = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
-  if(res)
-    return res;
+  result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
+  if(result)
+    return result;
 
   /* Concatenate the HMAC MD5 output  with the client nonce */
   memcpy(lmresp, hmac_output, 16);
   memcpy(lmresp+16, challenge_client, 8);
 
-  return res;
+  return result;
 }
 
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
 #endif /* USE_NTRESPONSES */
 
-#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* USE_NTLM */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_core.h b/Utilities/cmcurl/lib/curl_ntlm_core.h
index fe41cdd..3a76359 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_core.h
+++ b/Utilities/cmcurl/lib/curl_ntlm_core.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,9 +24,11 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
+#if defined(USE_NTLM)
 
-#ifdef USE_SSLEAY
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#ifdef USE_OPENSSL
 #  if !defined(OPENSSL_VERSION_NUMBER) && \
       !defined(HEADER_SSL_H) && !defined(HEADER_MD5_H)
 #    error "curl_ntlm_core.h shall not be included before OpenSSL headers."
@@ -34,38 +36,49 @@
 #  ifdef OPENSSL_NO_MD4
 #    define USE_NTRESPONSES 0
 #    define USE_NTLM2SESSION 0
+#    define USE_NTLM_V2 0
 #  endif
 #endif
 
-/*
- * Define USE_NTRESPONSES to 1 in order to make the type-3 message include
- * the NT response message. Define USE_NTLM2SESSION to 1 in order to make
- * the type-3 message include the NTLM2Session response message, requires
- * USE_NTRESPONSES defined to 1.
- */
-
+/* Define USE_NTRESPONSES to 1 in order to make the type-3 message include
+ * the NT response message. */
 #ifndef USE_NTRESPONSES
-#  define USE_NTRESPONSES 1
-#  define USE_NTLM2SESSION 1
+#define USE_NTRESPONSES 1
+#endif
+
+/* Define USE_NTLM2SESSION to 1 in order to make the type-3 message include the
+   NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
+   Crypto engine that we have curl_ssl_md5sum() for. */
+#if !defined(USE_NTLM2SESSION) && USE_NTRESPONSES && !defined(USE_WIN32_CRYPTO)
+#define USE_NTLM2SESSION 1
+#endif
+
+/* Define USE_NTLM_V2 to 1 in order to allow the type-3 message to include the
+   LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1
+   and support for 64-bit integers. */
+#if !defined(USE_NTLM_V2) && USE_NTRESPONSES && (CURL_SIZEOF_CURL_OFF_T > 4)
+#define USE_NTLM_V2 1
 #endif
 
 void Curl_ntlm_core_lm_resp(const unsigned char *keys,
                             const unsigned char *plaintext,
                             unsigned char *results);
 
-void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
-                               const char *password,
-                               unsigned char *lmbuffer /* 21 bytes */);
+CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
+                                   const char *password,
+                                   unsigned char *lmbuffer /* 21 bytes */);
 
 #if USE_NTRESPONSES
-CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
-                       const unsigned char *data, unsigned int datalen,
-                       unsigned char *output);
-
 CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
                                    const char *password,
                                    unsigned char *ntbuffer /* 21 bytes */);
 
+#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+
+CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
+                       const unsigned char *data, unsigned int datalen,
+                       unsigned char *output);
+
 CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
                                        const char *domain, size_t domlen,
                                        unsigned char *ntlmhash,
@@ -82,8 +95,12 @@ CURLcode  Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
                                       unsigned char *challenge_server,
                                       unsigned char *lmresp);
 
-#endif
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+#endif /* USE_NTRESPONSES */
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
 
-#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
+#endif /* USE_NTLM */
 
 #endif /* HEADER_CURL_NTLM_CORE_H */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_msgs.c b/Utilities/cmcurl/lib/curl_ntlm_msgs.c
index b807926..7f07dec 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_msgs.c
+++ b/Utilities/cmcurl/lib/curl_ntlm_msgs.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,7 +22,7 @@
 
 #include "curl_setup.h"
 
-#ifdef USE_NTLM
+#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
 
 /*
  * NTLM details:
@@ -41,21 +41,21 @@
 #include "curl_gethostname.h"
 #include "curl_multibyte.h"
 #include "warnless.h"
-#include "curl_memory.h"
-
-#ifdef USE_WINDOWS_SSPI
-#  include "curl_sspi.h"
-#endif
 
 #include "vtls/vtls.h"
 
+#ifdef USE_NSS
+#include "vtls/nssg.h" /* for Curl_nss_force_init() */
+#endif
+
 #define BUILDING_CURL_NTLM_MSGS_C
 #include "curl_ntlm_msgs.h"
+#include "curl_sasl.h"
+#include "curl_endian.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /* "NTLMSSP" signature is always in ASCII regardless of the platform */
@@ -147,63 +147,38 @@ static void ntlm_print_hex(FILE *handle, const char *buf, size_t len)
 # define DEBUG_OUT(x) Curl_nop_stmt
 #endif
 
-#ifndef USE_WINDOWS_SSPI
-/*
- * This function converts from the little endian format used in the
- * incoming package to whatever endian format we're using natively.
- * Argument is a pointer to a 4 byte buffer.
- */
-static unsigned int readint_le(unsigned char *buf)
-{
-  return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
-    ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
-}
-
-/*
- * This function converts from the little endian format used in the incoming
- * package to whatever endian format we're using natively. Argument is a
- * pointer to a 2 byte buffer.
- */
-static unsigned int readshort_le(unsigned char *buf)
-{
-  return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8);
-}
-
 /*
- * Curl_ntlm_decode_type2_target()
+ * ntlm_decode_type2_target()
  *
  * This is used to decode the "target info" in the ntlm type-2 message
  * received.
  *
  * Parameters:
  *
- * data      [in]    - Pointer to the session handle
- * buffer    [in]    - The decoded base64 ntlm header of Type 2
- * size      [in]    - The input buffer size, atleast 32 bytes
- * ntlm      [in]    - Pointer to ntlm data struct being used and modified.
+ * data      [in]     - The session handle.
+ * buffer    [in]     - The decoded type-2 message.
+ * size      [in]     - The input buffer size, at least 32 bytes.
+ * ntlm      [in/out] - The ntlm data struct being used and modified.
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_ntlm_decode_type2_target(struct SessionHandle *data,
-                                       unsigned char *buffer,
-                                       size_t size,
-                                       struct ntlmdata *ntlm)
+static CURLcode ntlm_decode_type2_target(struct SessionHandle *data,
+                                         unsigned char *buffer,
+                                         size_t size,
+                                         struct ntlmdata *ntlm)
 {
-  unsigned int target_info_len = 0;
+  unsigned short target_info_len = 0;
   unsigned int target_info_offset = 0;
 
-  Curl_safefree(ntlm->target_info);
-  ntlm->target_info_len = 0;
-
   if(size >= 48) {
-    target_info_len = readshort_le(&buffer[40]);
-    target_info_offset = readint_le(&buffer[44]);
+    target_info_len = Curl_read16_le(&buffer[40]);
+    target_info_offset = Curl_read32_le(&buffer[44]);
     if(target_info_len > 0) {
       if(((target_info_offset + target_info_len) > size) ||
          (target_info_offset < 48)) {
         infof(data, "NTLM handshake failure (bad type-2 message). "
                     "Target Info Offset Len is set incorrect by the peer\n");
-        return CURLE_REMOTE_ACCESS_DENIED;
+        return CURLE_BAD_CONTENT_ENCODING;
       }
 
       ntlm->target_info = malloc(target_info_len);
@@ -211,17 +186,14 @@ CURLcode Curl_ntlm_decode_type2_target(struct SessionHandle *data,
         return CURLE_OUT_OF_MEMORY;
 
       memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len);
-      ntlm->target_info_len = target_info_len;
-
     }
-
   }
 
+  ntlm->target_info_len = target_info_len;
+
   return CURLE_OK;
 }
 
-#endif
-
 /*
   NTLM message structure notes:
 
@@ -239,29 +211,26 @@ CURLcode Curl_ntlm_decode_type2_target(struct SessionHandle *data,
 */
 
 /*
- * Curl_ntlm_decode_type2_message()
+ * Curl_sasl_decode_ntlm_type2_message()
  *
- * This is used to decode a ntlm type-2 message received from a HTTP or SASL
- * based (such as SMTP, POP3 or IMAP) server. The message is first decoded
- * from a base64 string into a raw ntlm message and checked for validity
- * before the appropriate data for creating a type-3 message is written to
- * the given ntlm data structure.
+ * This is used to decode an already encoded NTLM type-2 message. The message
+ * is first decoded from a base64 string into a raw NTLM message and checked
+ * for validity before the appropriate data for creating a type-3 message is
+ * written to the given NTLM data structure.
  *
  * Parameters:
  *
- * data    [in]     - Pointer to session handle.
- * header  [in]     - Pointer to the input buffer.
- * ntlm    [in]     - Pointer to ntlm data struct being used and modified.
+ * data     [in]     - The session handle.
+ * type2msg [in]     - The base64 encoded type-2 message.
+ * ntlm     [in/out] - The ntlm data struct being used and modified.
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
-                                        const char *header,
-                                        struct ntlmdata *ntlm)
+CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
+                                             const char *type2msg,
+                                             struct ntlmdata *ntlm)
 {
-#ifndef USE_WINDOWS_SSPI
   static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
-#endif
 
   /* NTLM type-2 message structure:
 
@@ -279,52 +248,52 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
                                         (*) -> Optional
   */
 
-  size_t size = 0;
-  unsigned char *buffer = NULL;
-  CURLcode error;
-
-#if defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_WINDOWS_SSPI)
+  CURLcode result = CURLE_OK;
+  unsigned char *type2 = NULL;
+  size_t type2_len = 0;
+
+#if defined(USE_NSS)
+  /* Make sure the crypto backend is initialized */
+  result = Curl_nss_force_init(data);
+  if(result)
+    return result;
+#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
   (void)data;
 #endif
 
-  error = Curl_base64_decode(header, &buffer, &size);
-  if(error)
-    return error;
-
-  if(!buffer) {
-    infof(data, "NTLM handshake failure (unhandled condition)\n");
-    return CURLE_REMOTE_ACCESS_DENIED;
+  /* Decode the base-64 encoded type-2 message */
+  if(strlen(type2msg) && *type2msg != '=') {
+    result = Curl_base64_decode(type2msg, &type2, &type2_len);
+    if(result)
+      return result;
   }
 
-#ifdef USE_WINDOWS_SSPI
-  ntlm->type_2 = malloc(size + 1);
-  if(ntlm->type_2 == NULL) {
-    free(buffer);
-    return CURLE_OUT_OF_MEMORY;
+  /* Ensure we have a valid type-2 message */
+  if(!type2) {
+    infof(data, "NTLM handshake failure (empty type-2 message)\n");
+    return CURLE_BAD_CONTENT_ENCODING;
   }
-  ntlm->n_type_2 = curlx_uztoul(size);
-  memcpy(ntlm->type_2, buffer, size);
-#else
+
   ntlm->flags = 0;
 
-  if((size < 32) ||
-     (memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) ||
-     (memcmp(buffer + 8, type2_marker, sizeof(type2_marker)) != 0)) {
+  if((type2_len < 32) ||
+     (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
+     (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) {
     /* This was not a good enough type-2 message */
-    free(buffer);
+    free(type2);
     infof(data, "NTLM handshake failure (bad type-2 message)\n");
-    return CURLE_REMOTE_ACCESS_DENIED;
+    return CURLE_BAD_CONTENT_ENCODING;
   }
 
-  ntlm->flags = readint_le(&buffer[20]);
-  memcpy(ntlm->nonce, &buffer[24], 8);
+  ntlm->flags = Curl_read32_le(&type2[20]);
+  memcpy(ntlm->nonce, &type2[24], 8);
 
   if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
-    error = Curl_ntlm_decode_type2_target(data, buffer, size, ntlm);
-    if(error) {
-      free(buffer);
+    result = ntlm_decode_type2_target(data, type2, type2_len, ntlm);
+    if(result) {
+      free(type2);
       infof(data, "NTLM handshake failure (bad type-2 message)\n");
-      return error;
+      return result;
     }
   }
 
@@ -336,32 +305,12 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
     fprintf(stderr, "\n****\n");
     fprintf(stderr, "**** Header %s\n ", header);
   });
-#endif
-  free(buffer);
-
-  return CURLE_OK;
-}
 
-#ifdef USE_WINDOWS_SSPI
-void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm)
-{
-  Curl_safefree(ntlm->type_2);
+  free(type2);
 
-  if(ntlm->has_handles) {
-    s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
-    s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
-    ntlm->has_handles = 0;
-  }
-
-  ntlm->max_token_length = 0;
-  Curl_safefree(ntlm->output_token);
-
-  Curl_sspi_free_identity(ntlm->p_identity);
-  ntlm->p_identity = NULL;
+  return result;
 }
-#endif
 
-#ifndef USE_WINDOWS_SSPI
 /* copy the source to the destination and fill in zeroes in every
    other destination byte! */
 static void unicodecpy(unsigned char *dest, const char *src, size_t length)
@@ -372,14 +321,12 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
     dest[2 * i + 1] = '\0';
   }
 }
-#endif
 
 /*
- * Curl_ntlm_create_type1_message()
+ * Curl_sasl_create_ntlm_type1_message()
  *
  * This is used to generate an already encoded NTLM type-1 message ready for
- * sending to the recipient, be it a HTTP or SASL based (such as SMTP, POP3
- * or IMAP) server, using the appropriate compile time crypo API.
+ * sending to the recipient using the appropriate compile time crypto API.
  *
  * Parameters:
  *
@@ -392,11 +339,10 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_ntlm_create_type1_message(const char *userp,
-                                        const char *passwdp,
-                                        struct ntlmdata *ntlm,
-                                        char **outptr,
-                                        size_t *outlen)
+CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
 {
   /* NTLM type-1 message structure:
 
@@ -414,89 +360,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
 
   size_t size;
 
-#ifdef USE_WINDOWS_SSPI
-
-  PSecPkgInfo SecurityPackage;
-  SecBuffer type_1_buf;
-  SecBufferDesc type_1_desc;
-  SECURITY_STATUS status;
-  unsigned long attrs;
-  TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
-
-  Curl_ntlm_sspi_cleanup(ntlm);
-
-  /* Query the security package for NTLM */
-  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("NTLM"),
-                                              &SecurityPackage);
-  if(status != SEC_E_OK)
-    return CURLE_NOT_BUILT_IN;
-
-  ntlm->max_token_length = SecurityPackage->cbMaxToken;
-
-  /* Release the package buffer as it is not required anymore */
-  s_pSecFn->FreeContextBuffer(SecurityPackage);
-
-  /* Allocate our output buffer */
-  ntlm->output_token = malloc(ntlm->max_token_length);
-  if(!ntlm->output_token)
-    return CURLE_OUT_OF_MEMORY;
-
-  if(userp && *userp) {
-    CURLcode result;
-
-    /* Populate our identity structure */
-    result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity);
-    if(result)
-      return result;
-
-    /* Allow proper cleanup of the identity structure */
-    ntlm->p_identity = &ntlm->identity;
-  }
-  else
-    /* Use the current Windows user */
-    ntlm->p_identity = NULL;
-
-  /* Acquire our credientials handle */
-  status = s_pSecFn->AcquireCredentialsHandle(NULL,
-                                              (TCHAR *) TEXT("NTLM"),
-                                              SECPKG_CRED_OUTBOUND, NULL,
-                                              ntlm->p_identity, NULL, NULL,
-                                              &ntlm->handle, &tsDummy);
-  if(status != SEC_E_OK)
-    return CURLE_OUT_OF_MEMORY;
-
-  /* Setup the type-1 "output" security buffer */
-  type_1_desc.ulVersion = SECBUFFER_VERSION;
-  type_1_desc.cBuffers  = 1;
-  type_1_desc.pBuffers  = &type_1_buf;
-  type_1_buf.BufferType = SECBUFFER_TOKEN;
-  type_1_buf.pvBuffer   = ntlm->output_token;
-  type_1_buf.cbBuffer   = curlx_uztoul(ntlm->max_token_length);
-
-  /* Generate our type-1 message */
-  status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL,
-                                               (TCHAR *) TEXT(""),
-                                               ISC_REQ_CONFIDENTIALITY |
-                                               ISC_REQ_REPLAY_DETECT |
-                                               ISC_REQ_CONNECTION,
-                                               0, SECURITY_NETWORK_DREP,
-                                               NULL, 0,
-                                               &ntlm->c_handle, &type_1_desc,
-                                               &attrs, &tsDummy);
-
-  if(status == SEC_I_COMPLETE_AND_CONTINUE ||
-     status == SEC_I_CONTINUE_NEEDED)
-    s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &type_1_desc);
-  else if(status != SEC_E_OK) {
-    s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
-    return CURLE_RECV_ERROR;
-  }
-
-  ntlm->has_handles = 1;
-  size = type_1_buf.cbBuffer;
-
-#else
-
   unsigned char ntlmbuf[NTLM_BUFSIZE];
   const char *host = "";              /* empty */
   const char *domain = "";            /* empty */
@@ -507,9 +370,11 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
                                          domain are empty */
   (void)userp;
   (void)passwdp;
-  (void)ntlm;
 
-#if USE_NTLM2SESSION
+  /* Clean up any former leftovers and initialise to defaults */
+  Curl_sasl_ntlm_cleanup(ntlm);
+
+#if USE_NTRESPONSES && USE_NTLM2SESSION
 #define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
 #else
 #define NTLM2FLAG 0
@@ -550,8 +415,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
   /* Initial packet length */
   size = 32 + hostlen + domlen;
 
-#endif
-
   DEBUG_OUT({
     fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
             "0x%08.8x ",
@@ -575,20 +438,14 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
   });
 
   /* Return with binary blob encoded into base64 */
-#ifdef USE_WINDOWS_SSPI
-  return Curl_base64_encode(NULL, (char *)ntlm->output_token, size,
-                            outptr, outlen);
-#else
   return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
-#endif
 }
 
 /*
- * Curl_ntlm_create_type3_message()
+ * Curl_sasl_create_ntlm_type3_message()
  *
  * This is used to generate an already encoded NTLM type-3 message ready for
- * sending to the recipient, be it a HTTP or SASL based (such as SMTP, POP3
- * or IMAP) server, using the appropriate compile time crypo API.
+ * sending to the recipient using the appropriate compile time crypto API.
  *
  * Parameters:
  *
@@ -602,12 +459,12 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
-                                        const char *userp,
-                                        const char *passwdp,
-                                        struct ntlmdata *ntlm,
-                                        char **outptr,
-                                        size_t *outlen)
+CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
+
 {
   /* NTLM type-3 message structure:
 
@@ -627,65 +484,8 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
                                           (*) -> Optional
   */
 
-  size_t size;
-
-#ifdef USE_WINDOWS_SSPI
   CURLcode result = CURLE_OK;
-  SecBuffer type_2_buf;
-  SecBuffer type_3_buf;
-  SecBufferDesc type_2_desc;
-  SecBufferDesc type_3_desc;
-  SECURITY_STATUS status;
-  unsigned long attrs;
-  TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
-
-  (void)passwdp;
-  (void)userp;
-  (void)data;
-
-  /* Setup the type-2 "input" security buffer */
-  type_2_desc.ulVersion = SECBUFFER_VERSION;
-  type_2_desc.cBuffers  = 1;
-  type_2_desc.pBuffers  = &type_2_buf;
-  type_2_buf.BufferType = SECBUFFER_TOKEN;
-  type_2_buf.pvBuffer   = ntlm->type_2;
-  type_2_buf.cbBuffer   = ntlm->n_type_2;
-
-  /* Setup the type-3 "output" security buffer */
-  type_3_desc.ulVersion = SECBUFFER_VERSION;
-  type_3_desc.cBuffers  = 1;
-  type_3_desc.pBuffers  = &type_3_buf;
-  type_3_buf.BufferType = SECBUFFER_TOKEN;
-  type_3_buf.pvBuffer   = ntlm->output_token;
-  type_3_buf.cbBuffer   = curlx_uztoul(ntlm->max_token_length);
-
-  /* Generate our type-3 message */
-  status = s_pSecFn->InitializeSecurityContext(&ntlm->handle,
-                                               &ntlm->c_handle,
-                                               (TCHAR *) TEXT(""),
-                                               ISC_REQ_CONFIDENTIALITY |
-                                               ISC_REQ_REPLAY_DETECT |
-                                               ISC_REQ_CONNECTION,
-                                               0, SECURITY_NETWORK_DREP,
-                                               &type_2_desc,
-                                               0, &ntlm->c_handle,
-                                               &type_3_desc,
-                                               &attrs, &tsDummy);
-  if(status != SEC_E_OK)
-    return CURLE_RECV_ERROR;
-
-  size = type_3_buf.cbBuffer;
-
-  /* Return with binary blob encoded into base64 */
-  result = Curl_base64_encode(NULL, (char *)ntlm->output_token, size,
-                              outptr, outlen);
-
-  Curl_ntlm_sspi_cleanup(ntlm);
-
-  return result;
-
-#else
-
+  size_t size;
   unsigned char ntlmbuf[NTLM_BUFSIZE];
   int lmrespoff;
   unsigned char lmresp[24]; /* fixed-size */
@@ -706,7 +506,6 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
   size_t hostlen = 0;
   size_t userlen = 0;
   size_t domlen = 0;
-  CURLcode res = CURLE_OK;
 
   user = strchr(userp, '\\');
   if(!user)
@@ -733,7 +532,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
     hostlen = strlen(host);
   }
 
-#if USE_NTRESPONSES
+#if USE_NTRESPONSES && USE_NTLM_V2
   if(ntlm->target_info_len) {
     unsigned char ntbuffer[0x18];
     unsigned int entropy[2];
@@ -742,35 +541,35 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
     entropy[0] = Curl_rand(data);
     entropy[1] = Curl_rand(data);
 
-    res = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
-    if(res)
-      return res;
+    result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    if(result)
+      return result;
 
-    res = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
-                                        ntbuffer, ntlmv2hash);
-    if(res)
-      return res;
+    result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
+                                           ntbuffer, ntlmv2hash);
+    if(result)
+      return result;
 
     /* LMv2 response */
-    res = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
-                                      (unsigned char *)&entropy[0],
-                                      &ntlm->nonce[0], lmresp);
-    if(res)
-      return res;
+    result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
+                                         (unsigned char *)&entropy[0],
+                                         &ntlm->nonce[0], lmresp);
+    if(result)
+      return result;
 
     /* NTLMv2 response */
-    res = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
-                                        (unsigned char *)&entropy[0],
-                                        ntlm, &ntlmv2resp, &ntresplen);
-    if(res)
-      return res;
+    result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
+                                           (unsigned char *)&entropy[0],
+                                           ntlm, &ntlmv2resp, &ntresplen);
+    if(result)
+      return result;
 
     ptr_ntresp = ntlmv2resp;
   }
   else
 #endif
 
-#if USE_NTLM2SESSION
+#if USE_NTRESPONSES && USE_NTLM2SESSION
   /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
   if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
     unsigned char ntbuffer[0x18];
@@ -792,13 +591,13 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
     memcpy(tmp, &ntlm->nonce[0], 8);
     memcpy(tmp + 8, entropy, 8);
 
-    Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
-
-    /* We shall only use the first 8 bytes of md5sum, but the des
-       code in Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
-    if(CURLE_OUT_OF_MEMORY ==
-       Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer))
-      return CURLE_OUT_OF_MEMORY;
+    result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
+    if(!result)
+      /* We shall only use the first 8 bytes of md5sum, but the des code in
+         Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
+      result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    if(result)
+      return result;
 
     Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp);
 
@@ -815,14 +614,19 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
     unsigned char lmbuffer[0x18];
 
 #if USE_NTRESPONSES
-    if(CURLE_OUT_OF_MEMORY ==
-       Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer))
-      return CURLE_OUT_OF_MEMORY;
+    result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    if(result)
+      return result;
+
     Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
 #endif
 
-    Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
+    result = Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
+    if(result)
+      return result;
+
     Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
+
     /* A safer but less compatible alternative is:
      *   Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
      * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
@@ -954,7 +758,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
     ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen);
   });
 
-  Curl_safefree(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
+  free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
 
 #endif
 
@@ -997,14 +801,17 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
   size += hostlen;
 
   /* Convert domain, user, and host to ASCII but leave the rest as-is */
-  res = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
-                                size - domoff);
-  if(res)
+  result = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
+                                   size - domoff);
+  if(result)
     return CURLE_CONV_FAILED;
 
   /* Return with binary blob encoded into base64 */
-  return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
-#endif
+  result = Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
+
+  Curl_sasl_ntlm_cleanup(ntlm);
+
+  return result;
 }
 
-#endif /* USE_NTLM */
+#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_msgs.h b/Utilities/cmcurl/lib/curl_ntlm_msgs.h
index 80413c8..2a71431 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_msgs.h
+++ b/Utilities/cmcurl/lib/curl_ntlm_msgs.h
@@ -26,40 +26,6 @@
 
 #ifdef USE_NTLM
 
-/* This is to generate a base64 encoded NTLM type-1 message */
-CURLcode Curl_ntlm_create_type1_message(const char *userp,
-                                        const char *passwdp,
-                                        struct ntlmdata *ntlm,
-                                        char **outptr,
-                                        size_t *outlen);
-
-/* This is to generate a base64 encoded NTLM type-3 message */
-CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
-                                        const char *userp,
-                                        const char *passwdp,
-                                        struct ntlmdata *ntlm,
-                                        char **outptr,
-                                        size_t *outlen);
-
-/* This is to decode a NTLM type-2 message */
-CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
-                                        const char* header,
-                                        struct ntlmdata* ntlm);
-
-/* This is to decode target info received in NTLM type-2 message */
-CURLcode Curl_ntlm_decode_type2_target(struct SessionHandle *data,
-                                       unsigned char* buffer,
-                                       size_t size,
-                                       struct ntlmdata* ntlm);
-
-
-/* This is to clean up the ntlm data structure */
-#ifdef USE_WINDOWS_SSPI
-void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm);
-#else
-#define Curl_ntlm_sspi_cleanup(x)
-#endif
-
 /* NTLM buffer fixed size, large enough for long user + host + domain */
 #define NTLM_BUFSIZE 1024
 
diff --git a/Utilities/cmcurl/lib/curl_ntlm_wb.c b/Utilities/cmcurl/lib/curl_ntlm_wb.c
index 23ee726..b2a5fb3 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_wb.c
+++ b/Utilities/cmcurl/lib/curl_ntlm_wb.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,7 +22,8 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
 
 /*
  * NTLM details:
@@ -50,12 +51,10 @@
 #include "curl_ntlm_wb.h"
 #include "url.h"
 #include "strerror.h"
-#include "curl_memory.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #if DEBUG_ME
@@ -106,9 +105,9 @@ void Curl_ntlm_wb_cleanup(struct connectdata *conn)
     conn->ntlm_auth_hlpr_pid = 0;
   }
 
-  Curl_safefree(conn->challenge_header);
+  free(conn->challenge_header);
   conn->challenge_header = NULL;
-  Curl_safefree(conn->response_header);
+  free(conn->response_header);
   conn->response_header = NULL;
 }
 
@@ -245,13 +244,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
   sclose(sockfds[1]);
   conn->ntlm_auth_hlpr_socket = sockfds[0];
   conn->ntlm_auth_hlpr_pid = child_pid;
-  Curl_safefree(domain);
-  Curl_safefree(ntlm_auth_alloc);
+  free(domain);
+  free(ntlm_auth_alloc);
   return CURLE_OK;
 
 done:
-  Curl_safefree(domain);
-  Curl_safefree(ntlm_auth_alloc);
+  free(domain);
+  free(ntlm_auth_alloc);
   return CURLE_REMOTE_ACCESS_DENIED;
 }
 
@@ -293,7 +292,7 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
     len_out += size;
     if(buf[len_out - 1] == '\n') {
       buf[len_out - 1] = '\0';
-      goto wrfinish;
+      break;
     }
     newbuf = realloc(buf, len_out + NTLM_BUFSIZE);
     if(!newbuf) {
@@ -302,13 +301,12 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
     }
     buf = newbuf;
   }
-  goto done;
-wrfinish:
+
   /* Samba/winbind installed but not configured */
   if(state == NTLMSTATE_TYPE1 &&
      len_out == 3 &&
      buf[0] == 'P' && buf[1] == 'W')
-    return CURLE_REMOTE_ACCESS_DENIED;
+    goto done;
   /* invalid response */
   if(len_out < 4)
     goto done;
@@ -391,12 +389,12 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
     if(res)
       return res;
 
-    Curl_safefree(*allocuserpwd);
+    free(*allocuserpwd);
     *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
                             proxy ? "Proxy-" : "",
                             conn->response_header);
     DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
-    Curl_safefree(conn->response_header);
+    free(conn->response_header);
     conn->response_header = NULL;
     break;
   case NTLMSTATE_TYPE2:
@@ -409,7 +407,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
     if(res)
       return res;
 
-    Curl_safefree(*allocuserpwd);
+    free(*allocuserpwd);
     *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
                             proxy ? "Proxy-" : "",
                             conn->response_header);
@@ -421,10 +419,8 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
   case NTLMSTATE_TYPE3:
     /* connection is already authenticated,
      * don't send a header in future requests */
-    if(*allocuserpwd) {
-      free(*allocuserpwd);
-      *allocuserpwd=NULL;
-    }
+    free(*allocuserpwd);
+    *allocuserpwd=NULL;
     authp->done = TRUE;
     break;
   }
@@ -432,4 +428,4 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
   return CURLE_OK;
 }
 
-#endif /* USE_NTLM && NTLM_WB_ENABLED */
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_wb.h b/Utilities/cmcurl/lib/curl_ntlm_wb.h
index db6bc16..828bb57 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_wb.h
+++ b/Utilities/cmcurl/lib/curl_ntlm_wb.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,7 +24,8 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
 
 /* this is for creating ntlm header output by delegating challenge/response
    to Samba's winbind daemon helper ntlm_auth */
@@ -32,6 +33,6 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy);
 
 void Curl_ntlm_wb_cleanup(struct connectdata *conn);
 
-#endif /* USE_NTLM && NTLM_WB_ENABLED */
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
 
 #endif /* HEADER_CURL_NTLM_WB_H */
diff --git a/Utilities/cmcurl/lib/curl_printf.h b/Utilities/cmcurl/lib/curl_printf.h
new file mode 100644
index 0000000..086923f
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_printf.h
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_PRINTF_H
+#define HEADER_CURL_PRINTF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * This header should be included by ALL code in libcurl that uses any
+ * *rintf() functions.
+ */
+
+#include <curl/mprintf.h>
+
+# undef printf
+# undef fprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+# define printf curl_mprintf
+# define fprintf curl_mfprintf
+# define snprintf curl_msnprintf
+# define vprintf curl_mvprintf
+# define vfprintf curl_mvfprintf
+# define vsnprintf curl_mvsnprintf
+# define aprintf curl_maprintf
+# define vaprintf curl_mvaprintf
+
+/* We define away the sprintf functions unconditonally since we don't want
+   internal code to be using them, intentionally or by mistake!*/
+# undef sprintf
+# undef vsprintf
+# define sprintf sprintf_was_used
+# define vsprintf vsprintf_was_used
+
+#endif /* HEADER_CURL_PRINTF_H */
diff --git a/Utilities/cmcurl/lib/curl_rtmp.c b/Utilities/cmcurl/lib/curl_rtmp.c
index e0c24b0..2938972 100644
--- a/Utilities/cmcurl/lib/curl_rtmp.c
+++ b/Utilities/cmcurl/lib/curl_rtmp.c
@@ -5,7 +5,7 @@
  *                | (__| |_| |  _ <| |___
  *                 \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  * Copyright (C) 2010, Howard Chu, <hyc at highlandsun.com>
  *
  * This software is licensed as described in the file COPYING, which
@@ -32,10 +32,6 @@
 #include "warnless.h"
 #include <curl/curl.h>
 #include <librtmp/rtmp.h>
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -49,7 +45,7 @@
 
 #define DEF_BUFTIME    (2*60*60*1000)    /* 2 hours */
 
-static CURLcode rtmp_setup(struct connectdata *conn);
+static CURLcode rtmp_setup_connection(struct connectdata *conn);
 static CURLcode rtmp_do(struct connectdata *conn, bool *done);
 static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
 static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
@@ -64,7 +60,7 @@ static Curl_send rtmp_send;
 
 const struct Curl_handler Curl_handler_rtmp = {
   "RTMP",                               /* scheme */
-  rtmp_setup,                           /* setup_connection */
+  rtmp_setup_connection,                /* setup_connection */
   rtmp_do,                              /* do_it */
   rtmp_done,                            /* done */
   ZERO_NULL,                            /* do_more */
@@ -84,7 +80,7 @@ const struct Curl_handler Curl_handler_rtmp = {
 
 const struct Curl_handler Curl_handler_rtmpt = {
   "RTMPT",                              /* scheme */
-  rtmp_setup,                           /* setup_connection */
+  rtmp_setup_connection,                /* setup_connection */
   rtmp_do,                              /* do_it */
   rtmp_done,                            /* done */
   ZERO_NULL,                            /* do_more */
@@ -104,7 +100,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
 
 const struct Curl_handler Curl_handler_rtmpe = {
   "RTMPE",                              /* scheme */
-  rtmp_setup,                           /* setup_connection */
+  rtmp_setup_connection,                /* setup_connection */
   rtmp_do,                              /* do_it */
   rtmp_done,                            /* done */
   ZERO_NULL,                            /* do_more */
@@ -124,7 +120,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
 
 const struct Curl_handler Curl_handler_rtmpte = {
   "RTMPTE",                             /* scheme */
-  rtmp_setup,                           /* setup_connection */
+  rtmp_setup_connection,                /* setup_connection */
   rtmp_do,                              /* do_it */
   rtmp_done,                            /* done */
   ZERO_NULL,                            /* do_more */
@@ -144,7 +140,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
 
 const struct Curl_handler Curl_handler_rtmps = {
   "RTMPS",                              /* scheme */
-  rtmp_setup,                           /* setup_connection */
+  rtmp_setup_connection,                /* setup_connection */
   rtmp_do,                              /* do_it */
   rtmp_done,                            /* done */
   ZERO_NULL,                            /* do_more */
@@ -164,7 +160,7 @@ const struct Curl_handler Curl_handler_rtmps = {
 
 const struct Curl_handler Curl_handler_rtmpts = {
   "RTMPTS",                             /* scheme */
-  rtmp_setup,                           /* setup_connection */
+  rtmp_setup_connection,                /* setup_connection */
   rtmp_do,                              /* do_it */
   rtmp_done,                            /* done */
   ZERO_NULL,                            /* do_more */
@@ -182,10 +178,9 @@ const struct Curl_handler Curl_handler_rtmpts = {
   PROTOPT_NONE                          /* flags*/
 };
 
-static CURLcode rtmp_setup(struct connectdata *conn)
+static CURLcode rtmp_setup_connection(struct connectdata *conn)
 {
   RTMP *r = RTMP_Alloc();
-
   if(!r)
     return CURLE_OUT_OF_MEMORY;
 
@@ -202,7 +197,7 @@ static CURLcode rtmp_setup(struct connectdata *conn)
 static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
 {
   RTMP *r = conn->proto.generic;
-  SET_RCVTIMEO(tv,10);
+  SET_RCVTIMEO(tv, 10);
 
   r->m_sb.sb_socket = conn->sock[FIRSTSOCKET];
 
@@ -217,7 +212,7 @@ static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
      !(r->Link.protocol & RTMP_FEATURE_HTTP))
     r->Link.lFlags |= RTMP_LF_BUFX;
 
-  curlx_nonblock(r->m_sb.sb_socket, FALSE);
+  (void)curlx_nonblock(r->m_sb.sb_socket, FALSE);
   setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
              (char *)&tv, sizeof(tv));
 
diff --git a/Utilities/cmcurl/lib/curl_sasl.c b/Utilities/cmcurl/lib/curl_sasl.c
index 7e2b8af..68646bc 100644
--- a/Utilities/cmcurl/lib/curl_sasl.c
+++ b/Utilities/cmcurl/lib/curl_sasl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -19,6 +19,7 @@
  * KIND, either express or implied.
  *
  * RFC2195 CRAM-MD5 authentication
+ * RFC2617 Basic and Digest Access Authentication
  * RFC2831 DIGEST-MD5 authentication
  * RFC4422 Simple Authentication and Security Layer (SASL)
  * RFC4616 PLAIN authentication
@@ -36,26 +37,35 @@
 #include "curl_md5.h"
 #include "vtls/vtls.h"
 #include "curl_hmac.h"
-#include "curl_ntlm_msgs.h"
 #include "curl_sasl.h"
 #include "warnless.h"
-#include "curl_memory.h"
 #include "strtok.h"
+#include "strequal.h"
 #include "rawstr.h"
+#include "sendf.h"
+#include "non-ascii.h" /* included for Curl_convert_... prototypes */
+#include "curl_printf.h"
 
-#ifdef USE_NSS
-#include "vtls/nssg.h" /* for Curl_nss_force_init() */
-#endif
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
-#if defined(USE_WINDOWS_SSPI)
-extern void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
-#endif
+/* Supported mechanisms */
+const struct {
+  const char   *name;  /* Name */
+  size_t        len;   /* Name length */
+  unsigned int  bit;   /* Flag bit */
+} mechtable[] = {
+  { "LOGIN",      5,  SASL_MECH_LOGIN },
+  { "PLAIN",      5,  SASL_MECH_PLAIN },
+  { "CRAM-MD5",   8,  SASL_MECH_CRAM_MD5 },
+  { "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 },
+  { "GSSAPI",     6,  SASL_MECH_GSSAPI },
+  { "EXTERNAL",   8,  SASL_MECH_EXTERNAL },
+  { "NTLM",       4,  SASL_MECH_NTLM },
+  { "XOAUTH2",    7,  SASL_MECH_XOAUTH2 },
+  { ZERO_NULL,    0,  0 }
+};
 
 #if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
 #define DIGEST_QOP_VALUE_AUTH             (1 << 0)
@@ -66,6 +76,131 @@ extern void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
 #define DIGEST_QOP_VALUE_STRING_AUTH_INT  "auth-int"
 #define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf"
 
+/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
+   It converts digest text to ASCII so the MD5 will be correct for
+   what ultimately goes over the network.
+*/
+#define CURL_OUTPUT_DIGEST_CONV(a, b) \
+  result = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
+  if(result) { \
+    free(b); \
+    return result; \
+  }
+
+#endif
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+/*
+ * Returns 0 on success and then the buffers are filled in fine.
+ *
+ * Non-zero means failure to parse.
+ */
+int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
+                              const char **endptr)
+{
+  int c;
+  bool starts_with_quote = FALSE;
+  bool escape = FALSE;
+
+  for(c = DIGEST_MAX_VALUE_LENGTH - 1; (*str && (*str != '=') && c--); )
+    *value++ = *str++;
+  *value = 0;
+
+  if('=' != *str++)
+    /* eek, no match */
+    return 1;
+
+  if('\"' == *str) {
+    /* this starts with a quote so it must end with one as well! */
+    str++;
+    starts_with_quote = TRUE;
+  }
+
+  for(c = DIGEST_MAX_CONTENT_LENGTH - 1; *str && c--; str++) {
+    switch(*str) {
+    case '\\':
+      if(!escape) {
+        /* possibly the start of an escaped quote */
+        escape = TRUE;
+        *content++ = '\\'; /* even though this is an escape character, we still
+                              store it as-is in the target buffer */
+        continue;
+      }
+      break;
+    case ',':
+      if(!starts_with_quote) {
+        /* this signals the end of the content if we didn't get a starting
+           quote and then we do "sloppy" parsing */
+        c = 0; /* the end */
+        continue;
+      }
+      break;
+    case '\r':
+    case '\n':
+      /* end of string */
+      c = 0;
+      continue;
+    case '\"':
+      if(!escape && starts_with_quote) {
+        /* end of string */
+        c = 0;
+        continue;
+      }
+      break;
+    }
+    escape = FALSE;
+    *content++ = *str;
+  }
+  *content = 0;
+
+  *endptr = str;
+
+  return 0; /* all is fine! */
+}
+#endif
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
+/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
+static void sasl_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */
+                                     unsigned char *dest) /* 33 bytes */
+{
+  int i;
+  for(i = 0; i < 16; i++)
+    snprintf((char *)&dest[i*2], 3, "%02x", source[i]);
+}
+
+/* Perform quoted-string escaping as described in RFC2616 and its errata */
+static char *sasl_digest_string_quoted(const char *source)
+{
+  char *dest, *d;
+  const char *s = source;
+  size_t n = 1; /* null terminator */
+
+  /* Calculate size needed */
+  while(*s) {
+    ++n;
+    if(*s == '"' || *s == '\\') {
+      ++n;
+    }
+    ++s;
+  }
+
+  dest = malloc(n);
+  if(dest) {
+    s = source;
+    d = dest;
+    while(*s) {
+      if(*s == '"' || *s == '\\') {
+        *d++ = '\\';
+      }
+      *d++ = *s++;
+    }
+    *d = 0;
+  }
+
+  return dest;
+}
+
 /* Retrieves the value for a corresponding key from the challenge string
  * returns TRUE if the key could be found, FALSE if it does not exists
  */
@@ -118,11 +253,11 @@ static CURLcode sasl_digest_get_qop_values(const char *options, int *value)
     token = strtok_r(NULL, ",", &tok_buf);
   }
 
-  Curl_safefree(tmp);
+  free(tmp);
 
   return CURLE_OK;
 }
-#endif
+#endif /* !CURL_DISABLE_CRYPTO_AUTH && !USE_WINDOWS_SSPI */
 
 #if !defined(USE_WINDOWS_SSPI)
 /*
@@ -132,8 +267,8 @@ static CURLcode sasl_digest_get_qop_values(const char *options, int *value)
  *
  * Parameters:
  *
- * serivce  [in] - The service type such as www, smtp, pop or imap.
- * instance [in] - The instance name such as the host nme or realm.
+ * service  [in] - The service type such as www, smtp, pop or imap.
+ * host     [in] - The host name or realm.
  *
  * Returns a pointer to the newly allocated SPN.
  */
@@ -145,7 +280,7 @@ char *Curl_sasl_build_spn(const char *service, const char *host)
 #endif
 
 /*
- * Curl_sasl_create_plain_message()
+ * sasl_create_plain_message()
  *
  * This is used to generate an already encoded PLAIN message ready
  * for sending to the recipient.
@@ -161,10 +296,10 @@ char *Curl_sasl_build_spn(const char *service, const char *host)
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
-                                        const char *userp,
-                                        const char *passwdp,
-                                        char **outptr, size_t *outlen)
+static CURLcode sasl_create_plain_message(struct SessionHandle *data,
+                                          const char *userp,
+                                          const char *passwdp,
+                                          char **outptr, size_t *outlen)
 {
   CURLcode result;
   char *plainauth;
@@ -191,12 +326,12 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
   /* Base64 encode the reply */
   result = Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr,
                               outlen);
-  Curl_safefree(plainauth);
+  free(plainauth);
   return result;
 }
 
 /*
- * Curl_sasl_create_login_message()
+ * sasl_create_login_message()
  *
  * This is used to generate an already encoded LOGIN message containing the
  * user name or password ready for sending to the recipient.
@@ -211,9 +346,9 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
-                                        const char *valuep, char **outptr,
-                                        size_t *outlen)
+static CURLcode sasl_create_login_message(struct SessionHandle *data,
+                                          const char *valuep, char **outptr,
+                                          size_t *outlen)
 {
   size_t vlen = strlen(valuep);
 
@@ -233,23 +368,47 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
   return Curl_base64_encode(data, valuep, vlen, outptr, outlen);
 }
 
+/*
+ * sasl_create_external_message()
+ *
+ * This is used to generate an already encoded EXTERNAL message containing
+ * the user name ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * user    [in]     - The user name.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_external_message(struct SessionHandle *data,
+                                             const char *user, char **outptr,
+                                             size_t *outlen)
+{
+  /* This is the same formatting as the login message. */
+  return sasl_create_login_message(data, user, outptr, outlen);
+}
+
 #ifndef CURL_DISABLE_CRYPTO_AUTH
  /*
- * Curl_sasl_decode_cram_md5_message()
+ * sasl_decode_cram_md5_message()
  *
  * This is used to decode an already encoded CRAM-MD5 challenge message.
  *
  * Parameters:
  *
- * chlg64  [in]     - Pointer to the base64 encoded challenge message.
+ * chlg64  [in]     - The base64 encoded challenge message.
  * outptr  [in/out] - The address where a pointer to newly allocated memory
  *                    holding the result will be stored upon completion.
  * outlen  [out]    - The length of the output message.
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
-                                           size_t *outlen)
+static CURLcode sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
+                                             size_t *outlen)
 {
   CURLcode result = CURLE_OK;
   size_t chlg64len = strlen(chlg64);
@@ -265,7 +424,7 @@ CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
  }
 
  /*
- * Curl_sasl_create_cram_md5_message()
+ * sasl_create_cram_md5_message()
  *
  * This is used to generate an already encoded CRAM-MD5 response message ready
  * for sending to the recipient.
@@ -282,11 +441,11 @@ CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
-                                           const char *chlg,
-                                           const char *userp,
-                                           const char *passwdp,
-                                           char **outptr, size_t *outlen)
+static CURLcode sasl_create_cram_md5_message(struct SessionHandle *data,
+                                             const char *chlg,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             char **outptr, size_t *outlen)
 {
   CURLcode result = CURLE_OK;
   size_t chlglen = 0;
@@ -324,7 +483,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
   /* Base64 encode the response */
   result = Curl_base64_encode(data, response, 0, outptr, outlen);
 
-  Curl_safefree(response);
+  free(response);
 
   return result;
 }
@@ -338,7 +497,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
  *
  * Parameters:
  *
- * chlg64  [in]     - Pointer to the base64 encoded challenge message.
+ * chlg64  [in]     - The base64 encoded challenge message.
  * nonce   [in/out] - The buffer where the nonce will be stored.
  * nlen    [in]     - The length of the nonce buffer.
  * realm   [in/out] - The buffer where the realm will be stored.
@@ -374,7 +533,7 @@ static CURLcode sasl_decode_digest_md5_message(const char *chlg64,
 
   /* Retrieve nonce string from the challenge */
   if(!sasl_digest_get_key_value((char *)chlg, "nonce=\"", nonce, nlen, '\"')) {
-    Curl_safefree(chlg);
+    free(chlg);
     return CURLE_BAD_CONTENT_ENCODING;
   }
 
@@ -386,17 +545,17 @@ static CURLcode sasl_decode_digest_md5_message(const char *chlg64,
 
   /* Retrieve algorithm string from the challenge */
   if(!sasl_digest_get_key_value((char *)chlg, "algorithm=", alg, alen, ',')) {
-    Curl_safefree(chlg);
+    free(chlg);
     return CURLE_BAD_CONTENT_ENCODING;
   }
 
   /* Retrieve qop-options string from the challenge */
   if(!sasl_digest_get_key_value((char *)chlg, "qop=\"", qop, qlen, '\"')) {
-    Curl_safefree(chlg);
+    free(chlg);
     return CURLE_BAD_CONTENT_ENCODING;
   }
 
-  Curl_safefree(chlg);
+  free(chlg);
 
   return CURLE_OK;
 }
@@ -410,7 +569,7 @@ static CURLcode sasl_decode_digest_md5_message(const char *chlg64,
  * Parameters:
  *
  * data    [in]     - The session handle.
- * chlg64  [in]     - Pointer to the base64 encoded challenge message.
+ * chlg64  [in]     - The base64 encoded challenge message.
  * userp   [in]     - The user name.
  * passdwp [in]     - The user's password.
  * service [in]     - The service type such as www, smtp, pop or imap.
@@ -518,7 +677,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
   /* Calculate H(A2) */
   ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
   if(!ctxt) {
-    Curl_safefree(spn);
+    free(spn);
 
     return CURLE_OUT_OF_MEMORY;
   }
@@ -536,7 +695,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
   /* Now calculate the response hash */
   ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
   if(!ctxt) {
-    Curl_safefree(spn);
+    free(spn);
 
     return CURLE_OUT_OF_MEMORY;
   }
@@ -569,110 +728,432 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
                      "qop=%s",
                      userp, realm, nonce,
                      cnonce, nonceCount, spn, resp_hash_hex, qop);
-  Curl_safefree(spn);
+  free(spn);
   if(!response)
     return CURLE_OUT_OF_MEMORY;
 
   /* Base64 encode the response */
   result = Curl_base64_encode(data, response, 0, outptr, outlen);
 
-  Curl_safefree(response);
+  free(response);
 
   return result;
 }
-#endif  /* !USE_WINDOWS_SSPI */
 
-#endif  /* CURL_DISABLE_CRYPTO_AUTH */
-
-#ifdef USE_NTLM
 /*
- * Curl_sasl_create_ntlm_type1_message()
+ * Curl_sasl_decode_digest_http_message()
  *
- * This is used to generate an already encoded NTLM type-1 message ready for
- * sending to the recipient.
+ * This is used to decode a HTTP DIGEST challenge message into the seperate
+ * attributes.
  *
- * Note: This is a simple wrapper of the NTLM function which means that any
- * SASL based protocols don't have to include the NTLM functions directly.
+ * Parameters:
+ *
+ * chlg    [in]     - The challenge message.
+ * digest  [in/out] - The digest data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
+                                              struct digestdata *digest)
+{
+  bool before = FALSE; /* got a nonce before */
+  bool foundAuth = FALSE;
+  bool foundAuthInt = FALSE;
+  char *token = NULL;
+  char *tmp = NULL;
+
+  /* If we already have received a nonce, keep that in mind */
+  if(digest->nonce)
+    before = TRUE;
+
+  /* Clean up any former leftovers and initialise to defaults */
+  Curl_sasl_digest_cleanup(digest);
+
+  for(;;) {
+    char value[DIGEST_MAX_VALUE_LENGTH];
+    char content[DIGEST_MAX_CONTENT_LENGTH];
+
+    /* Pass all additional spaces here */
+    while(*chlg && ISSPACE(*chlg))
+      chlg++;
+
+    /* Extract a value=content pair */
+    if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
+      if(Curl_raw_equal(value, "nonce")) {
+        digest->nonce = strdup(content);
+        if(!digest->nonce)
+          return CURLE_OUT_OF_MEMORY;
+      }
+      else if(Curl_raw_equal(value, "stale")) {
+        if(Curl_raw_equal(content, "true")) {
+          digest->stale = TRUE;
+          digest->nc = 1; /* we make a new nonce now */
+        }
+      }
+      else if(Curl_raw_equal(value, "realm")) {
+        digest->realm = strdup(content);
+        if(!digest->realm)
+          return CURLE_OUT_OF_MEMORY;
+      }
+      else if(Curl_raw_equal(value, "opaque")) {
+        digest->opaque = strdup(content);
+        if(!digest->opaque)
+          return CURLE_OUT_OF_MEMORY;
+      }
+      else if(Curl_raw_equal(value, "qop")) {
+        char *tok_buf;
+        /* Tokenize the list and choose auth if possible, use a temporary
+            clone of the buffer since strtok_r() ruins it */
+        tmp = strdup(content);
+        if(!tmp)
+          return CURLE_OUT_OF_MEMORY;
+
+        token = strtok_r(tmp, ",", &tok_buf);
+        while(token != NULL) {
+          if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
+            foundAuth = TRUE;
+          }
+          else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
+            foundAuthInt = TRUE;
+          }
+          token = strtok_r(NULL, ",", &tok_buf);
+        }
+
+        free(tmp);
+
+        /* Select only auth or auth-int. Otherwise, ignore */
+        if(foundAuth) {
+          digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH);
+          if(!digest->qop)
+            return CURLE_OUT_OF_MEMORY;
+        }
+        else if(foundAuthInt) {
+          digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH_INT);
+          if(!digest->qop)
+            return CURLE_OUT_OF_MEMORY;
+        }
+      }
+      else if(Curl_raw_equal(value, "algorithm")) {
+        digest->algorithm = strdup(content);
+        if(!digest->algorithm)
+          return CURLE_OUT_OF_MEMORY;
+
+        if(Curl_raw_equal(content, "MD5-sess"))
+          digest->algo = CURLDIGESTALGO_MD5SESS;
+        else if(Curl_raw_equal(content, "MD5"))
+          digest->algo = CURLDIGESTALGO_MD5;
+        else
+          return CURLE_BAD_CONTENT_ENCODING;
+      }
+      else {
+        /* unknown specifier, ignore it! */
+      }
+    }
+    else
+      break; /* we're done here */
+
+    /* Pass all additional spaces here */
+    while(*chlg && ISSPACE(*chlg))
+      chlg++;
+
+    /* Allow the list to be comma-separated */
+    if(',' == *chlg)
+      chlg++;
+  }
+
+  /* We had a nonce since before, and we got another one now without
+     'stale=true'. This means we provided bad credentials in the previous
+     request */
+  if(before && !digest->stale)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* We got this header without a nonce, that's a bad Digest line! */
+  if(!digest->nonce)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_create_digest_http_message()
+ *
+ * This is used to generate a HTTP DIGEST response message ready for sending
+ * to the recipient.
  *
  * Parameters:
  *
- * userp   [in]     - The user name in the format User or Domain\User.
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name.
  * passdwp [in]     - The user's password.
- * ntlm    [in/out] - The ntlm data struct being used and modified.
+ * request [in]     - The HTTP request.
+ * uripath [in]     - The path of the HTTP uri.
+ * digest  [in/out] - The digest data struct being used and modified.
  * outptr  [in/out] - The address where a pointer to newly allocated memory
  *                    holding the result will be stored upon completion.
  * outlen  [out]    - The length of the output message.
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
-                                             const char *passwdp,
-                                             struct ntlmdata *ntlm,
-                                             char **outptr, size_t *outlen)
+CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const unsigned char *request,
+                                              const unsigned char *uripath,
+                                              struct digestdata *digest,
+                                              char **outptr, size_t *outlen)
 {
-  return Curl_ntlm_create_type1_message(userp, passwdp, ntlm, outptr, outlen);
+  CURLcode result;
+  unsigned char md5buf[16]; /* 16 bytes/128 bits */
+  unsigned char request_digest[33];
+  unsigned char *md5this;
+  unsigned char ha1[33];/* 32 digits and 1 zero byte */
+  unsigned char ha2[33];/* 32 digits and 1 zero byte */
+  char cnoncebuf[33];
+  char *cnonce = NULL;
+  size_t cnonce_sz = 0;
+  char *userp_quoted;
+  char *response = NULL;
+  char *tmp = NULL;
+
+  if(!digest->nc)
+    digest->nc = 1;
+
+  if(!digest->cnonce) {
+    snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
+             Curl_rand(data), Curl_rand(data),
+             Curl_rand(data), Curl_rand(data));
+
+    result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
+                                &cnonce, &cnonce_sz);
+    if(result)
+      return result;
+
+    digest->cnonce = cnonce;
+  }
+
+  /*
+    if the algorithm is "MD5" or unspecified (which then defaults to MD5):
+
+    A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+
+    if the algorithm is "MD5-sess" then:
+
+    A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
+         ":" unq(nonce-value) ":" unq(cnonce-value)
+  */
+
+  md5this = (unsigned char *)
+    aprintf("%s:%s:%s", userp, digest->realm, passwdp);
+  if(!md5this)
+    return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
+  Curl_md5it(md5buf, md5this);
+  free(md5this);
+  sasl_digest_md5_to_ascii(md5buf, ha1);
+
+  if(digest->algo == CURLDIGESTALGO_MD5SESS) {
+    /* nonce and cnonce are OUTSIDE the hash */
+    tmp = aprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
+    Curl_md5it(md5buf, (unsigned char *)tmp);
+    free(tmp);
+    sasl_digest_md5_to_ascii(md5buf, ha1);
+  }
+
+  /*
+    If the "qop" directive's value is "auth" or is unspecified, then A2 is:
+
+      A2       = Method ":" digest-uri-value
+
+          If the "qop" value is "auth-int", then A2 is:
+
+      A2       = Method ":" digest-uri-value ":" H(entity-body)
+
+    (The "Method" value is the HTTP request method as specified in section
+    5.1.1 of RFC 2616)
+  */
+
+  md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
+
+  if(digest->qop && Curl_raw_equal(digest->qop, "auth-int")) {
+    /* We don't support auth-int for PUT or POST at the moment.
+       TODO: replace md5 of empty string with entity-body for PUT/POST */
+    unsigned char *md5this2 = (unsigned char *)
+      aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e");
+    free(md5this);
+    md5this = md5this2;
+  }
+
+  if(!md5this)
+    return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
+  Curl_md5it(md5buf, md5this);
+  free(md5this);
+  sasl_digest_md5_to_ascii(md5buf, ha2);
+
+  if(digest->qop) {
+    md5this = (unsigned char *)aprintf("%s:%s:%08x:%s:%s:%s",
+                                       ha1,
+                                       digest->nonce,
+                                       digest->nc,
+                                       digest->cnonce,
+                                       digest->qop,
+                                       ha2);
+  }
+  else {
+    md5this = (unsigned char *)aprintf("%s:%s:%s",
+                                       ha1,
+                                       digest->nonce,
+                                       ha2);
+  }
+
+  if(!md5this)
+    return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
+  Curl_md5it(md5buf, md5this);
+  free(md5this);
+  sasl_digest_md5_to_ascii(md5buf, request_digest);
+
+  /* for test case 64 (snooped from a Mozilla 1.3a request)
+
+    Authorization: Digest username="testuser", realm="testrealm", \
+    nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
+
+    Digest parameters are all quoted strings.  Username which is provided by
+    the user will need double quotes and backslashes within it escaped.  For
+    the other fields, this shouldn't be an issue.  realm, nonce, and opaque
+    are copied as is from the server, escapes and all.  cnonce is generated
+    with web-safe characters.  uri is already percent encoded.  nc is 8 hex
+    characters.  algorithm and qop with standard values only contain web-safe
+    chracters.
+  */
+  userp_quoted = sasl_digest_string_quoted(userp);
+  if(!userp_quoted)
+    return CURLE_OUT_OF_MEMORY;
+
+  if(digest->qop) {
+    response = aprintf("username=\"%s\", "
+                       "realm=\"%s\", "
+                       "nonce=\"%s\", "
+                       "uri=\"%s\", "
+                       "cnonce=\"%s\", "
+                       "nc=%08x, "
+                       "qop=%s, "
+                       "response=\"%s\"",
+                       userp_quoted,
+                       digest->realm,
+                       digest->nonce,
+                       uripath,
+                       digest->cnonce,
+                       digest->nc,
+                       digest->qop,
+                       request_digest);
+
+    if(Curl_raw_equal(digest->qop, "auth"))
+      digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0
+                       padded which tells to the server how many times you are
+                       using the same nonce in the qop=auth mode */
+  }
+  else {
+    response = aprintf("username=\"%s\", "
+                       "realm=\"%s\", "
+                       "nonce=\"%s\", "
+                       "uri=\"%s\", "
+                       "response=\"%s\"",
+                       userp_quoted,
+                       digest->realm,
+                       digest->nonce,
+                       uripath,
+                       request_digest);
+  }
+  free(userp_quoted);
+  if(!response)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Add the optional fields */
+  if(digest->opaque) {
+    /* Append the opaque */
+    tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque);
+    free(response);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    response = tmp;
+  }
+
+  if(digest->algorithm) {
+    /* Append the algorithm */
+    tmp = aprintf("%s, algorithm=\"%s\"", response, digest->algorithm);
+    free(response);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    response = tmp;
+  }
+
+  /* Return the output */
+  *outptr = response;
+  *outlen = strlen(response);
+
+  return CURLE_OK;
 }
 
 /*
- * Curl_sasl_decode_ntlm_type2_message()
+ * Curl_sasl_digest_cleanup()
  *
- * This is used to decode an already encoded NTLM type-2 message.
+ * This is used to clean up the digest specific data.
  *
  * Parameters:
  *
- * data     [in]     - Pointer to session handle.
- * type2msg [in]     - Pointer to the base64 encoded type-2 message.
- * ntlm     [in/out] - The ntlm data struct being used and modified.
+ * digest    [in/out] - The digest data struct being cleaned up.
  *
- * Returns CURLE_OK on success.
  */
-CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
-                                             const char *type2msg,
-                                             struct ntlmdata *ntlm)
+void Curl_sasl_digest_cleanup(struct digestdata *digest)
 {
-#ifdef USE_NSS
-  CURLcode result;
-
-  /* make sure the crypto backend is initialized */
-  result = Curl_nss_force_init(data);
-  if(result)
-    return result;
-#endif
-
-  return Curl_ntlm_decode_type2_message(data, type2msg, ntlm);
+  Curl_safefree(digest->nonce);
+  Curl_safefree(digest->cnonce);
+  Curl_safefree(digest->realm);
+  Curl_safefree(digest->opaque);
+  Curl_safefree(digest->qop);
+  Curl_safefree(digest->algorithm);
+
+  digest->nc = 0;
+  digest->algo = CURLDIGESTALGO_MD5; /* default algorithm */
+  digest->stale = FALSE; /* default means normal, not stale */
 }
+#endif  /* !USE_WINDOWS_SSPI */
+
+#endif  /* CURL_DISABLE_CRYPTO_AUTH */
 
+#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
 /*
- * Curl_sasl_create_ntlm_type3_message()
+ * Curl_sasl_ntlm_cleanup()
  *
- * This is used to generate an already encoded NTLM type-3 message ready for
- * sending to the recipient.
+ * This is used to clean up the ntlm specific data.
  *
  * Parameters:
  *
- * data    [in]     - Pointer to session handle.
- * userp   [in]     - The user name in the format User or Domain\User.
- * passdwp [in]     - The user's password.
- * ntlm    [in/out] - The ntlm data struct being used and modified.
- * outptr  [in/out] - The address where a pointer to newly allocated memory
- *                    holding the result will be stored upon completion.
- * outlen  [out]    - The length of the output message.
+ * ntlm    [in/out] - The ntlm data struct being cleaned up.
  *
- * Returns CURLE_OK on success.
  */
-CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
-                                             const char *userp,
-                                             const char *passwdp,
-                                             struct ntlmdata *ntlm,
-                                             char **outptr, size_t *outlen)
+void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm)
 {
-  return Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm, outptr,
-                                        outlen);
+  /* Free the target info */
+  Curl_safefree(ntlm->target_info);
+
+  /* Reset any variables */
+  ntlm->target_info_len = 0;
 }
-#endif /* USE_NTLM */
+#endif /* USE_NTLM && !USE_WINDOWS_SSPI*/
 
 /*
- * Curl_sasl_create_xoauth2_message()
+ * sasl_create_xoauth2_message()
  *
  * This is used to generate an already encoded OAuth 2.0 message ready for
  * sending to the recipient.
@@ -688,10 +1169,10 @@ CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
  *
  * Returns CURLE_OK on success.
  */
-CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
-                                          const char *user,
-                                          const char *bearer,
-                                          char **outptr, size_t *outlen)
+static CURLcode sasl_create_xoauth2_message(struct SessionHandle *data,
+                                            const char *user,
+                                            const char *bearer,
+                                            char **outptr, size_t *outlen)
 {
   CURLcode result = CURLE_OK;
   char *xoauth = NULL;
@@ -704,7 +1185,7 @@ CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
   /* Base64 encode the reply */
   result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen);
 
-  Curl_safefree(xoauth);
+  free(xoauth);
 
   return result;
 }
@@ -717,25 +1198,472 @@ CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
  *
  * Parameters:
  *
- * conn     [in]     - Pointer to the connection data.
+ * conn     [in]     - The connection data.
  * authused [in]     - The authentication mechanism used.
  */
 void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
 {
-#if defined(USE_WINDOWS_SSPI)
+#if defined(USE_KERBEROS5)
   /* Cleanup the gssapi structure */
   if(authused == SASL_MECH_GSSAPI) {
     Curl_sasl_gssapi_cleanup(&conn->krb5);
   }
-#ifdef USE_NTLM
+#endif
+
+#if defined(USE_NTLM)
   /* Cleanup the ntlm structure */
-  else if(authused == SASL_MECH_NTLM) {
-    Curl_ntlm_sspi_cleanup(&conn->ntlm);
+  if(authused == SASL_MECH_NTLM) {
+    Curl_sasl_ntlm_cleanup(&conn->ntlm);
   }
 #endif
-#else
+
+#if !defined(USE_KERBEROS5) && !defined(USE_NTLM)
   /* Reserved for future use */
   (void)conn;
   (void)authused;
 #endif
 }
+
+/*
+ * Curl_sasl_decode_mech()
+ *
+ * Convert a SASL mechanism name into a token.
+ *
+ * Parameters:
+ *
+ * ptr    [in]     - The mechanism string.
+ * maxlen [in]     - Maximum mechanism string length.
+ * len    [out]    - If not NULL, effective name length.
+ *
+ * Returns the SASL mechanism token or 0 if no match.
+ */
+unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len)
+{
+  unsigned int i;
+  char c;
+
+  for(i = 0; mechtable[i].name; i++) {
+    if(maxlen >= mechtable[i].len &&
+       !memcmp(ptr, mechtable[i].name, mechtable[i].len)) {
+      if(len)
+        *len = mechtable[i].len;
+
+      if(maxlen == mechtable[i].len)
+        return mechtable[i].bit;
+
+      c = ptr[mechtable[i].len];
+      if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_')
+        return mechtable[i].bit;
+    }
+  }
+
+  return 0;
+}
+
+/*
+ * Curl_sasl_parse_url_auth_option()
+ *
+ * Parse the URL login options.
+ */
+CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
+                                         const char *value, size_t len)
+{
+  CURLcode result = CURLE_OK;
+  unsigned int mechbit;
+  size_t mechlen;
+
+  if(!len)
+    return CURLE_URL_MALFORMAT;
+
+    if(sasl->resetprefs) {
+      sasl->resetprefs = FALSE;
+      sasl->prefmech = SASL_AUTH_NONE;
+    }
+
+    if(strnequal(value, "*", len))
+      sasl->prefmech = SASL_AUTH_DEFAULT;
+    else if((mechbit = Curl_sasl_decode_mech(value, len, &mechlen)) &&
+            mechlen == len)
+      sasl->prefmech |= mechbit;
+    else
+      result = CURLE_URL_MALFORMAT;
+
+  return result;
+}
+
+/*
+ * Curl_sasl_init()
+ *
+ * Initializes the SASL structure.
+ */
+void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params)
+{
+  sasl->params = params;           /* Set protocol dependent parameters */
+  sasl->state = SASL_STOP;         /* Not yet running */
+  sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */
+  sasl->prefmech = SASL_AUTH_DEFAULT; /* Prefer all mechanisms */
+  sasl->authused = SASL_AUTH_NONE; /* No the authentication mechanism used */
+  sasl->resetprefs = TRUE;         /* Reset prefmech upon AUTH parsing. */
+  sasl->mutual_auth = FALSE;       /* No mutual authentication (GSSAPI only) */
+  sasl->force_ir = FALSE;          /* Respect external option */
+}
+
+/*
+ * state()
+ *
+ * This is the ONLY way to change SASL state!
+ */
+static void state(struct SASL *sasl, struct connectdata *conn,
+                  saslstate newstate)
+{
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[]={
+    "STOP",
+    "PLAIN",
+    "LOGIN",
+    "LOGIN_PASSWD",
+    "EXTERNAL",
+    "CRAMMD5",
+    "DIGESTMD5",
+    "DIGESTMD5_RESP",
+    "NTLM",
+    "NTLM_TYPE2MSG",
+    "GSSAPI",
+    "GSSAPI_TOKEN",
+    "GSSAPI_NO_DATA",
+    "XOAUTH2",
+    "CANCEL",
+    "FINAL",
+    /* LAST */
+  };
+
+  if(sasl->state != newstate)
+    infof(conn->data, "SASL %p state change from %s to %s\n",
+          (void *)sasl, names[sasl->state], names[newstate]);
+#else
+  (void) conn;
+#endif
+
+  sasl->state = newstate;
+}
+
+/*
+ * Curl_sasl_can_authenticate()
+ *
+ * Check if we have enough auth data and capabilities to authenticate.
+ */
+bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn)
+{
+  /* Have credentials been provided? */
+  if(conn->bits.user_passwd)
+    return TRUE;
+
+  /* EXTERNAL can authenticate without a user name and/or password */
+  if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL)
+    return TRUE;
+
+  return FALSE;
+}
+
+/*
+ * Curl_sasl_start()
+ *
+ * Calculate the required login details for SASL authentication.
+ */
+CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
+                         bool force_ir, saslprogress *progress)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  unsigned int enabledmechs;
+  const char *mech = NULL;
+  char *resp = NULL;
+  size_t len = 0;
+  saslstate state1 = SASL_STOP;
+  saslstate state2 = SASL_FINAL;
+
+  sasl->force_ir = force_ir;    /* Latch for future use */
+  sasl->authused = 0;           /* No mechanism used yet */
+  enabledmechs = sasl->authmechs & sasl->prefmech;
+  *progress = SASL_IDLE;
+
+  /* Calculate the supported authentication mechanism, by decreasing order of
+     security, as well as the initial response where appropriate */
+  if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) {
+    mech = SASL_MECH_STRING_EXTERNAL;
+    state1 = SASL_EXTERNAL;
+    sasl->authused = SASL_MECH_EXTERNAL;
+
+    if(force_ir || data->set.sasl_ir)
+      result = sasl_create_external_message(data, conn->user, &resp, &len);
+  }
+  else if(conn->bits.user_passwd) {
+#if defined(USE_KERBEROS5)
+    if(enabledmechs & SASL_MECH_GSSAPI) {
+      sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
+      mech = SASL_MECH_STRING_GSSAPI;
+      state1 = SASL_GSSAPI;
+      state2 = SASL_GSSAPI_TOKEN;
+      sasl->authused = SASL_MECH_GSSAPI;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_sasl_create_gssapi_user_message(data, conn->user,
+                                                      conn->passwd,
+                                                      sasl->params->service,
+                                                      sasl->mutual_auth,
+                                                      NULL, &conn->krb5,
+                                                      &resp, &len);
+    }
+    else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+    if(enabledmechs & SASL_MECH_DIGEST_MD5) {
+      mech = SASL_MECH_STRING_DIGEST_MD5;
+      state1 = SASL_DIGESTMD5;
+      sasl->authused = SASL_MECH_DIGEST_MD5;
+    }
+    else if(enabledmechs & SASL_MECH_CRAM_MD5) {
+      mech = SASL_MECH_STRING_CRAM_MD5;
+      state1 = SASL_CRAMMD5;
+      sasl->authused = SASL_MECH_CRAM_MD5;
+    }
+    else
+#endif
+#ifdef USE_NTLM
+    if(enabledmechs & SASL_MECH_NTLM) {
+      mech = SASL_MECH_STRING_NTLM;
+      state1 = SASL_NTLM;
+      state2 = SASL_NTLM_TYPE2MSG;
+      sasl->authused = SASL_MECH_NTLM;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
+                                                     &conn->ntlm, &resp, &len);
+      }
+    else
+#endif
+    if((enabledmechs & SASL_MECH_XOAUTH2) || conn->xoauth2_bearer) {
+      mech = SASL_MECH_STRING_XOAUTH2;
+      state1 = SASL_XOAUTH2;
+      sasl->authused = SASL_MECH_XOAUTH2;
+
+      if(force_ir || data->set.sasl_ir)
+        result = sasl_create_xoauth2_message(data, conn->user,
+                                             conn->xoauth2_bearer,
+                                             &resp, &len);
+    }
+    else if(enabledmechs & SASL_MECH_LOGIN) {
+      mech = SASL_MECH_STRING_LOGIN;
+      state1 = SASL_LOGIN;
+      state2 = SASL_LOGIN_PASSWD;
+      sasl->authused = SASL_MECH_LOGIN;
+
+      if(force_ir || data->set.sasl_ir)
+        result = sasl_create_login_message(data, conn->user, &resp, &len);
+    }
+    else if(enabledmechs & SASL_MECH_PLAIN) {
+      mech = SASL_MECH_STRING_PLAIN;
+      state1 = SASL_PLAIN;
+      sasl->authused = SASL_MECH_PLAIN;
+
+      if(force_ir || data->set.sasl_ir)
+        result = sasl_create_plain_message(data, conn->user, conn->passwd,
+                                           &resp, &len);
+    }
+  }
+
+  if(!result) {
+    if(resp && sasl->params->maxirlen &&
+       strlen(mech) + len > sasl->params->maxirlen) {
+      free(resp);
+      resp = NULL;
+    }
+
+    if(mech) {
+      result = sasl->params->sendauth(conn, mech, resp);
+      if(!result) {
+        *progress = SASL_INPROGRESS;
+        state(sasl, conn, resp? state2: state1);
+      }
+    }
+  }
+
+  free(resp);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_continue()
+ *
+ * Continue the authentication.
+ */
+CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
+                            int code, saslprogress *progress)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  saslstate newstate = SASL_FINAL;
+  char *resp = NULL;
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+  char *serverdata;
+  char *chlg = NULL;
+  size_t chlglen = 0;
+#endif
+  size_t len = 0;
+
+  *progress = SASL_INPROGRESS;
+
+  if(sasl->state == SASL_FINAL) {
+    if(code != sasl->params->finalcode)
+      result = CURLE_LOGIN_DENIED;
+    *progress = SASL_DONE;
+    state(sasl, conn, SASL_STOP);
+    return result;
+  }
+
+  if(sasl->state != SASL_CANCEL && code != sasl->params->contcode) {
+    *progress = SASL_DONE;
+    state(sasl, conn, SASL_STOP);
+    return CURLE_LOGIN_DENIED;
+  }
+
+  switch(sasl->state) {
+  case SASL_STOP:
+    *progress = SASL_DONE;
+    return result;
+  case SASL_PLAIN:
+    result = sasl_create_plain_message(data, conn->user, conn->passwd, &resp,
+                                       &len);
+    break;
+  case SASL_LOGIN:
+    result = sasl_create_login_message(data, conn->user, &resp, &len);
+    newstate = SASL_LOGIN_PASSWD;
+    break;
+  case SASL_LOGIN_PASSWD:
+    result = sasl_create_login_message(data, conn->passwd, &resp, &len);
+    break;
+  case SASL_EXTERNAL:
+    result = sasl_create_external_message(data, conn->user, &resp, &len);
+    break;
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+  case SASL_CRAMMD5:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    result = sasl_decode_cram_md5_message(serverdata, &chlg, &chlglen);
+    if(!result)
+      result = sasl_create_cram_md5_message(data, chlg, conn->user,
+                                            conn->passwd, &resp, &len);
+    free(chlg);
+    break;
+  case SASL_DIGESTMD5:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    result = Curl_sasl_create_digest_md5_message(data, serverdata,
+                                                 conn->user, conn->passwd,
+                                                 sasl->params->service,
+                                                 &resp, &len);
+    newstate = SASL_DIGESTMD5_RESP;
+    break;
+  case SASL_DIGESTMD5_RESP:
+    if(!(resp = strdup("")))
+      result = CURLE_OUT_OF_MEMORY;
+    break;
+#endif
+
+#ifdef USE_NTLM
+  case SASL_NTLM:
+    /* Create the type-1 message */
+    result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
+                                                 &conn->ntlm, &resp, &len);
+    newstate = SASL_NTLM_TYPE2MSG;
+    break;
+  case SASL_NTLM_TYPE2MSG:
+    /* Decode the type-2 message */
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    result = Curl_sasl_decode_ntlm_type2_message(data, serverdata,
+                                                 &conn->ntlm);
+    if(!result)
+      result = Curl_sasl_create_ntlm_type3_message(data, conn->user,
+                                                   conn->passwd, &conn->ntlm,
+                                                   &resp, &len);
+    break;
+#endif
+
+#if defined(USE_KERBEROS5)
+  case SASL_GSSAPI:
+    result = Curl_sasl_create_gssapi_user_message(data, conn->user,
+                                                  conn->passwd,
+                                                  sasl->params->service,
+                                                  sasl->mutual_auth, NULL,
+                                                  &conn->krb5,
+                                                  &resp, &len);
+    newstate = SASL_GSSAPI_TOKEN;
+    break;
+  case SASL_GSSAPI_TOKEN:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    if(sasl->mutual_auth) {
+      /* Decode the user token challenge and create the optional response
+         message */
+      result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
+                                                    sasl->mutual_auth,
+                                                    serverdata, &conn->krb5,
+                                                    &resp, &len);
+      newstate = SASL_GSSAPI_NO_DATA;
+    }
+    else
+      /* Decode the security challenge and create the response message */
+      result = Curl_sasl_create_gssapi_security_message(data, serverdata,
+                                                        &conn->krb5,
+                                                        &resp, &len);
+    break;
+  case SASL_GSSAPI_NO_DATA:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    /* Decode the security challenge and create the response message */
+    result = Curl_sasl_create_gssapi_security_message(data, serverdata,
+                                                      &conn->krb5,
+                                                      &resp, &len);
+    break;
+#endif
+
+  case SASL_XOAUTH2:
+    /* Create the authorisation message */
+    result = sasl_create_xoauth2_message(data, conn->user,
+                                         conn->xoauth2_bearer, &resp, &len);
+    break;
+  case SASL_CANCEL:
+    /* Remove the offending mechanism from the supported list */
+    sasl->authmechs ^= sasl->authused;
+
+    /* Start an alternative SASL authentication */
+    result = Curl_sasl_start(sasl, conn, sasl->force_ir, progress);
+    newstate = sasl->state;   /* Use state from Curl_sasl_start() */
+    break;
+  default:
+    failf(data, "Unsupported SASL authentication mechanism");
+    result = CURLE_UNSUPPORTED_PROTOCOL;  /* Should not happen */
+    break;
+  }
+
+  switch(result) {
+  case CURLE_BAD_CONTENT_ENCODING:
+    /* Cancel dialog */
+    result = sasl->params->sendcont(conn, "*");
+    newstate = SASL_CANCEL;
+    break;
+  case CURLE_OK:
+    if(resp)
+      result = sasl->params->sendcont(conn, resp);
+    break;
+  default:
+    newstate = SASL_STOP;    /* Stop on error */
+    *progress = SASL_DONE;
+    break;
+  }
+
+  free(resp);
+
+  state(sasl, conn, newstate);
+
+  return result;
+}
diff --git a/Utilities/cmcurl/lib/curl_sasl.h b/Utilities/cmcurl/lib/curl_sasl.h
index e56fa1a..117d60e 100644
--- a/Utilities/cmcurl/lib/curl_sasl.h
+++ b/Utilities/cmcurl/lib/curl_sasl.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,16 +26,19 @@
 
 struct SessionHandle;
 struct connectdata;
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+struct digestdata;
+#endif
+
+#if defined(USE_NTLM)
 struct ntlmdata;
+#endif
 
-#if defined(USE_WINDOWS_SSPI)
+#if defined(USE_KERBEROS5)
 struct kerberos5data;
 #endif
 
-/* Authentication mechanism values */
-#define SASL_AUTH_NONE          0
-#define SASL_AUTH_ANY           ~0U
-
 /* Authentication mechanism flags */
 #define SASL_MECH_LOGIN             (1 << 0)
 #define SASL_MECH_PLAIN             (1 << 1)
@@ -46,6 +49,12 @@ struct kerberos5data;
 #define SASL_MECH_NTLM              (1 << 6)
 #define SASL_MECH_XOAUTH2           (1 << 7)
 
+/* Authentication mechanism values */
+#define SASL_AUTH_NONE          0
+#define SASL_AUTH_ANY           ~0U
+#define SASL_AUTH_DEFAULT       (SASL_AUTH_ANY & \
+                                 ~(SASL_MECH_EXTERNAL | SASL_MECH_XOAUTH2))
+
 /* Authentication mechanism strings */
 #define SASL_MECH_STRING_LOGIN      "LOGIN"
 #define SASL_MECH_STRING_PLAIN      "PLAIN"
@@ -56,6 +65,70 @@ struct kerberos5data;
 #define SASL_MECH_STRING_NTLM       "NTLM"
 #define SASL_MECH_STRING_XOAUTH2    "XOAUTH2"
 
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+#define DIGEST_MAX_VALUE_LENGTH           256
+#define DIGEST_MAX_CONTENT_LENGTH         1024
+#endif
+
+enum {
+  CURLDIGESTALGO_MD5,
+  CURLDIGESTALGO_MD5SESS
+};
+
+/* SASL machine states */
+typedef enum {
+  SASL_STOP,
+  SASL_PLAIN,
+  SASL_LOGIN,
+  SASL_LOGIN_PASSWD,
+  SASL_EXTERNAL,
+  SASL_CRAMMD5,
+  SASL_DIGESTMD5,
+  SASL_DIGESTMD5_RESP,
+  SASL_NTLM,
+  SASL_NTLM_TYPE2MSG,
+  SASL_GSSAPI,
+  SASL_GSSAPI_TOKEN,
+  SASL_GSSAPI_NO_DATA,
+  SASL_XOAUTH2,
+  SASL_CANCEL,
+  SASL_FINAL
+} saslstate;
+
+/* Progress indicator */
+typedef enum {
+  SASL_IDLE,
+  SASL_INPROGRESS,
+  SASL_DONE
+} saslprogress;
+
+/* Protocol dependent SASL parameters */
+struct SASLproto {
+  const char *service;     /* The service name */
+  int contcode;            /* Code to receive when continuation is expected */
+  int finalcode;           /* Code to receive upon authentication success */
+  size_t maxirlen;         /* Maximum initial response length */
+  CURLcode (*sendauth)(struct connectdata *conn,
+                       const char *mech, const char *ir);
+                           /* Send authentication command */
+  CURLcode (*sendcont)(struct connectdata *conn, const char *contauth);
+                           /* Send authentication continuation */
+  void (*getmessage)(char *buffer, char **outptr);
+                           /* Get SASL response message */
+};
+
+/* Per-connection parameters */
+struct SASL {
+  const struct SASLproto *params; /* Protocol dependent parameters */
+  saslstate state;         /* Current machine state */
+  unsigned int authmechs;  /* Accepted authentication mechanisms */
+  unsigned int prefmech;   /* Preferred authentication mechanism */
+  unsigned int authused;   /* Auth mechanism used for the connection */
+  bool resetprefs;         /* For URL auth option parsing. */
+  bool mutual_auth;        /* Mutual authentication enabled (GSSAPI only) */
+  bool force_ir;           /* Protocol always supports initial response */
+};
+
 /* This is used to test whether the line starts with the given mechanism */
 #define sasl_mech_equal(line, wordlen, mech) \
   (wordlen == (sizeof(mech) - 1) / sizeof(char) && \
@@ -68,29 +141,15 @@ char *Curl_sasl_build_spn(const char *service, const char *instance);
 TCHAR *Curl_sasl_build_spn(const char *service, const char *instance);
 #endif
 
-/* This is used to generate a base64 encoded PLAIN authentication message */
-CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
-                                        const char *userp,
-                                        const char *passwdp,
-                                        char **outptr, size_t *outlen);
+/* This is used to extract the realm from a challenge message */
+int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
+                              const char **endptr);
 
-/* This is used to generate a base64 encoded LOGIN authentication message
-   containing either the user name or password details */
-CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
-                                        const char *valuep, char **outptr,
-                                        size_t *outlen);
+#if defined(HAVE_GSSAPI)
+char *Curl_sasl_build_gssapi_spn(const char *service, const char *host);
+#endif
 
 #ifndef CURL_DISABLE_CRYPTO_AUTH
-/* This is used to decode a base64 encoded CRAM-MD5 challange message */
-CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
-                                           size_t *outlen);
-
-/* This is used to generate a base64 encoded CRAM-MD5 response message */
-CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
-                                           const char *chlg,
-                                           const char *user,
-                                           const char *passwdp,
-                                           char **outptr, size_t *outlen);
 
 /* This is used to generate a base64 encoded DIGEST-MD5 response message */
 CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
@@ -99,6 +158,22 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
                                              const char *passwdp,
                                              const char *service,
                                              char **outptr, size_t *outlen);
+
+/* This is used to decode a HTTP DIGEST challenge message */
+CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
+                                              struct digestdata *digest);
+
+/* This is used to generate a HTTP DIGEST response message */
+CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const unsigned char *request,
+                                              const unsigned char *uri,
+                                              struct digestdata *digest,
+                                              char **outptr, size_t *outlen);
+
+/* This is used to clean up the digest specific data */
+void Curl_sasl_digest_cleanup(struct digestdata *digest);
 #endif
 
 #ifdef USE_NTLM
@@ -121,9 +196,12 @@ CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
                                              struct ntlmdata *ntlm,
                                              char **outptr, size_t *outlen);
 
+/* This is used to clean up the ntlm specific data */
+void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm);
+
 #endif /* USE_NTLM */
 
-#if defined(USE_WINDOWS_SSPI)
+#if defined(USE_KERBEROS5)
 /* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
    message */
 CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
@@ -142,17 +220,35 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
                                                   struct kerberos5data *krb5,
                                                   char **outptr,
                                                   size_t *outlen);
-#endif
 
-/* This is used to generate a base64 encoded XOAUTH2 authentication message
-   containing the user name and bearer token */
-CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
-                                          const char *user,
-                                          const char *bearer,
-                                          char **outptr, size_t *outlen);
+/* This is used to clean up the gssapi specific data */
+void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
+#endif /* USE_KERBEROS5 */
 
 /* This is used to cleanup any libraries or curl modules used by the sasl
    functions */
 void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
 
+/* Convert a mechanism name to a token */
+unsigned int Curl_sasl_decode_mech(const char *ptr,
+                                   size_t maxlen, size_t *len);
+
+/* Parse the URL login options */
+CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
+                                         const char *value, size_t len);
+
+/* Initializes an SASL structure */
+void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params);
+
+/* Check if we have enough auth data and capabilities to authenticate */
+bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn);
+
+/* Calculate the required login details for SASL authentication  */
+CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
+                         bool force_ir, saslprogress *progress);
+
+/* Continue an SASL authentication  */
+CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
+                            int code, saslprogress *progress);
+
 #endif /* HEADER_CURL_SASL_H */
diff --git a/Utilities/cmcurl/lib/curl_sasl_gssapi.c b/Utilities/cmcurl/lib/curl_sasl_gssapi.c
new file mode 100644
index 0000000..3c6f3ce
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_sasl_gssapi.c
@@ -0,0 +1,392 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014 - 2015, Steve Holme, <steve_holme at hotmail.com>.
+ * Copyright (C) 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && defined(USE_KERBEROS5)
+
+#include <curl/curl.h>
+
+#include "curl_sasl.h"
+#include "urldata.h"
+#include "curl_base64.h"
+#include "curl_gssapi.h"
+#include "sendf.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+* Curl_sasl_build_gssapi_spn()
+*
+* This is used to build a SPN string in the format service at host.
+*
+* Parameters:
+*
+* serivce  [in] - The service type such as www, smtp, pop or imap.
+* host     [in] - The host name or realm.
+*
+* Returns a pointer to the newly allocated SPN.
+*/
+char *Curl_sasl_build_gssapi_spn(const char *service, const char *host)
+{
+  /* Generate and return our SPN */
+  return aprintf("%s@%s", service, host);
+}
+
+/*
+ * Curl_sasl_create_gssapi_user_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) user token
+ * message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data        [in]     - The session handle.
+ * userp       [in]     - The user name.
+ * passdwp     [in]     - The user's password.
+ * service     [in]     - The service type such as www, smtp, pop or imap.
+ * mutual_auth [in]     - Flag specifing whether or not mutual authentication
+ *                        is enabled.
+ * chlg64      [in]     - Pointer to the optional base64 encoded challenge
+ *                        message.
+ * krb5        [in/out] - The gssapi data struct being used and modified.
+ * outptr      [in/out] - The address where a pointer to newly allocated memory
+ *                        holding the result will be stored upon completion.
+ * outlen      [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const char *service,
+                                              const bool mutual_auth,
+                                              const char *chlg64,
+                                              struct kerberos5data *krb5,
+                                              char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlglen = 0;
+  unsigned char *chlg = NULL;
+  OM_uint32 gss_status;
+  OM_uint32 gss_major_status;
+  OM_uint32 gss_minor_status;
+  gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+
+  (void) userp;
+  (void) passwdp;
+
+  if(krb5->context == GSS_C_NO_CONTEXT) {
+    /* Generate our SPN */
+    char *spn = Curl_sasl_build_gssapi_spn(service,
+                                           data->easy_conn->host.name);
+    if(!spn)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Populate the SPN structure */
+    spn_token.value = spn;
+    spn_token.length = strlen(spn);
+
+    /* Import the SPN */
+    gss_major_status = gss_import_name(&gss_minor_status, &spn_token,
+                                       GSS_C_NT_HOSTBASED_SERVICE, &krb5->spn);
+    if(GSS_ERROR(gss_major_status)) {
+      Curl_gss_log_error(data, gss_minor_status, "gss_import_name() failed: ");
+
+      free(spn);
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    free(spn);
+  }
+  else {
+    /* Decode the base-64 encoded challenge message */
+    if(strlen(chlg64) && *chlg64 != '=') {
+      result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+      if(result)
+        return result;
+    }
+
+    /* Ensure we have a valid challenge message */
+    if(!chlg) {
+      infof(data, "GSSAPI handshake failure (empty challenge message)\n");
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
+
+    /* Setup the challenge "input" security buffer */
+    input_token.value = chlg;
+    input_token.length = chlglen;
+  }
+
+  gss_major_status = Curl_gss_init_sec_context(data,
+                                               &gss_minor_status,
+                                               &krb5->context,
+                                               krb5->spn,
+                                               &Curl_krb5_mech_oid,
+                                               GSS_C_NO_CHANNEL_BINDINGS,
+                                               &input_token,
+                                               &output_token,
+                                               mutual_auth,
+                                               NULL);
+
+  free(input_token.value);
+
+  if(GSS_ERROR(gss_major_status)) {
+    if(output_token.value)
+      gss_release_buffer(&gss_status, &output_token);
+
+    Curl_gss_log_error(data, gss_minor_status,
+                       "gss_init_sec_context() failed: ");
+
+    return CURLE_RECV_ERROR;
+  }
+
+  if(output_token.value && output_token.length) {
+    /* Base64 encode the response */
+    result = Curl_base64_encode(data, (char *) output_token.value,
+                                output_token.length, outptr, outlen);
+
+    gss_release_buffer(&gss_status, &output_token);
+  }
+
+  return result;
+}
+
+/*
+ * Curl_sasl_create_gssapi_security_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) security
+ * token message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * chlg64  [in]     - Pointer to the optional base64 encoded challenge message.
+ * krb5    [in/out] - The gssapi data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
+                                                  const char *chlg64,
+                                                  struct kerberos5data *krb5,
+                                                  char **outptr,
+                                                  size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlglen = 0;
+  size_t messagelen = 0;
+  unsigned char *chlg = NULL;
+  unsigned char *message = NULL;
+  OM_uint32 gss_status;
+  OM_uint32 gss_major_status;
+  OM_uint32 gss_minor_status;
+  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+  unsigned int indata = 0;
+  unsigned int outdata = 0;
+  gss_qop_t qop = GSS_C_QOP_DEFAULT;
+  unsigned int sec_layer = 0;
+  unsigned int max_size = 0;
+  gss_name_t username = GSS_C_NO_NAME;
+  gss_buffer_desc username_token;
+
+  /* Decode the base-64 encoded input message */
+  if(strlen(chlg64) && *chlg64 != '=') {
+    result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid challenge message */
+  if(!chlg) {
+    infof(data, "GSSAPI handshake failure (empty security message)\n");
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Get the fully qualified username back from the context */
+  gss_major_status = gss_inquire_context(&gss_minor_status, krb5->context,
+                                         &username, NULL, NULL, NULL, NULL,
+                                         NULL, NULL);
+  if(GSS_ERROR(gss_major_status)) {
+    Curl_gss_log_error(data, gss_minor_status,
+                       "gss_inquire_context() failed: ");
+
+    free(chlg);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Convert the username from internal format to a displayable token */
+  gss_major_status = gss_display_name(&gss_minor_status, username,
+                                      &username_token, NULL);
+  if(GSS_ERROR(gss_major_status)) {
+    Curl_gss_log_error(data, gss_minor_status, "gss_display_name() failed: ");
+
+    free(chlg);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Setup the challenge "input" security buffer */
+  input_token.value = chlg;
+  input_token.length = chlglen;
+
+  /* Decrypt the inbound challenge and obtain the qop */
+  gss_major_status = gss_unwrap(&gss_minor_status, krb5->context, &input_token,
+                                &output_token, NULL, &qop);
+  if(GSS_ERROR(gss_major_status)) {
+    Curl_gss_log_error(data, gss_minor_status, "gss_unwrap() failed: ");
+
+    gss_release_buffer(&gss_status, &username_token);
+    free(chlg);
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Not 4 octets long so fail as per RFC4752 Section 3.1 */
+  if(output_token.length != 4) {
+    infof(data, "GSSAPI handshake failure (invalid security data)\n");
+
+    gss_release_buffer(&gss_status, &username_token);
+    free(chlg);
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Copy the data out and free the challenge as it is not required anymore */
+  memcpy(&indata, output_token.value, 4);
+  gss_release_buffer(&gss_status, &output_token);
+  free(chlg);
+
+  /* Extract the security layer */
+  sec_layer = indata & 0x000000FF;
+  if(!(sec_layer & GSSAUTH_P_NONE)) {
+    infof(data, "GSSAPI handshake failure (invalid security layer)\n");
+
+    gss_release_buffer(&gss_status, &username_token);
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Extract the maximum message size the server can receive */
+  max_size = ntohl(indata & 0xFFFFFF00);
+  if(max_size > 0) {
+    /* The server has told us it supports a maximum receive buffer, however, as
+       we don't require one unless we are encrypting data, we tell the server
+       our receive buffer is zero. */
+    max_size = 0;
+  }
+
+  /* Allocate our message */
+  messagelen = sizeof(outdata) + username_token.length + 1;
+  message = malloc(messagelen);
+  if(!message) {
+    gss_release_buffer(&gss_status, &username_token);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Populate the message with the security layer, client supported receive
+     message size and authorization identity including the 0x00 based
+     terminator. Note: Dispite RFC4752 Section 3.1 stating "The authorization
+     identity is not terminated with the zero-valued (%x00) octet." it seems
+     necessary to include it. */
+  outdata = htonl(max_size) | sec_layer;
+  memcpy(message, &outdata, sizeof(outdata));
+  memcpy(message + sizeof(outdata), username_token.value,
+         username_token.length);
+  message[messagelen - 1] = '\0';
+
+  /* Free the username token as it is not required anymore */
+  gss_release_buffer(&gss_status, &username_token);
+
+  /* Setup the "authentication data" security buffer */
+  input_token.value = message;
+  input_token.length = messagelen;
+
+  /* Encrypt the data */
+  gss_major_status = gss_wrap(&gss_minor_status, krb5->context, 0,
+                              GSS_C_QOP_DEFAULT, &input_token, NULL,
+                              &output_token);
+  if(GSS_ERROR(gss_major_status)) {
+    Curl_gss_log_error(data, gss_minor_status, "gss_wrap() failed: ");
+
+    free(message);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, (char *) output_token.value,
+                              output_token.length, outptr, outlen);
+
+  /* Free the output buffer */
+  gss_release_buffer(&gss_status, &output_token);
+
+  /* Free the message buffer */
+  free(message);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_gssapi_cleanup()
+ *
+ * This is used to clean up the gssapi specific data.
+ *
+ * Parameters:
+ *
+ * krb5     [in/out] - The kerberos 5 data struct being cleaned up.
+ *
+ */
+void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
+{
+  OM_uint32 minor_status;
+
+  /* Free our security context */
+  if(krb5->context != GSS_C_NO_CONTEXT) {
+    gss_delete_sec_context(&minor_status, &krb5->context, GSS_C_NO_BUFFER);
+    krb5->context = GSS_C_NO_CONTEXT;
+  }
+
+  /* Free the SPN */
+  if(krb5->spn != GSS_C_NO_NAME) {
+    gss_release_name(&minor_status, &krb5->spn);
+    krb5->spn = GSS_C_NO_NAME;
+  }
+}
+
+#endif /* HAVE_GSSAPI && USE_KERBEROS5 */
diff --git a/Utilities/cmcurl/lib/curl_sasl_sspi.c b/Utilities/cmcurl/lib/curl_sasl_sspi.c
index df4da96..b149530 100644
--- a/Utilities/cmcurl/lib/curl_sasl_sspi.c
+++ b/Utilities/cmcurl/lib/curl_sasl_sspi.c
@@ -5,8 +5,8 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
+ * Copyright (C) 2014 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  * Copyright (C) 2014, Steve Holme, <steve_holme at hotmail.com>.
- * Copyright (C) 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -19,6 +19,7 @@
  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  * KIND, either express or implied.
  *
+ * RFC2617 Basic and Digest Access Authentication
  * RFC2831 DIGEST-MD5 authentication
  * RFC4422 Simple Authentication and Security Layer (SASL)
  * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
@@ -35,17 +36,16 @@
 #include "urldata.h"
 #include "curl_base64.h"
 #include "warnless.h"
-#include "curl_memory.h"
 #include "curl_multibyte.h"
+#include "sendf.h"
+#include "strdup.h"
+#include "curl_printf.h"
+#include "rawstr.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
-void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
-
 /*
  * Curl_sasl_build_spn()
  *
@@ -54,7 +54,7 @@ void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
  * Parameters:
  *
  * serivce  [in] - The service type such as www, smtp, pop or imap.
- * instance [in] - The instance name such as the host nme or realm.
+ * host     [in] - The host name or realm.
  *
  * Returns a pointer to the newly allocated SPN.
  */
@@ -79,14 +79,13 @@ TCHAR *Curl_sasl_build_spn(const char *service, const char *host)
   /* Allocate our TCHAR based SPN */
   tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn);
   if(!tchar_spn) {
-    Curl_safefree(utf8_spn);
+    free(utf8_spn);
 
     return NULL;
   }
 
   /* Release the UTF8 variant when operating with Unicode */
-  if(utf8_spn != tchar_spn)
-    Curl_safefree(utf8_spn);
+  Curl_unicodefree(utf8_spn);
 
   /* Return our newly allocated SPN */
   return tchar_spn;
@@ -102,8 +101,8 @@ TCHAR *Curl_sasl_build_spn(const char *service, const char *host)
  * Parameters:
  *
  * data    [in]     - The session handle.
- * chlg64  [in]     - Pointer to the base64 encoded challenge message.
- * userp   [in]     - The user name.
+ * chlg64  [in]     - The base64 encoded challenge message.
+ * userp   [in]     - The user name in the format User or Domain\User.
  * passdwp [in]     - The user's password.
  * service [in]     - The service type such as www, smtp, pop or imap.
  * outptr  [in/out] - The address where a pointer to newly allocated memory
@@ -122,57 +121,54 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
   CURLcode result = CURLE_OK;
   TCHAR *spn = NULL;
   size_t chlglen = 0;
-  size_t resp_max = 0;
-  unsigned char *chlg = NULL;
-  unsigned char *resp = NULL;
-  CredHandle handle;
-  CtxtHandle ctx;
+  size_t token_max = 0;
+  unsigned char *input_token = NULL;
+  unsigned char *output_token = NULL;
+  CredHandle credentials;
+  CtxtHandle context;
   PSecPkgInfo SecurityPackage;
   SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
   SecBuffer chlg_buf;
   SecBuffer resp_buf;
   SecBufferDesc chlg_desc;
   SecBufferDesc resp_desc;
   SECURITY_STATUS status;
   unsigned long attrs;
-  TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
 
   /* Decode the base-64 encoded challenge message */
   if(strlen(chlg64) && *chlg64 != '=') {
-    result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+    result = Curl_base64_decode(chlg64, &input_token, &chlglen);
     if(result)
       return result;
   }
 
   /* Ensure we have a valid challenge message */
-  if(!chlg)
-    return CURLE_BAD_CONTENT_ENCODING;
+  if(!input_token) {
+    infof(data, "DIGEST-MD5 handshake failure (empty challenge message)\n");
 
-  /* Ensure we have some login credientials as DigestSSP cannot use the current
-     Windows user like NTLMSSP can */
-  if(!userp || !*userp) {
-    Curl_safefree(chlg);
-    return CURLE_LOGIN_DENIED;
+    return CURLE_BAD_CONTENT_ENCODING;
   }
 
   /* Query the security package for DigestSSP */
-  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("WDigest"),
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
                                               &SecurityPackage);
   if(status != SEC_E_OK) {
-    Curl_safefree(chlg);
+    free(input_token);
 
     return CURLE_NOT_BUILT_IN;
   }
 
-  resp_max = SecurityPackage->cbMaxToken;
+  token_max = SecurityPackage->cbMaxToken;
 
   /* Release the package buffer as it is not required anymore */
   s_pSecFn->FreeContextBuffer(SecurityPackage);
 
   /* Allocate our response buffer */
-  resp = malloc(resp_max);
-  if(!resp) {
-    Curl_safefree(chlg);
+  output_token = malloc(token_max);
+  if(!output_token) {
+    free(input_token);
 
     return CURLE_OUT_OF_MEMORY;
   }
@@ -180,36 +176,44 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
   /* Generate our SPN */
   spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
   if(!spn) {
-    Curl_safefree(resp);
-    Curl_safefree(chlg);
+    free(output_token);
+    free(input_token);
 
     return CURLE_OUT_OF_MEMORY;
   }
 
-  /* Populate our identity structure */
-  result = Curl_create_sspi_identity(userp, passwdp, &identity);
-  if(result) {
-    Curl_safefree(spn);
-    Curl_safefree(resp);
-    Curl_safefree(chlg);
+  if(userp && *userp) {
+    /* Populate our identity structure */
+    result = Curl_create_sspi_identity(userp, passwdp, &identity);
+    if(result) {
+      free(spn);
+      free(output_token);
+      free(input_token);
+
+      return result;
+    }
 
-    return result;
+    /* Allow proper cleanup of the identity structure */
+    p_identity = &identity;
   }
+  else
+    /* Use the current Windows user */
+    p_identity = NULL;
 
-  /* Acquire our credientials handle */
+  /* Acquire our credentials handle */
   status = s_pSecFn->AcquireCredentialsHandle(NULL,
-                                              (TCHAR *) TEXT("WDigest"),
+                                              (TCHAR *) TEXT(SP_NAME_DIGEST),
                                               SECPKG_CRED_OUTBOUND, NULL,
-                                              &identity, NULL, NULL,
-                                              &handle, &tsDummy);
+                                              p_identity, NULL, NULL,
+                                              &credentials, &expiry);
 
   if(status != SEC_E_OK) {
-    Curl_sspi_free_identity(&identity);
-    Curl_safefree(spn);
-    Curl_safefree(resp);
-    Curl_safefree(chlg);
+    Curl_sspi_free_identity(p_identity);
+    free(spn);
+    free(output_token);
+    free(input_token);
 
-    return CURLE_OUT_OF_MEMORY;
+    return CURLE_LOGIN_DENIED;
   }
 
   /* Setup the challenge "input" security buffer */
@@ -217,7 +221,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
   chlg_desc.cBuffers  = 1;
   chlg_desc.pBuffers  = &chlg_buf;
   chlg_buf.BufferType = SECBUFFER_TOKEN;
-  chlg_buf.pvBuffer   = chlg;
+  chlg_buf.pvBuffer   = input_token;
   chlg_buf.cbBuffer   = curlx_uztoul(chlglen);
 
   /* Setup the response "output" security buffer */
@@ -225,52 +229,611 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
   resp_desc.cBuffers  = 1;
   resp_desc.pBuffers  = &resp_buf;
   resp_buf.BufferType = SECBUFFER_TOKEN;
-  resp_buf.pvBuffer   = resp;
-  resp_buf.cbBuffer   = curlx_uztoul(resp_max);
-
-  /* Generate our challenge-response message */
-  status = s_pSecFn->InitializeSecurityContext(&handle, NULL, spn, 0, 0, 0,
-                                               &chlg_desc, 0, &ctx,
-                                               &resp_desc, &attrs, &tsDummy);
-
-  if(status == SEC_I_COMPLETE_AND_CONTINUE ||
-     status == SEC_I_CONTINUE_NEEDED)
-    s_pSecFn->CompleteAuthToken(&handle, &resp_desc);
-  else if(status != SEC_E_OK) {
-    s_pSecFn->FreeCredentialsHandle(&handle);
-    Curl_sspi_free_identity(&identity);
-    Curl_safefree(spn);
-    Curl_safefree(resp);
-    Curl_safefree(chlg);
+  resp_buf.pvBuffer   = output_token;
+  resp_buf.cbBuffer   = curlx_uztoul(token_max);
+
+  /* Generate our response message */
+  status = s_pSecFn->InitializeSecurityContext(&credentials, NULL, spn,
+                                               0, 0, 0, &chlg_desc, 0,
+                                               &context, &resp_desc, &attrs,
+                                               &expiry);
+
+  if(status == SEC_I_COMPLETE_NEEDED ||
+     status == SEC_I_COMPLETE_AND_CONTINUE)
+    s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
+  else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+    s_pSecFn->FreeCredentialsHandle(&credentials);
+    Curl_sspi_free_identity(p_identity);
+    free(spn);
+    free(output_token);
+    free(input_token);
 
     return CURLE_RECV_ERROR;
   }
 
   /* Base64 encode the response */
-  result = Curl_base64_encode(data, (char *)resp, resp_buf.cbBuffer, outptr,
-                              outlen);
+  result = Curl_base64_encode(data, (char *) output_token, resp_buf.cbBuffer,
+                              outptr, outlen);
 
   /* Free our handles */
-  s_pSecFn->DeleteSecurityContext(&ctx);
-  s_pSecFn->FreeCredentialsHandle(&handle);
+  s_pSecFn->DeleteSecurityContext(&context);
+  s_pSecFn->FreeCredentialsHandle(&credentials);
 
   /* Free the identity structure */
-  Curl_sspi_free_identity(&identity);
+  Curl_sspi_free_identity(p_identity);
 
   /* Free the SPN */
-  Curl_safefree(spn);
+  free(spn);
 
   /* Free the response buffer */
-  Curl_safefree(resp);
+  free(output_token);
 
-  /* Free the decoeded challenge message */
-  Curl_safefree(chlg);
+  /* Free the decoded challenge message */
+  free(input_token);
 
   return result;
 }
 
+/*
+* Curl_override_sspi_http_realm()
+*
+* This is used to populate the domain in a SSPI identity structure
+* The realm is extracted from the challenge message and used as the
+* domain if it is not already explicitly set.
+*
+* Parameters:
+*
+* chlg     [in]     - The challenge message.
+* identity [in/out] - The identity structure.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
+                                       SEC_WINNT_AUTH_IDENTITY *identity)
+{
+  xcharp_u domain, dup_domain;
+
+  /* If domain is blank or unset, check challenge message for realm */
+  if(!identity->Domain || !identity->DomainLength) {
+    for(;;) {
+      char value[DIGEST_MAX_VALUE_LENGTH];
+      char content[DIGEST_MAX_CONTENT_LENGTH];
+
+      /* Pass all additional spaces here */
+      while(*chlg && ISSPACE(*chlg))
+        chlg++;
+
+      /* Extract a value=content pair */
+      if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
+        if(Curl_raw_equal(value, "realm")) {
+
+          /* Setup identity's domain and length */
+          domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)content);
+          if(!domain.tchar_ptr)
+            return CURLE_OUT_OF_MEMORY;
+          dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr);
+          if(!dup_domain.tchar_ptr) {
+            Curl_unicodefree(domain.tchar_ptr);
+            return CURLE_OUT_OF_MEMORY;
+          }
+          identity->Domain = dup_domain.tbyte_ptr;
+          identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr));
+          dup_domain.tchar_ptr = NULL;
+
+          Curl_unicodefree(domain.tchar_ptr);
+        }
+        else {
+          /* unknown specifier, ignore it! */
+        }
+      }
+      else
+        break; /* we're done here */
+
+      /* Pass all additional spaces here */
+      while(*chlg && ISSPACE(*chlg))
+        chlg++;
+
+      /* Allow the list to be comma-separated */
+      if(',' == *chlg)
+        chlg++;
+    }
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_decode_digest_http_message()
+ *
+ * This is used to decode a HTTP DIGEST challenge message into the seperate
+ * attributes.
+ *
+ * Parameters:
+ *
+ * chlg    [in]     - The challenge message.
+ * digest  [in/out] - The digest data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
+                                              struct digestdata *digest)
+{
+  size_t chlglen = strlen(chlg);
+
+  /* We had an input token before and we got another one now. This means we
+  provided bad credentials in the previous request. */
+  if(digest->input_token)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Simply store the challenge for use later */
+  digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen);
+  if(!digest->input_token)
+    return CURLE_OUT_OF_MEMORY;
+
+  digest->input_token_len = chlglen;
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_create_digest_http_message()
+ *
+ * This is used to generate a HTTP DIGEST response message ready for sending
+ * to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name in the format User or Domain\User.
+ * passdwp [in]     - The user's password.
+ * request [in]     - The HTTP request.
+ * uripath [in]     - The path of the HTTP uri.
+ * digest  [in/out] - The digest data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const unsigned char *request,
+                                              const unsigned char *uripath,
+                                              struct digestdata *digest,
+                                              char **outptr, size_t *outlen)
+{
+  size_t token_max;
+  CredHandle credentials;
+  CtxtHandle context;
+  char *resp;
+  BYTE *output_token;
+  PSecPkgInfo SecurityPackage;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
+  SecBuffer chlg_buf[3];
+  SecBuffer resp_buf;
+  SecBufferDesc chlg_desc;
+  SecBufferDesc resp_desc;
+  SECURITY_STATUS status;
+  unsigned long attrs;
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+  (void) data;
+
+  /* Query the security package for DigestSSP */
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
+                                              &SecurityPackage);
+  if(status != SEC_E_OK)
+    return CURLE_NOT_BUILT_IN;
+
+  token_max = SecurityPackage->cbMaxToken;
+
+  /* Release the package buffer as it is not required anymore */
+  s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+  /* Allocate the output buffer according to the max token size as indicated
+     by the security package */
+  output_token = malloc(token_max);
+  if(!output_token)
+    return CURLE_OUT_OF_MEMORY;
+
+  if(userp && *userp) {
+    /* Populate our identity structure */
+    if(Curl_create_sspi_identity(userp, passwdp, &identity))
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Populate our identity domain */
+    if(Curl_override_sspi_http_realm((const char*)digest->input_token,
+                                     &identity))
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Allow proper cleanup of the identity structure */
+    p_identity = &identity;
+  }
+  else
+    /* Use the current Windows user */
+    p_identity = NULL;
+
+  /* Acquire our credentials handle */
+  status = s_pSecFn->AcquireCredentialsHandle(NULL,
+                                              (TCHAR *) TEXT(SP_NAME_DIGEST),
+                                              SECPKG_CRED_OUTBOUND, NULL,
+                                              p_identity, NULL, NULL,
+                                              &credentials, &expiry);
+  if(status != SEC_E_OK) {
+    free(output_token);
+
+    return CURLE_LOGIN_DENIED;
+  }
+
+  /* Setup the challenge "input" security buffer if present */
+  chlg_desc.ulVersion    = SECBUFFER_VERSION;
+  chlg_desc.cBuffers     = 3;
+  chlg_desc.pBuffers     = chlg_buf;
+  chlg_buf[0].BufferType = SECBUFFER_TOKEN;
+  chlg_buf[0].pvBuffer   = digest->input_token;
+  chlg_buf[0].cbBuffer   = curlx_uztoul(digest->input_token_len);
+  chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS;
+  chlg_buf[1].pvBuffer   = (void *)request;
+  chlg_buf[1].cbBuffer   = curlx_uztoul(strlen((const char *) request));
+  chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS;
+  chlg_buf[2].pvBuffer   = NULL;
+  chlg_buf[2].cbBuffer   = 0;
+
+  /* Setup the response "output" security buffer */
+  resp_desc.ulVersion = SECBUFFER_VERSION;
+  resp_desc.cBuffers  = 1;
+  resp_desc.pBuffers  = &resp_buf;
+  resp_buf.BufferType = SECBUFFER_TOKEN;
+  resp_buf.pvBuffer   = output_token;
+  resp_buf.cbBuffer   = curlx_uztoul(token_max);
+
+  /* Generate our reponse message */
+  status = s_pSecFn->InitializeSecurityContext(&credentials, NULL,
+                                               (TCHAR *) uripath,
+                                               ISC_REQ_USE_HTTP_STYLE, 0, 0,
+                                               &chlg_desc, 0, &context,
+                                               &resp_desc, &attrs, &expiry);
+
+  if(status == SEC_I_COMPLETE_NEEDED ||
+     status == SEC_I_COMPLETE_AND_CONTINUE)
+    s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
+  else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+    s_pSecFn->FreeCredentialsHandle(&credentials);
+
+    free(output_token);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  resp = malloc(resp_buf.cbBuffer + 1);
+  if(!resp) {
+    s_pSecFn->DeleteSecurityContext(&context);
+    s_pSecFn->FreeCredentialsHandle(&credentials);
+
+    free(output_token);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Copy the generated reponse */
+  memcpy(resp, resp_buf.pvBuffer, resp_buf.cbBuffer);
+  resp[resp_buf.cbBuffer] = 0x00;
+
+  /* Return the response */
+  *outptr = resp;
+  *outlen = resp_buf.cbBuffer;
+
+  /* Free our handles */
+  s_pSecFn->DeleteSecurityContext(&context);
+  s_pSecFn->FreeCredentialsHandle(&credentials);
+
+  /* Free the identity structure */
+  Curl_sspi_free_identity(p_identity);
+
+  /* Free the response buffer */
+  free(output_token);
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_digest_cleanup()
+ *
+ * This is used to clean up the digest specific data.
+ *
+ * Parameters:
+ *
+ * digest    [in/out] - The digest data struct being cleaned up.
+ *
+ */
+void Curl_sasl_digest_cleanup(struct digestdata *digest)
+{
+  /* Free the input token */
+  Curl_safefree(digest->input_token);
+
+  /* Reset any variables */
+  digest->input_token_len = 0;
+}
 #endif /* !CURL_DISABLE_CRYPTO_AUTH */
 
+#if defined USE_NTLM
+/*
+* Curl_sasl_create_ntlm_type1_message()
+*
+* This is used to generate an already encoded NTLM type-1 message ready for
+* sending to the recipient.
+*
+* Parameters:
+*
+* userp   [in]     - The user name in the format User or Domain\User.
+* passdwp [in]     - The user's password.
+* ntlm    [in/out] - The ntlm data struct being used and modified.
+* outptr  [in/out] - The address where a pointer to newly allocated memory
+*                    holding the result will be stored upon completion.
+* outlen  [out]    - The length of the output message.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
+{
+  PSecPkgInfo SecurityPackage;
+  SecBuffer type_1_buf;
+  SecBufferDesc type_1_desc;
+  SECURITY_STATUS status;
+  unsigned long attrs;
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+  /* Clean up any former leftovers and initialise to defaults */
+  Curl_sasl_ntlm_cleanup(ntlm);
+
+  /* Query the security package for NTLM */
+  status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
+                                              &SecurityPackage);
+  if(status != SEC_E_OK)
+    return CURLE_NOT_BUILT_IN;
+
+  ntlm->token_max = SecurityPackage->cbMaxToken;
+
+  /* Release the package buffer as it is not required anymore */
+  s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+  /* Allocate our output buffer */
+  ntlm->output_token = malloc(ntlm->token_max);
+  if(!ntlm->output_token)
+    return CURLE_OUT_OF_MEMORY;
+
+  if(userp && *userp) {
+    CURLcode result;
+
+    /* Populate our identity structure */
+    result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity);
+    if(result)
+      return result;
+
+    /* Allow proper cleanup of the identity structure */
+    ntlm->p_identity = &ntlm->identity;
+  }
+  else
+    /* Use the current Windows user */
+    ntlm->p_identity = NULL;
+
+  /* Allocate our credentials handle */
+  ntlm->credentials = malloc(sizeof(CredHandle));
+  if(!ntlm->credentials)
+    return CURLE_OUT_OF_MEMORY;
+
+  memset(ntlm->credentials, 0, sizeof(CredHandle));
+
+  /* Acquire our credentials handle */
+  status = s_pSecFn->AcquireCredentialsHandle(NULL,
+                                              (TCHAR *) TEXT(SP_NAME_NTLM),
+                                              SECPKG_CRED_OUTBOUND, NULL,
+                                              ntlm->p_identity, NULL, NULL,
+                                              ntlm->credentials, &expiry);
+  if(status != SEC_E_OK)
+    return CURLE_LOGIN_DENIED;
+
+  /* Allocate our new context handle */
+  ntlm->context = malloc(sizeof(CtxtHandle));
+  if(!ntlm->context)
+    return CURLE_OUT_OF_MEMORY;
+
+  memset(ntlm->context, 0, sizeof(CtxtHandle));
+
+  /* Setup the type-1 "output" security buffer */
+  type_1_desc.ulVersion = SECBUFFER_VERSION;
+  type_1_desc.cBuffers  = 1;
+  type_1_desc.pBuffers  = &type_1_buf;
+  type_1_buf.BufferType = SECBUFFER_TOKEN;
+  type_1_buf.pvBuffer   = ntlm->output_token;
+  type_1_buf.cbBuffer   = curlx_uztoul(ntlm->token_max);
+
+  /* Generate our type-1 message */
+  status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL,
+                                               (TCHAR *) TEXT(""),
+                                               0, 0, SECURITY_NETWORK_DREP,
+                                               NULL, 0,
+                                               ntlm->context, &type_1_desc,
+                                               &attrs, &expiry);
+  if(status == SEC_I_COMPLETE_NEEDED ||
+    status == SEC_I_COMPLETE_AND_CONTINUE)
+    s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc);
+  else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED)
+    return CURLE_RECV_ERROR;
+
+  /* Base64 encode the response */
+  return Curl_base64_encode(NULL, (char *) ntlm->output_token,
+                            type_1_buf.cbBuffer, outptr, outlen);
+}
+
+/*
+* Curl_sasl_decode_ntlm_type2_message()
+*
+* This is used to decode an already encoded NTLM type-2 message.
+*
+* Parameters:
+*
+* data     [in]     - The session handle.
+* type2msg [in]     - The base64 encoded type-2 message.
+* ntlm     [in/out] - The ntlm data struct being used and modified.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
+                                             const char *type2msg,
+                                             struct ntlmdata *ntlm)
+{
+  CURLcode result = CURLE_OK;
+  unsigned char *type2 = NULL;
+  size_t type2_len = 0;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) data;
+#endif
+
+  /* Decode the base-64 encoded type-2 message */
+  if(strlen(type2msg) && *type2msg != '=') {
+    result = Curl_base64_decode(type2msg, &type2, &type2_len);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid type-2 message */
+  if(!type2) {
+    infof(data, "NTLM handshake failure (empty type-2 message)\n");
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Simply store the challenge for use later */
+  ntlm->input_token = type2;
+  ntlm->input_token_len = type2_len;
+
+  return result;
+}
+
+/*
+* Curl_sasl_create_ntlm_type3_message()
+*
+* This is used to generate an already encoded NTLM type-3 message ready for
+* sending to the recipient.
+*
+* Parameters:
+*
+* data    [in]     - The session handle.
+* userp   [in]     - The user name in the format User or Domain\User.
+* passdwp [in]     - The user's password.
+* ntlm    [in/out] - The ntlm data struct being used and modified.
+* outptr  [in/out] - The address where a pointer to newly allocated memory
+*                    holding the result will be stored upon completion.
+* outlen  [out]    - The length of the output message.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  SecBuffer type_2_buf;
+  SecBuffer type_3_buf;
+  SecBufferDesc type_2_desc;
+  SecBufferDesc type_3_desc;
+  SECURITY_STATUS status;
+  unsigned long attrs;
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+  (void) passwdp;
+  (void) userp;
+
+  /* Setup the type-2 "input" security buffer */
+  type_2_desc.ulVersion = SECBUFFER_VERSION;
+  type_2_desc.cBuffers  = 1;
+  type_2_desc.pBuffers  = &type_2_buf;
+  type_2_buf.BufferType = SECBUFFER_TOKEN;
+  type_2_buf.pvBuffer   = ntlm->input_token;
+  type_2_buf.cbBuffer   = curlx_uztoul(ntlm->input_token_len);
+
+  /* Setup the type-3 "output" security buffer */
+  type_3_desc.ulVersion = SECBUFFER_VERSION;
+  type_3_desc.cBuffers  = 1;
+  type_3_desc.pBuffers  = &type_3_buf;
+  type_3_buf.BufferType = SECBUFFER_TOKEN;
+  type_3_buf.pvBuffer   = ntlm->output_token;
+  type_3_buf.cbBuffer   = curlx_uztoul(ntlm->token_max);
+
+  /* Generate our type-3 message */
+  status = s_pSecFn->InitializeSecurityContext(ntlm->credentials,
+                                               ntlm->context,
+                                               (TCHAR *) TEXT(""),
+                                               0, 0, SECURITY_NETWORK_DREP,
+                                               &type_2_desc,
+                                               0, ntlm->context,
+                                               &type_3_desc,
+                                               &attrs, &expiry);
+  if(status != SEC_E_OK) {
+    infof(data, "NTLM handshake failure (type-3 message): Status=%x\n",
+          status);
+
+    return CURLE_RECV_ERROR;
+  }
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, (char *) ntlm->output_token,
+                              type_3_buf.cbBuffer, outptr, outlen);
+
+  Curl_sasl_ntlm_cleanup(ntlm);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_ntlm_cleanup()
+ *
+ * This is used to clean up the ntlm specific data.
+ *
+ * Parameters:
+ *
+ * ntlm    [in/out] - The ntlm data struct being cleaned up.
+ *
+ */
+void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm)
+{
+  /* Free our security context */
+  if(ntlm->context) {
+    s_pSecFn->DeleteSecurityContext(ntlm->context);
+    free(ntlm->context);
+    ntlm->context = NULL;
+  }
+
+  /* Free our credentials handle */
+  if(ntlm->credentials) {
+    s_pSecFn->FreeCredentialsHandle(ntlm->credentials);
+    free(ntlm->credentials);
+    ntlm->credentials = NULL;
+  }
+
+  /* Free our identity */
+  Curl_sspi_free_identity(ntlm->p_identity);
+  ntlm->p_identity = NULL;
+
+  /* Free the input and output tokens */
+  Curl_safefree(ntlm->input_token);
+  Curl_safefree(ntlm->output_token);
+
+  /* Reset any variables */
+  ntlm->token_max = 0;
+}
+#endif /* USE_NTLM */
+
+#if defined(USE_KERBEROS5)
 /*
  * Curl_sasl_create_gssapi_user_message()
  *
@@ -280,13 +843,12 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
  * Parameters:
  *
  * data        [in]     - The session handle.
- * userp       [in]     - The user name.
+ * userp       [in]     - The user name in the format User or Domain\User.
  * passdwp     [in]     - The user's password.
  * service     [in]     - The service type such as www, smtp, pop or imap.
  * mutual_auth [in]     - Flag specifing whether or not mutual authentication
  *                        is enabled.
- * chlg64      [in]     - Pointer to the optional base64 encoded challenge
- *                        message.
+ * chlg64      [in]     - The optional base64 encoded challenge message.
  * krb5        [in/out] - The gssapi data struct being used and modified.
  * outptr      [in/out] - The address where a pointer to newly allocated memory
  *                        holding the result will be stored upon completion.
@@ -314,11 +876,12 @@ CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
   SecBufferDesc resp_desc;
   SECURITY_STATUS status;
   unsigned long attrs;
-  TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
+  TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
 
   if(!krb5->credentials) {
     /* Query the security package for Kerberos */
-    status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("Kerberos"),
+    status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
+                                                TEXT(SP_NAME_KERBEROS),
                                                 &SecurityPackage);
     if(status != SEC_E_OK) {
       return CURLE_NOT_BUILT_IN;
@@ -329,6 +892,11 @@ CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
     /* Release the package buffer as it is not required anymore */
     s_pSecFn->FreeContextBuffer(SecurityPackage);
 
+    /* Allocate our response buffer */
+    krb5->output_token = malloc(krb5->token_max);
+    if(!krb5->output_token)
+      return CURLE_OUT_OF_MEMORY;
+
     /* Generate our SPN */
     krb5->spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
     if(!krb5->spn)
@@ -342,11 +910,6 @@ CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
 
       /* Allow proper cleanup of the identity structure */
       krb5->p_identity = &krb5->identity;
-
-      /* Allocate our response buffer */
-      krb5->output_token = malloc(krb5->token_max);
-      if(!krb5->output_token)
-        return CURLE_OUT_OF_MEMORY;
     }
     else
       /* Use the current Windows user */
@@ -359,14 +922,15 @@ CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
 
     memset(krb5->credentials, 0, sizeof(CredHandle));
 
-    /* Acquire our credientials handle */
+    /* Acquire our credentials handle */
     status = s_pSecFn->AcquireCredentialsHandle(NULL,
-                                                (TCHAR *) TEXT("Kerberos"),
+                                                (TCHAR *)
+                                                TEXT(SP_NAME_KERBEROS),
                                                 SECPKG_CRED_OUTBOUND, NULL,
                                                 krb5->p_identity, NULL, NULL,
-                                                krb5->credentials, &tsDummy);
+                                                krb5->credentials, &expiry);
     if(status != SEC_E_OK)
-      return CURLE_OUT_OF_MEMORY;
+      return CURLE_LOGIN_DENIED;
 
     /* Allocate our new context handle */
     krb5->context = malloc(sizeof(CtxtHandle));
@@ -384,8 +948,11 @@ CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
     }
 
     /* Ensure we have a valid challenge message */
-    if(!chlg)
+    if(!chlg) {
+      infof(data, "GSSAPI handshake failure (empty challenge message)\n");
+
       return CURLE_BAD_CONTENT_ENCODING;
+    }
 
     /* Setup the challenge "input" security buffer */
     chlg_desc.ulVersion = SECBUFFER_VERSION;
@@ -414,10 +981,10 @@ CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
                                                chlg ? &chlg_desc : NULL, 0,
                                                &context,
                                                &resp_desc, &attrs,
-                                               &tsDummy);
+                                               &expiry);
 
   if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
-    Curl_safefree(chlg);
+    free(chlg);
 
     return CURLE_RECV_ERROR;
   }
@@ -435,7 +1002,7 @@ CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
   }
 
   /* Free the decoded challenge */
-  Curl_safefree(chlg);
+  free(chlg);
 
   return result;
 }
@@ -449,7 +1016,7 @@ CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
  * Parameters:
  *
  * data    [in]     - The session handle.
- * chlg64  [in]     - Pointer to the optional base64 encoded challenge message.
+ * chlg64  [in]     - The optional base64 encoded challenge message.
  * krb5    [in/out] - The gssapi data struct being used and modified.
  * outptr  [in/out] - The address where a pointer to newly allocated memory
  *                    holding the result will be stored upon completion.
@@ -485,8 +1052,7 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
   SecPkgContext_Sizes sizes;
   SecPkgCredentials_Names names;
   SECURITY_STATUS status;
-
-  /* TODO: Verify the unicodeness of this function */
+  char *user_name;
 
   /* Decode the base-64 encoded input message */
   if(strlen(chlg64) && *chlg64 != '=') {
@@ -496,15 +1062,18 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
   }
 
   /* Ensure we have a valid challenge message */
-  if(!chlg)
+  if(!chlg) {
+    infof(data, "GSSAPI handshake failure (empty security message)\n");
+
     return CURLE_BAD_CONTENT_ENCODING;
+  }
 
   /* Get our response size information */
   status = s_pSecFn->QueryContextAttributes(krb5->context,
                                             SECPKG_ATTR_SIZES,
                                             &sizes);
   if(status != SEC_E_OK) {
-    Curl_safefree(chlg);
+    free(chlg);
 
     return CURLE_OUT_OF_MEMORY;
   }
@@ -514,7 +1083,7 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
                                                 SECPKG_CRED_ATTR_NAMES,
                                                 &names);
   if(status != SEC_E_OK) {
-    Curl_safefree(chlg);
+    free(chlg);
 
     return CURLE_RECV_ERROR;
   }
@@ -530,30 +1099,34 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
   input_buf[1].pvBuffer = NULL;
   input_buf[1].cbBuffer = 0;
 
-  /* Decrypt in the inbound challenge obtaining the qop */
+  /* Decrypt the inbound challenge and obtain the qop */
   status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop);
   if(status != SEC_E_OK) {
-    Curl_safefree(chlg);
+    infof(data, "GSSAPI handshake failure (empty security message)\n");
+
+    free(chlg);
 
     return CURLE_BAD_CONTENT_ENCODING;
   }
 
-  /* Not 4 octets long to fail as per RFC4752 Section 3.1 */
+  /* Not 4 octets long so fail as per RFC4752 Section 3.1 */
   if(input_buf[1].cbBuffer != 4) {
-    Curl_safefree(chlg);
+    infof(data, "GSSAPI handshake failure (invalid security data)\n");
+
+    free(chlg);
 
     return CURLE_BAD_CONTENT_ENCODING;
   }
 
-  /* Copy the data out into a coinput_bufnvenient variable and free the SSPI
-     allocated buffer as it is not required anymore */
+  /* Copy the data out and free the challenge as it is not required anymore */
   memcpy(&indata, input_buf[1].pvBuffer, 4);
   s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer);
+  free(chlg);
 
   /* Extract the security layer */
   sec_layer = indata & 0x000000FF;
   if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) {
-    Curl_safefree(chlg);
+    infof(data, "GSSAPI handshake failure (invalid security layer)\n");
 
     return CURLE_BAD_CONTENT_ENCODING;
   }
@@ -562,27 +1135,30 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
   max_size = ntohl(indata & 0xFFFFFF00);
   if(max_size > 0) {
     /* The server has told us it supports a maximum receive buffer, however, as
-       we don't require one unless we are encrypting data we, tell the server
+       we don't require one unless we are encrypting data, we tell the server
        our receive buffer is zero. */
     max_size = 0;
   }
 
-  outdata = htonl(max_size) | sec_layer;
-
   /* Allocate the trailer */
   trailer = malloc(sizes.cbSecurityTrailer);
-  if(!trailer) {
-    Curl_safefree(chlg);
+  if(!trailer)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Convert the user name to UTF8 when operating with Unicode */
+  user_name = Curl_convert_tchar_to_UTF8(names.sUserName);
+  if(!user_name) {
+    free(trailer);
 
     return CURLE_OUT_OF_MEMORY;
   }
 
   /* Allocate our message */
-  messagelen = 4 + strlen(names.sUserName) + 1;
+  messagelen = sizeof(outdata) + strlen(user_name) + 1;
   message = malloc(messagelen);
   if(!message) {
-    Curl_safefree(trailer);
-    Curl_safefree(chlg);
+    free(trailer);
+    Curl_unicodefree(user_name);
 
     return CURLE_OUT_OF_MEMORY;
   }
@@ -592,15 +1168,16 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
      terminator. Note: Dispite RFC4752 Section 3.1 stating "The authorization
      identity is not terminated with the zero-valued (%x00) octet." it seems
      necessary to include it. */
-  memcpy(message, &outdata, 4);
-  strcpy((char *)message + 4, names.sUserName);
+  outdata = htonl(max_size) | sec_layer;
+  memcpy(message, &outdata, sizeof(outdata));
+  strcpy((char *) message + sizeof(outdata), user_name);
+  Curl_unicodefree(user_name);
 
   /* Allocate the padding */
   padding = malloc(sizes.cbBlockSize);
   if(!padding) {
-    Curl_safefree(message);
-    Curl_safefree(trailer);
-    Curl_safefree(chlg);
+    free(message);
+    free(trailer);
 
     return CURLE_OUT_OF_MEMORY;
   }
@@ -623,10 +1200,9 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
   status = s_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT,
                                     &wrap_desc, 0);
   if(status != SEC_E_OK) {
-    Curl_safefree(padding);
-    Curl_safefree(message);
-    Curl_safefree(trailer);
-    Curl_safefree(chlg);
+    free(padding);
+    free(message);
+    free(trailer);
 
     return CURLE_OUT_OF_MEMORY;
   }
@@ -636,10 +1212,9 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
                wrap_buf[2].cbBuffer;
   appdata = malloc(appdatalen);
   if(!appdata) {
-    Curl_safefree(padding);
-    Curl_safefree(message);
-    Curl_safefree(trailer);
-    Curl_safefree(chlg);
+    free(padding);
+    free(message);
+    free(trailer);
 
     return CURLE_OUT_OF_MEMORY;
   }
@@ -656,25 +1231,34 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
                               outlen);
 
   /* Free all of our local buffers */
-  Curl_safefree(appdata);
-  Curl_safefree(padding);
-  Curl_safefree(message);
-  Curl_safefree(trailer);
-  Curl_safefree(chlg);
+  free(appdata);
+  free(padding);
+  free(message);
+  free(trailer);
 
   return result;
 }
 
+/*
+ * Curl_sasl_gssapi_cleanup()
+ *
+ * This is used to clean up the gssapi specific data.
+ *
+ * Parameters:
+ *
+ * krb5     [in/out] - The kerberos 5 data struct being cleaned up.
+ *
+ */
 void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
 {
-  /* Free  the context */
+  /* Free our security context */
   if(krb5->context) {
     s_pSecFn->DeleteSecurityContext(krb5->context);
     free(krb5->context);
     krb5->context = NULL;
   }
 
-  /* Free the credientials handle */
+  /* Free our credentials handle */
   if(krb5->credentials) {
     s_pSecFn->FreeCredentialsHandle(krb5->credentials);
     free(krb5->credentials);
@@ -692,5 +1276,6 @@ void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
   /* Reset any variables */
   krb5->token_max = 0;
 }
+#endif /* USE_KERBEROS5 */
 
 #endif /* USE_WINDOWS_SSPI */
diff --git a/Utilities/cmcurl/lib/curl_sec.h b/Utilities/cmcurl/lib/curl_sec.h
index 82151e9..6c48da2 100644
--- a/Utilities/cmcurl/lib/curl_sec.h
+++ b/Utilities/cmcurl/lib/curl_sec.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,7 +30,7 @@ struct Curl_sec_client_mech {
   void (*end)(void *);
   int (*check_prot)(void *, int);
   int (*overhead)(void *, int, int);
-  int (*encode)(void *, const void*, int, int, void**, struct connectdata *);
+  int (*encode)(void *, const void*, int, int, void**);
   int (*decode)(void *, void*, int, int, struct connectdata *);
 };
 
diff --git a/Utilities/cmcurl/lib/curl_setup.h b/Utilities/cmcurl/lib/curl_setup.h
index 9cc5758..19c1baf 100644
--- a/Utilities/cmcurl/lib/curl_setup.h
+++ b/Utilities/cmcurl/lib/curl_setup.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -194,6 +194,9 @@
 #  ifndef CURL_DISABLE_GOPHER
 #    define CURL_DISABLE_GOPHER
 #  endif
+#  ifndef CURL_DISABLE_SMB
+#    define CURL_DISABLE_SMB
+#  endif
 #endif
 
 /*
@@ -616,26 +619,38 @@ int netware_init(void);
 
 #define LIBIDN_REQUIRED_VERSION "0.4.1"
 
-#if defined(USE_GNUTLS) || defined(USE_SSLEAY) || defined(USE_NSS) || \
-    defined(USE_QSOSSL) || defined(USE_POLARSSL) || defined(USE_AXTLS) || \
+#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
+    defined(USE_POLARSSL) || defined(USE_AXTLS) || \
     defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
     defined(USE_DARWINSSL) || defined(USE_GSKIT)
 #define USE_SSL    /* SSL support has been enabled */
 #endif
 
+/* Single point where USE_SPNEGO definition might be defined */
 #if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
     (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
 #define USE_SPNEGO
 #endif
 
-/* Single point where USE_NTLM definition might be done */
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_NTLM) && \
-    !defined(CURL_DISABLE_CRYPTO_AUTH)
-#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI) || \
-    defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL)
+/* Single point where USE_KERBEROS5 definition might be defined */
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
+    (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
+#define USE_KERBEROS5
+#endif
+
+/* Single point where USE_NTLM definition might be defined */
+#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
+    defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \
+    defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
+
+#ifdef HAVE_BORINGSSL /* BoringSSL is not NTLM capable */
+#undef USE_NTLM
+#else
 #define USE_NTLM
 #endif
 #endif
+#endif
 
 /* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */
 #if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE)
@@ -651,8 +666,10 @@ int netware_init(void);
 #if defined(__GNUC__) && ((__GNUC__ >= 3) || \
   ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
 #  define UNUSED_PARAM __attribute__((__unused__))
+#  define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
 #else
 #  define UNUSED_PARAM /*NOTHING*/
+#  define WARN_UNUSED_RESULT
 #endif
 
 /*
@@ -705,4 +722,24 @@ int netware_init(void);
 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
 #endif
 
+/* In Windows the default file mode is text but an application can override it.
+Therefore we specify it explicitly. https://github.com/bagder/curl/pull/258
+*/
+#if defined(WIN32) || defined(MSDOS)
+#define FOPEN_READTEXT "rt"
+#define FOPEN_WRITETEXT "wt"
+#elif defined(__CYGWIN__)
+/* Cygwin has specific behavior we need to address when WIN32 is not defined.
+https://cygwin.com/cygwin-ug-net/using-textbinary.html
+For write we want our output to have line endings of LF and be compatible with
+other Cygwin utilities. For read we want to handle input that may have line
+endings either CRLF or LF so 't' is appropriate.
+*/
+#define FOPEN_READTEXT "rt"
+#define FOPEN_WRITETEXT "w"
+#else
+#define FOPEN_READTEXT "r"
+#define FOPEN_WRITETEXT "w"
+#endif
+
 #endif /* HEADER_CURL_SETUP_H */
diff --git a/Utilities/cmcurl/lib/curl_sspi.c b/Utilities/cmcurl/lib/curl_sspi.c
index f09d288..070424d 100644
--- a/Utilities/cmcurl/lib/curl_sspi.c
+++ b/Utilities/cmcurl/lib/curl_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,17 +25,12 @@
 #ifdef USE_WINDOWS_SSPI
 
 #include <curl/curl.h>
-
 #include "curl_sspi.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#include "curl_memory.h"
 #include "curl_multibyte.h"
 #include "warnless.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /* We use our own typedef here since some headers might lack these */
@@ -98,20 +93,25 @@ CURLcode Curl_sspi_global_init(void)
        osver.dwPlatformId == platformId)
       securityDll = TRUE;
 #else
-    ULONGLONG majorVersionMask;
-    ULONGLONG platformIdMask;
+    ULONGLONG cm;
     OSVERSIONINFOEX osver;
 
     memset(&osver, 0, sizeof(osver));
     osver.dwOSVersionInfoSize = sizeof(osver);
     osver.dwMajorVersion = majorVersion;
     osver.dwPlatformId = platformId;
-    majorVersionMask = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
-    platformIdMask = VerSetConditionMask(0, VER_PLATFORMID, VER_EQUAL);
+
+    cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
 
     /* Verify the major version number == 4 and platform id == WIN_NT */
-    if(VerifyVersionInfo(&osver, VER_MAJORVERSION, majorVersionMask) &&
-       VerifyVersionInfo(&osver, VER_PLATFORMID, platformIdMask))
+    if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
+                                  VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR |
+                                  VER_PLATFORMID),
+                         cm))
       securityDll = TRUE;
 #endif
 
@@ -224,7 +224,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
 
   Curl_unicodefree(useranddomain.tchar_ptr);
 
-  /* Setup ntlm identity's password and length */
+  /* Setup the identity's password and length */
   passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
   if(!passwd.tchar_ptr)
     return CURLE_OUT_OF_MEMORY;
diff --git a/Utilities/cmcurl/lib/curl_sspi.h b/Utilities/cmcurl/lib/curl_sspi.h
index 5ab17d5..8655715 100644
--- a/Utilities/cmcurl/lib/curl_sspi.h
+++ b/Utilities/cmcurl/lib/curl_sspi.h
@@ -43,6 +43,10 @@
 CURLcode Curl_sspi_global_init(void);
 void Curl_sspi_global_cleanup(void);
 
+/* This is used to populate the domain in a SSPI identity structure */
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
+                                       SEC_WINNT_AUTH_IDENTITY *identity);
+
 /* This is used to generate an SSPI identity structure */
 CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
                                    SEC_WINNT_AUTH_IDENTITY *identity);
@@ -51,249 +55,276 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
 void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity);
 
 /* Forward-declaration of global variables defined in curl_sspi.c */
-
 extern HMODULE s_hSecDll;
 extern PSecurityFunctionTable s_pSecFn;
 
 /* Provide some definitions missing in old headers */
+#define SP_NAME_DIGEST              "WDigest"
+#define SP_NAME_NTLM                "NTLM"
+#define SP_NAME_NEGOTIATE           "Negotiate"
+#define SP_NAME_KERBEROS            "Kerberos"
+
+#ifndef ISC_REQ_USE_HTTP_STYLE
+#define ISC_REQ_USE_HTTP_STYLE                0x01000000
+#endif
+
+#ifndef ISC_RET_REPLAY_DETECT
+#define ISC_RET_REPLAY_DETECT                 0x00000004
+#endif
+
+#ifndef ISC_RET_SEQUENCE_DETECT
+#define ISC_RET_SEQUENCE_DETECT               0x00000008
+#endif
+
+#ifndef ISC_RET_CONFIDENTIALITY
+#define ISC_RET_CONFIDENTIALITY               0x00000010
+#endif
+
+#ifndef ISC_RET_ALLOCATED_MEMORY
+#define ISC_RET_ALLOCATED_MEMORY              0x00000100
+#endif
+
+#ifndef ISC_RET_STREAM
+#define ISC_RET_STREAM                        0x00008000
+#endif
 
 #ifndef SEC_E_INSUFFICIENT_MEMORY
-# define SEC_E_INSUFFICIENT_MEMORY             ((HRESULT)0x80090300L)
+# define SEC_E_INSUFFICIENT_MEMORY            ((HRESULT)0x80090300L)
 #endif
 #ifndef SEC_E_INVALID_HANDLE
-# define SEC_E_INVALID_HANDLE                  ((HRESULT)0x80090301L)
+# define SEC_E_INVALID_HANDLE                 ((HRESULT)0x80090301L)
 #endif
 #ifndef SEC_E_UNSUPPORTED_FUNCTION
-# define SEC_E_UNSUPPORTED_FUNCTION            ((HRESULT)0x80090302L)
+# define SEC_E_UNSUPPORTED_FUNCTION           ((HRESULT)0x80090302L)
 #endif
 #ifndef SEC_E_TARGET_UNKNOWN
-# define SEC_E_TARGET_UNKNOWN                  ((HRESULT)0x80090303L)
+# define SEC_E_TARGET_UNKNOWN                 ((HRESULT)0x80090303L)
 #endif
 #ifndef SEC_E_INTERNAL_ERROR
-# define SEC_E_INTERNAL_ERROR                  ((HRESULT)0x80090304L)
+# define SEC_E_INTERNAL_ERROR                 ((HRESULT)0x80090304L)
 #endif
 #ifndef SEC_E_SECPKG_NOT_FOUND
-# define SEC_E_SECPKG_NOT_FOUND                ((HRESULT)0x80090305L)
+# define SEC_E_SECPKG_NOT_FOUND               ((HRESULT)0x80090305L)
 #endif
 #ifndef SEC_E_NOT_OWNER
-# define SEC_E_NOT_OWNER                       ((HRESULT)0x80090306L)
+# define SEC_E_NOT_OWNER                      ((HRESULT)0x80090306L)
 #endif
 #ifndef SEC_E_CANNOT_INSTALL
-# define SEC_E_CANNOT_INSTALL                  ((HRESULT)0x80090307L)
+# define SEC_E_CANNOT_INSTALL                 ((HRESULT)0x80090307L)
 #endif
 #ifndef SEC_E_INVALID_TOKEN
-# define SEC_E_INVALID_TOKEN                   ((HRESULT)0x80090308L)
+# define SEC_E_INVALID_TOKEN                  ((HRESULT)0x80090308L)
 #endif
 #ifndef SEC_E_CANNOT_PACK
-# define SEC_E_CANNOT_PACK                     ((HRESULT)0x80090309L)
+# define SEC_E_CANNOT_PACK                    ((HRESULT)0x80090309L)
 #endif
 #ifndef SEC_E_QOP_NOT_SUPPORTED
-# define SEC_E_QOP_NOT_SUPPORTED               ((HRESULT)0x8009030AL)
+# define SEC_E_QOP_NOT_SUPPORTED              ((HRESULT)0x8009030AL)
 #endif
 #ifndef SEC_E_NO_IMPERSONATION
-# define SEC_E_NO_IMPERSONATION                ((HRESULT)0x8009030BL)
+# define SEC_E_NO_IMPERSONATION               ((HRESULT)0x8009030BL)
 #endif
 #ifndef SEC_E_LOGON_DENIED
-# define SEC_E_LOGON_DENIED                    ((HRESULT)0x8009030CL)
+# define SEC_E_LOGON_DENIED                   ((HRESULT)0x8009030CL)
 #endif
 #ifndef SEC_E_UNKNOWN_CREDENTIALS
-# define SEC_E_UNKNOWN_CREDENTIALS             ((HRESULT)0x8009030DL)
+# define SEC_E_UNKNOWN_CREDENTIALS            ((HRESULT)0x8009030DL)
 #endif
 #ifndef SEC_E_NO_CREDENTIALS
-# define SEC_E_NO_CREDENTIALS                  ((HRESULT)0x8009030EL)
+# define SEC_E_NO_CREDENTIALS                 ((HRESULT)0x8009030EL)
 #endif
 #ifndef SEC_E_MESSAGE_ALTERED
-# define SEC_E_MESSAGE_ALTERED                 ((HRESULT)0x8009030FL)
+# define SEC_E_MESSAGE_ALTERED                ((HRESULT)0x8009030FL)
 #endif
 #ifndef SEC_E_OUT_OF_SEQUENCE
-# define SEC_E_OUT_OF_SEQUENCE                 ((HRESULT)0x80090310L)
+# define SEC_E_OUT_OF_SEQUENCE                ((HRESULT)0x80090310L)
 #endif
 #ifndef SEC_E_NO_AUTHENTICATING_AUTHORITY
-# define SEC_E_NO_AUTHENTICATING_AUTHORITY     ((HRESULT)0x80090311L)
+# define SEC_E_NO_AUTHENTICATING_AUTHORITY    ((HRESULT)0x80090311L)
 #endif
 #ifndef SEC_E_BAD_PKGID
-# define SEC_E_BAD_PKGID                       ((HRESULT)0x80090316L)
+# define SEC_E_BAD_PKGID                      ((HRESULT)0x80090316L)
 #endif
 #ifndef SEC_E_CONTEXT_EXPIRED
-# define SEC_E_CONTEXT_EXPIRED                 ((HRESULT)0x80090317L)
+# define SEC_E_CONTEXT_EXPIRED                ((HRESULT)0x80090317L)
 #endif
 #ifndef SEC_E_INCOMPLETE_MESSAGE
-# define SEC_E_INCOMPLETE_MESSAGE              ((HRESULT)0x80090318L)
+# define SEC_E_INCOMPLETE_MESSAGE             ((HRESULT)0x80090318L)
 #endif
 #ifndef SEC_E_INCOMPLETE_CREDENTIALS
-# define SEC_E_INCOMPLETE_CREDENTIALS          ((HRESULT)0x80090320L)
+# define SEC_E_INCOMPLETE_CREDENTIALS         ((HRESULT)0x80090320L)
 #endif
 #ifndef SEC_E_BUFFER_TOO_SMALL
-# define SEC_E_BUFFER_TOO_SMALL                ((HRESULT)0x80090321L)
+# define SEC_E_BUFFER_TOO_SMALL               ((HRESULT)0x80090321L)
 #endif
 #ifndef SEC_E_WRONG_PRINCIPAL
-# define SEC_E_WRONG_PRINCIPAL                 ((HRESULT)0x80090322L)
+# define SEC_E_WRONG_PRINCIPAL                ((HRESULT)0x80090322L)
 #endif
 #ifndef SEC_E_TIME_SKEW
-# define SEC_E_TIME_SKEW                       ((HRESULT)0x80090324L)
+# define SEC_E_TIME_SKEW                      ((HRESULT)0x80090324L)
 #endif
 #ifndef SEC_E_UNTRUSTED_ROOT
-# define SEC_E_UNTRUSTED_ROOT                  ((HRESULT)0x80090325L)
+# define SEC_E_UNTRUSTED_ROOT                 ((HRESULT)0x80090325L)
 #endif
 #ifndef SEC_E_ILLEGAL_MESSAGE
-# define SEC_E_ILLEGAL_MESSAGE                 ((HRESULT)0x80090326L)
+# define SEC_E_ILLEGAL_MESSAGE                ((HRESULT)0x80090326L)
 #endif
 #ifndef SEC_E_CERT_UNKNOWN
-# define SEC_E_CERT_UNKNOWN                    ((HRESULT)0x80090327L)
+# define SEC_E_CERT_UNKNOWN                   ((HRESULT)0x80090327L)
 #endif
 #ifndef SEC_E_CERT_EXPIRED
-# define SEC_E_CERT_EXPIRED                    ((HRESULT)0x80090328L)
+# define SEC_E_CERT_EXPIRED                   ((HRESULT)0x80090328L)
 #endif
 #ifndef SEC_E_ENCRYPT_FAILURE
-# define SEC_E_ENCRYPT_FAILURE                 ((HRESULT)0x80090329L)
+# define SEC_E_ENCRYPT_FAILURE                ((HRESULT)0x80090329L)
 #endif
 #ifndef SEC_E_DECRYPT_FAILURE
-# define SEC_E_DECRYPT_FAILURE                 ((HRESULT)0x80090330L)
+# define SEC_E_DECRYPT_FAILURE                ((HRESULT)0x80090330L)
 #endif
 #ifndef SEC_E_ALGORITHM_MISMATCH
-# define SEC_E_ALGORITHM_MISMATCH              ((HRESULT)0x80090331L)
+# define SEC_E_ALGORITHM_MISMATCH             ((HRESULT)0x80090331L)
 #endif
 #ifndef SEC_E_SECURITY_QOS_FAILED
-# define SEC_E_SECURITY_QOS_FAILED             ((HRESULT)0x80090332L)
+# define SEC_E_SECURITY_QOS_FAILED            ((HRESULT)0x80090332L)
 #endif
 #ifndef SEC_E_UNFINISHED_CONTEXT_DELETED
-# define SEC_E_UNFINISHED_CONTEXT_DELETED      ((HRESULT)0x80090333L)
+# define SEC_E_UNFINISHED_CONTEXT_DELETED     ((HRESULT)0x80090333L)
 #endif
 #ifndef SEC_E_NO_TGT_REPLY
-# define SEC_E_NO_TGT_REPLY                    ((HRESULT)0x80090334L)
+# define SEC_E_NO_TGT_REPLY                   ((HRESULT)0x80090334L)
 #endif
 #ifndef SEC_E_NO_IP_ADDRESSES
-# define SEC_E_NO_IP_ADDRESSES                 ((HRESULT)0x80090335L)
+# define SEC_E_NO_IP_ADDRESSES                ((HRESULT)0x80090335L)
 #endif
 #ifndef SEC_E_WRONG_CREDENTIAL_HANDLE
-# define SEC_E_WRONG_CREDENTIAL_HANDLE         ((HRESULT)0x80090336L)
+# define SEC_E_WRONG_CREDENTIAL_HANDLE        ((HRESULT)0x80090336L)
 #endif
 #ifndef SEC_E_CRYPTO_SYSTEM_INVALID
-# define SEC_E_CRYPTO_SYSTEM_INVALID           ((HRESULT)0x80090337L)
+# define SEC_E_CRYPTO_SYSTEM_INVALID          ((HRESULT)0x80090337L)
 #endif
 #ifndef SEC_E_MAX_REFERRALS_EXCEEDED
-# define SEC_E_MAX_REFERRALS_EXCEEDED          ((HRESULT)0x80090338L)
+# define SEC_E_MAX_REFERRALS_EXCEEDED         ((HRESULT)0x80090338L)
 #endif
 #ifndef SEC_E_MUST_BE_KDC
-# define SEC_E_MUST_BE_KDC                     ((HRESULT)0x80090339L)
+# define SEC_E_MUST_BE_KDC                    ((HRESULT)0x80090339L)
 #endif
 #ifndef SEC_E_STRONG_CRYPTO_NOT_SUPPORTED
-# define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED     ((HRESULT)0x8009033AL)
+# define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED    ((HRESULT)0x8009033AL)
 #endif
 #ifndef SEC_E_TOO_MANY_PRINCIPALS
-# define SEC_E_TOO_MANY_PRINCIPALS             ((HRESULT)0x8009033BL)
+# define SEC_E_TOO_MANY_PRINCIPALS            ((HRESULT)0x8009033BL)
 #endif
 #ifndef SEC_E_NO_PA_DATA
-# define SEC_E_NO_PA_DATA                      ((HRESULT)0x8009033CL)
+# define SEC_E_NO_PA_DATA                     ((HRESULT)0x8009033CL)
 #endif
 #ifndef SEC_E_PKINIT_NAME_MISMATCH
-# define SEC_E_PKINIT_NAME_MISMATCH            ((HRESULT)0x8009033DL)
+# define SEC_E_PKINIT_NAME_MISMATCH           ((HRESULT)0x8009033DL)
 #endif
 #ifndef SEC_E_SMARTCARD_LOGON_REQUIRED
-# define SEC_E_SMARTCARD_LOGON_REQUIRED        ((HRESULT)0x8009033EL)
+# define SEC_E_SMARTCARD_LOGON_REQUIRED       ((HRESULT)0x8009033EL)
 #endif
 #ifndef SEC_E_SHUTDOWN_IN_PROGRESS
-# define SEC_E_SHUTDOWN_IN_PROGRESS            ((HRESULT)0x8009033FL)
+# define SEC_E_SHUTDOWN_IN_PROGRESS           ((HRESULT)0x8009033FL)
 #endif
 #ifndef SEC_E_KDC_INVALID_REQUEST
-# define SEC_E_KDC_INVALID_REQUEST             ((HRESULT)0x80090340L)
+# define SEC_E_KDC_INVALID_REQUEST            ((HRESULT)0x80090340L)
 #endif
 #ifndef SEC_E_KDC_UNABLE_TO_REFER
-# define SEC_E_KDC_UNABLE_TO_REFER             ((HRESULT)0x80090341L)
+# define SEC_E_KDC_UNABLE_TO_REFER            ((HRESULT)0x80090341L)
 #endif
 #ifndef SEC_E_KDC_UNKNOWN_ETYPE
-# define SEC_E_KDC_UNKNOWN_ETYPE               ((HRESULT)0x80090342L)
+# define SEC_E_KDC_UNKNOWN_ETYPE              ((HRESULT)0x80090342L)
 #endif
 #ifndef SEC_E_UNSUPPORTED_PREAUTH
-# define SEC_E_UNSUPPORTED_PREAUTH             ((HRESULT)0x80090343L)
+# define SEC_E_UNSUPPORTED_PREAUTH            ((HRESULT)0x80090343L)
 #endif
 #ifndef SEC_E_DELEGATION_REQUIRED
-# define SEC_E_DELEGATION_REQUIRED             ((HRESULT)0x80090345L)
+# define SEC_E_DELEGATION_REQUIRED            ((HRESULT)0x80090345L)
 #endif
 #ifndef SEC_E_BAD_BINDINGS
-# define SEC_E_BAD_BINDINGS                    ((HRESULT)0x80090346L)
+# define SEC_E_BAD_BINDINGS                   ((HRESULT)0x80090346L)
 #endif
 #ifndef SEC_E_MULTIPLE_ACCOUNTS
-# define SEC_E_MULTIPLE_ACCOUNTS               ((HRESULT)0x80090347L)
+# define SEC_E_MULTIPLE_ACCOUNTS              ((HRESULT)0x80090347L)
 #endif
 #ifndef SEC_E_NO_KERB_KEY
-# define SEC_E_NO_KERB_KEY                     ((HRESULT)0x80090348L)
+# define SEC_E_NO_KERB_KEY                    ((HRESULT)0x80090348L)
 #endif
 #ifndef SEC_E_CERT_WRONG_USAGE
-# define SEC_E_CERT_WRONG_USAGE                ((HRESULT)0x80090349L)
+# define SEC_E_CERT_WRONG_USAGE               ((HRESULT)0x80090349L)
 #endif
 #ifndef SEC_E_DOWNGRADE_DETECTED
-# define SEC_E_DOWNGRADE_DETECTED              ((HRESULT)0x80090350L)
+# define SEC_E_DOWNGRADE_DETECTED             ((HRESULT)0x80090350L)
 #endif
 #ifndef SEC_E_SMARTCARD_CERT_REVOKED
-# define SEC_E_SMARTCARD_CERT_REVOKED          ((HRESULT)0x80090351L)
+# define SEC_E_SMARTCARD_CERT_REVOKED         ((HRESULT)0x80090351L)
 #endif
 #ifndef SEC_E_ISSUING_CA_UNTRUSTED
-# define SEC_E_ISSUING_CA_UNTRUSTED            ((HRESULT)0x80090352L)
+# define SEC_E_ISSUING_CA_UNTRUSTED           ((HRESULT)0x80090352L)
 #endif
 #ifndef SEC_E_REVOCATION_OFFLINE_C
-# define SEC_E_REVOCATION_OFFLINE_C            ((HRESULT)0x80090353L)
+# define SEC_E_REVOCATION_OFFLINE_C           ((HRESULT)0x80090353L)
 #endif
 #ifndef SEC_E_PKINIT_CLIENT_FAILURE
-# define SEC_E_PKINIT_CLIENT_FAILURE           ((HRESULT)0x80090354L)
+# define SEC_E_PKINIT_CLIENT_FAILURE          ((HRESULT)0x80090354L)
 #endif
 #ifndef SEC_E_SMARTCARD_CERT_EXPIRED
-# define SEC_E_SMARTCARD_CERT_EXPIRED          ((HRESULT)0x80090355L)
+# define SEC_E_SMARTCARD_CERT_EXPIRED         ((HRESULT)0x80090355L)
 #endif
 #ifndef SEC_E_NO_S4U_PROT_SUPPORT
-# define SEC_E_NO_S4U_PROT_SUPPORT             ((HRESULT)0x80090356L)
+# define SEC_E_NO_S4U_PROT_SUPPORT            ((HRESULT)0x80090356L)
 #endif
 #ifndef SEC_E_CROSSREALM_DELEGATION_FAILURE
-# define SEC_E_CROSSREALM_DELEGATION_FAILURE   ((HRESULT)0x80090357L)
+# define SEC_E_CROSSREALM_DELEGATION_FAILURE  ((HRESULT)0x80090357L)
 #endif
 #ifndef SEC_E_REVOCATION_OFFLINE_KDC
-# define SEC_E_REVOCATION_OFFLINE_KDC          ((HRESULT)0x80090358L)
+# define SEC_E_REVOCATION_OFFLINE_KDC         ((HRESULT)0x80090358L)
 #endif
 #ifndef SEC_E_ISSUING_CA_UNTRUSTED_KDC
-# define SEC_E_ISSUING_CA_UNTRUSTED_KDC        ((HRESULT)0x80090359L)
+# define SEC_E_ISSUING_CA_UNTRUSTED_KDC       ((HRESULT)0x80090359L)
 #endif
 #ifndef SEC_E_KDC_CERT_EXPIRED
-# define SEC_E_KDC_CERT_EXPIRED                ((HRESULT)0x8009035AL)
+# define SEC_E_KDC_CERT_EXPIRED               ((HRESULT)0x8009035AL)
 #endif
 #ifndef SEC_E_KDC_CERT_REVOKED
-# define SEC_E_KDC_CERT_REVOKED                ((HRESULT)0x8009035BL)
+# define SEC_E_KDC_CERT_REVOKED               ((HRESULT)0x8009035BL)
 #endif
 #ifndef SEC_E_INVALID_PARAMETER
-# define SEC_E_INVALID_PARAMETER               ((HRESULT)0x8009035DL)
+# define SEC_E_INVALID_PARAMETER              ((HRESULT)0x8009035DL)
 #endif
 #ifndef SEC_E_DELEGATION_POLICY
-# define SEC_E_DELEGATION_POLICY               ((HRESULT)0x8009035EL)
+# define SEC_E_DELEGATION_POLICY              ((HRESULT)0x8009035EL)
 #endif
 #ifndef SEC_E_POLICY_NLTM_ONLY
-# define SEC_E_POLICY_NLTM_ONLY                ((HRESULT)0x8009035FL)
+# define SEC_E_POLICY_NLTM_ONLY               ((HRESULT)0x8009035FL)
 #endif
 
 #ifndef SEC_I_CONTINUE_NEEDED
-# define SEC_I_CONTINUE_NEEDED                 ((HRESULT)0x00090312L)
+# define SEC_I_CONTINUE_NEEDED                ((HRESULT)0x00090312L)
 #endif
 #ifndef SEC_I_COMPLETE_NEEDED
-# define SEC_I_COMPLETE_NEEDED                 ((HRESULT)0x00090313L)
+# define SEC_I_COMPLETE_NEEDED                ((HRESULT)0x00090313L)
 #endif
 #ifndef SEC_I_COMPLETE_AND_CONTINUE
-# define SEC_I_COMPLETE_AND_CONTINUE           ((HRESULT)0x00090314L)
+# define SEC_I_COMPLETE_AND_CONTINUE          ((HRESULT)0x00090314L)
 #endif
 #ifndef SEC_I_LOCAL_LOGON
-# define SEC_I_LOCAL_LOGON                     ((HRESULT)0x00090315L)
+# define SEC_I_LOCAL_LOGON                    ((HRESULT)0x00090315L)
 #endif
 #ifndef SEC_I_CONTEXT_EXPIRED
-# define SEC_I_CONTEXT_EXPIRED                 ((HRESULT)0x00090317L)
+# define SEC_I_CONTEXT_EXPIRED                ((HRESULT)0x00090317L)
 #endif
 #ifndef SEC_I_INCOMPLETE_CREDENTIALS
-# define SEC_I_INCOMPLETE_CREDENTIALS          ((HRESULT)0x00090320L)
+# define SEC_I_INCOMPLETE_CREDENTIALS         ((HRESULT)0x00090320L)
 #endif
 #ifndef SEC_I_RENEGOTIATE
-# define SEC_I_RENEGOTIATE                     ((HRESULT)0x00090321L)
+# define SEC_I_RENEGOTIATE                    ((HRESULT)0x00090321L)
 #endif
 #ifndef SEC_I_NO_LSA_CONTEXT
-# define SEC_I_NO_LSA_CONTEXT                  ((HRESULT)0x00090323L)
+# define SEC_I_NO_LSA_CONTEXT                 ((HRESULT)0x00090323L)
 #endif
 #ifndef SEC_I_SIGNATURE_NEEDED
-# define SEC_I_SIGNATURE_NEEDED                ((HRESULT)0x0009035CL)
+# define SEC_I_SIGNATURE_NEEDED               ((HRESULT)0x0009035CL)
 #endif
 
 #ifdef UNICODE
diff --git a/Utilities/cmcurl/lib/curl_threads.c b/Utilities/cmcurl/lib/curl_threads.c
index d40e024..f9b812e 100644
--- a/Utilities/cmcurl/lib/curl_threads.c
+++ b/Utilities/cmcurl/lib/curl_threads.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -33,10 +33,6 @@
 #endif
 
 #include "curl_threads.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -77,8 +73,8 @@ curl_thread_t Curl_thread_create(unsigned int (*func) (void*), void *arg)
   return t;
 
 err:
-  Curl_safefree(t);
-  Curl_safefree(ac);
+  free(t);
+  free(ac);
   return curl_thread_t_null;
 }
 
@@ -123,7 +119,12 @@ void Curl_thread_destroy(curl_thread_t hnd)
 
 int Curl_thread_join(curl_thread_t *hnd)
 {
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+    (_WIN32_WINNT < _WIN32_WINNT_VISTA)
   int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
+#else
+  int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
+#endif
 
   Curl_thread_destroy(*hnd);
 
diff --git a/Utilities/cmcurl/lib/curl_threads.h b/Utilities/cmcurl/lib/curl_threads.h
index 6457cbb..0f3191a 100644
--- a/Utilities/cmcurl/lib/curl_threads.h
+++ b/Utilities/cmcurl/lib/curl_threads.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -37,7 +37,12 @@
 #  define curl_mutex_t           CRITICAL_SECTION
 #  define curl_thread_t          HANDLE
 #  define curl_thread_t_null     (HANDLE)0
-#  define Curl_mutex_init(m)     InitializeCriticalSection(m)
+#  if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+      (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+#    define Curl_mutex_init(m)   InitializeCriticalSection(m)
+#  else
+#    define Curl_mutex_init(m)   InitializeCriticalSectionEx(m, 0, 1)
+#  endif
 #  define Curl_mutex_acquire(m)  EnterCriticalSection(m)
 #  define Curl_mutex_release(m)  LeaveCriticalSection(m)
 #  define Curl_mutex_destroy(m)  DeleteCriticalSection(m)
diff --git a/Utilities/cmcurl/lib/curlx.h b/Utilities/cmcurl/lib/curlx.h
index 9dc90a0..979e7d7 100644
--- a/Utilities/cmcurl/lib/curlx.h
+++ b/Utilities/cmcurl/lib/curlx.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -90,8 +90,7 @@
 #ifdef ENABLE_CURLX_PRINTF
 /* If this define is set, we define all "standard" printf() functions to use
    the curlx_* version instead. It makes the source code transparent and
-   easier to understand/patch. Undefine them first in case _MPRINTF_REPLACE
-   is set. */
+   easier to understand/patch. Undefine them first. */
 # undef printf
 # undef fprintf
 # undef sprintf
diff --git a/Utilities/cmcurl/lib/dict.c b/Utilities/cmcurl/lib/dict.c
index 86ddfb9..06d7699 100644
--- a/Utilities/cmcurl/lib/dict.c
+++ b/Utilities/cmcurl/lib/dict.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -57,10 +57,6 @@
 #include "strequal.h"
 #include "dict.h"
 #include "rawstr.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -101,7 +97,7 @@ static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
   char *dictp;
   char *ptr;
   int len;
-  char byte;
+  char ch;
   int olen=0;
 
   newp = curl_easy_unescape(data, inputbuff, 0, &len);
@@ -113,13 +109,13 @@ static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
     /* According to RFC2229 section 2.2, these letters need to be escaped with
        \[letter] */
     for(ptr = newp;
-        (byte = *ptr) != 0;
+        (ch = *ptr) != 0;
         ptr++) {
-      if((byte <= 32) || (byte == 127) ||
-          (byte == '\'') || (byte == '\"') || (byte == '\\')) {
+      if((ch <= 32) || (ch == 127) ||
+          (ch == '\'') || (ch == '\"') || (ch == '\\')) {
         dictp[olen++] = '\\';
       }
-      dictp[olen++] = byte;
+      dictp[olen++] = ch;
     }
     dictp[olen]=0;
   }
diff --git a/Utilities/cmcurl/lib/easy.c b/Utilities/cmcurl/lib/easy.c
index 160712e..316acb1 100644
--- a/Utilities/cmcurl/lib/easy.c
+++ b/Utilities/cmcurl/lib/easy.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -60,7 +60,6 @@
 #include "hostip.h"
 #include "share.h"
 #include "strdup.h"
-#include "curl_memory.h"
 #include "progress.h"
 #include "easyif.h"
 #include "select.h"
@@ -74,11 +73,11 @@
 #include "conncache.h"
 #include "multiif.h"
 #include "sigpipe.h"
+#include "ssh.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
@@ -136,9 +135,9 @@ static CURLcode win32_init(void)
 
 #ifdef USE_WINDOWS_SSPI
   {
-    CURLcode err = Curl_sspi_global_init();
-    if(err != CURLE_OK)
-      return err;
+    CURLcode result = Curl_sspi_global_init();
+    if(result)
+      return result;
   }
 #endif
 
@@ -243,7 +242,7 @@ CURLcode curl_global_init(long flags)
     }
 
   if(flags & CURL_GLOBAL_WIN32)
-    if(win32_init() != CURLE_OK) {
+    if(win32_init()) {
       DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
       return CURLE_FAILED_INIT;
     }
@@ -265,7 +264,7 @@ CURLcode curl_global_init(long flags)
   idna_init();
 #endif
 
-  if(Curl_resolver_global_init() != CURLE_OK) {
+  if(Curl_resolver_global_init()) {
     DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
     return CURLE_FAILED_INIT;
   }
@@ -293,7 +292,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
                               curl_free_callback f, curl_realloc_callback r,
                               curl_strdup_callback s, curl_calloc_callback c)
 {
-  CURLcode code = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   /* Invalid input, return immediately */
   if(!m || !f || !r || !s || !c)
@@ -308,8 +307,8 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
   }
 
   /* Call the actual init function first */
-  code = curl_global_init(flags);
-  if(code == CURLE_OK) {
+  result = curl_global_init(flags);
+  if(!result) {
     Curl_cmalloc = m;
     Curl_cfree = f;
     Curl_cstrdup = s;
@@ -317,7 +316,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
     Curl_ccalloc = c;
   }
 
-  return code;
+  return result;
 }
 
 /**
@@ -357,13 +356,13 @@ void curl_global_cleanup(void)
  */
 CURL *curl_easy_init(void)
 {
-  CURLcode res;
+  CURLcode result;
   struct SessionHandle *data;
 
   /* Make sure we inited the global SSL stuff */
   if(!initialized) {
-    res = curl_global_init(CURL_GLOBAL_DEFAULT);
-    if(res) {
+    result = curl_global_init(CURL_GLOBAL_DEFAULT);
+    if(result) {
       /* something in the global init failed, return nothing */
       DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
       return NULL;
@@ -371,8 +370,8 @@ CURL *curl_easy_init(void)
   }
 
   /* We use curl_open() with undefined URL so far */
-  res = Curl_open(&data);
-  if(res != CURLE_OK) {
+  result = Curl_open(&data);
+  if(result) {
     DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
     return NULL;
   }
@@ -390,17 +389,17 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
 {
   va_list arg;
   struct SessionHandle *data = curl;
-  CURLcode ret;
+  CURLcode result;
 
   if(!curl)
     return CURLE_BAD_FUNCTION_ARGUMENT;
 
   va_start(arg, tag);
 
-  ret = Curl_setopt(data, tag, arg);
+  result = Curl_setopt(data, tag, arg);
 
   va_end(arg);
-  return ret;
+  return result;
 }
 
 #ifdef CURLDEBUG
@@ -490,6 +489,10 @@ static int events_socket(CURL *easy,      /* easy handle */
   struct events *ev = userp;
   struct socketmonitor *m;
   struct socketmonitor *prev=NULL;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) easy;
+#endif
   (void)socketp;
 
   m = ev->list;
@@ -570,7 +573,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
 {
   bool done = FALSE;
   CURLMcode mcode;
-  CURLcode rc = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   while(!done) {
     CURLMsg *msg;
@@ -630,6 +633,9 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
         ev->ms += curlx_tvdiff(after, before);
 
     }
+    else
+      return CURLE_RECV_ERROR;
+
     if(mcode)
       return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
 
@@ -637,12 +643,12 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
        second argument */
     msg = curl_multi_info_read(multi, &pollrc);
     if(msg) {
-      rc = msg->data.result;
+      result = msg->data.result;
       done = TRUE;
     }
   }
 
-  return rc;
+  return result;
 }
 
 
@@ -668,7 +674,7 @@ static CURLcode easy_transfer(CURLM *multi)
 {
   bool done = FALSE;
   CURLMcode mcode = CURLM_OK;
-  CURLcode code = CURLE_OK;
+  CURLcode result = CURLE_OK;
   struct timeval before;
   int without_fds = 0;  /* count number of consecutive returns from
                            curl_multi_wait() without any filedescriptors */
@@ -683,7 +689,7 @@ static CURLcode easy_transfer(CURLM *multi)
     if(mcode == CURLM_OK) {
       if(ret == -1) {
         /* poll() failed not on EINTR, indicate a network problem */
-        code = CURLE_RECV_ERROR;
+        result = CURLE_RECV_ERROR;
         break;
       }
       else if(ret == 0) {
@@ -714,7 +720,7 @@ static CURLcode easy_transfer(CURLM *multi)
       int rc;
       CURLMsg *msg = curl_multi_info_read(multi, &rc);
       if(msg) {
-        code = msg->data.result;
+        result = msg->data.result;
         done = TRUE;
       }
     }
@@ -728,7 +734,7 @@ static CURLcode easy_transfer(CURLM *multi)
             CURLE_BAD_FUNCTION_ARGUMENT;
   }
 
-  return code;
+  return result;
 }
 
 
@@ -753,7 +759,7 @@ static CURLcode easy_perform(struct SessionHandle *data, bool events)
 {
   CURLM *multi;
   CURLMcode mcode;
-  CURLcode code = CURLE_OK;
+  CURLcode result = CURLE_OK;
   SIGPIPE_VARIABLE(pipe_st);
 
   if(!data)
@@ -794,7 +800,7 @@ static CURLcode easy_perform(struct SessionHandle *data, bool events)
   data->multi = multi;
 
   /* run the transfer */
-  code = events ? easy_events(multi) : easy_transfer(multi);
+  result = events ? easy_events(multi) : easy_transfer(multi);
 
   /* ignoring the return code isn't nice, but atm we can't really handle
      a failure here, room for future improvement! */
@@ -803,7 +809,7 @@ static CURLcode easy_perform(struct SessionHandle *data, bool events)
   sigpipe_restore(&pipe_st);
 
   /* The multi handle is kept alive, owned by the easy handle */
-  return code;
+  return result;
 }
 
 
@@ -854,16 +860,16 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
 {
   va_list arg;
   void *paramp;
-  CURLcode ret;
+  CURLcode result;
   struct SessionHandle *data = (struct SessionHandle *)curl;
 
   va_start(arg, info);
   paramp = va_arg(arg, void *);
 
-  ret = Curl_getinfo(data, info, paramp);
+  result = Curl_getinfo(data, info, paramp);
 
   va_end(arg);
-  return ret;
+  return result;
 }
 
 /*
@@ -890,7 +896,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
   outcurl->state.headersize = HEADERSIZE;
 
   /* copy all userdefined values */
-  if(Curl_dupset(outcurl, data) != CURLE_OK)
+  if(Curl_dupset(outcurl, data))
     goto fail;
 
   /* the connection cache is setup on demand */
@@ -936,7 +942,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
 
   /* Clone the resolver handle, if present, for the new handle */
   if(Curl_resolver_duphandle(&outcurl->state.resolver,
-                             data->state.resolver) != CURLE_OK)
+                             data->state.resolver))
     goto fail;
 
   Curl_convert_setup(outcurl);
@@ -1018,73 +1024,15 @@ CURLcode curl_easy_pause(CURL *curl, int action)
     /* we have a buffer for sending that we now seem to be able to deliver
        since the receive pausing is lifted! */
 
-    /* get the pointer, type and length in local copies since the function may
-       return PAUSE again and then we'll get a new copy allocted and stored in
+    /* get the pointer in local copy since the function may return PAUSE
+       again and then we'll get a new copy allocted and stored in
        the tempwrite variables */
     char *tempwrite = data->state.tempwrite;
-    char *freewrite = tempwrite; /* store this pointer to free it later */
-    size_t tempsize = data->state.tempwritesize;
-    int temptype = data->state.tempwritetype;
-    size_t chunklen;
-
-    /* clear tempwrite here just to make sure it gets cleared if there's no
-       further use of it, and make sure we don't clear it after the function
-       invoke as it may have been set to a new value by then */
-    data->state.tempwrite = NULL;
-
-    /* since the write callback API is define to never exceed
-       CURL_MAX_WRITE_SIZE bytes in a single call, and since we may in fact
-       have more data than that in our buffer here, we must loop sending the
-       data in multiple calls until there's no data left or we get another
-       pause returned.
-
-       A tricky part is that the function we call will "buffer" the data
-       itself when it pauses on a particular buffer, so we may need to do some
-       extra trickery if we get a pause return here.
-    */
-    do {
-      chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
-
-      result = Curl_client_write(data->easy_conn,
-                                 temptype, tempwrite, chunklen);
-      if(result)
-        /* failures abort the loop at once */
-        break;
-
-      if(data->state.tempwrite && (tempsize - chunklen)) {
-        /* Ouch, the reading is again paused and the block we send is now
-           "cached". If this is the final chunk we can leave it like this, but
-           if we have more chunks that are cached after this, we need to free
-           the newly cached one and put back a version that is truly the entire
-           contents that is saved for later
-        */
-        char *newptr;
-
-        /* note that tempsize is still the size as before the callback was
-           used, and thus the whole piece of data to keep */
-        newptr = realloc(data->state.tempwrite, tempsize);
-
-        if(!newptr) {
-          free(data->state.tempwrite); /* free old area */
-          data->state.tempwrite = NULL;
-          result = CURLE_OUT_OF_MEMORY;
-          /* tempwrite will be freed further down */
-          break;
-        }
-        data->state.tempwrite = newptr; /* store new pointer */
-        memcpy(newptr, tempwrite, tempsize);
-        data->state.tempwritesize = tempsize; /* store new size */
-        /* tempwrite will be freed further down */
-        break; /* go back to pausing until further notice */
-      }
-      else {
-        tempsize -= chunklen;  /* left after the call above */
-        tempwrite += chunklen; /* advance the pointer */
-      }
 
-    } while((result == CURLE_OK) && tempsize);
-
-    free(freewrite); /* this is unconditionally no longer used */
+    data->state.tempwrite = NULL;
+    result = Curl_client_chop_write(data->easy_conn, data->state.tempwritetype,
+                                    tempwrite, data->state.tempwritesize);
+    free(tempwrite);
   }
 
   /* if there's no error and we're not pausing both directions, we want
@@ -1129,20 +1077,20 @@ static CURLcode easy_connection(struct SessionHandle *data,
 CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
 {
   curl_socket_t sfd;
-  CURLcode ret;
+  CURLcode result;
   ssize_t n1;
   struct connectdata *c;
   struct SessionHandle *data = (struct SessionHandle *)curl;
 
-  ret = easy_connection(data, &sfd, &c);
-  if(ret)
-    return ret;
+  result = easy_connection(data, &sfd, &c);
+  if(result)
+    return result;
 
   *n = 0;
-  ret = Curl_read(c, sfd, buffer, buflen, &n1);
+  result = Curl_read(c, sfd, buffer, buflen, &n1);
 
-  if(ret != CURLE_OK)
-    return ret;
+  if(result)
+    return result;
 
   *n = (size_t)n1;
 
@@ -1157,26 +1105,26 @@ CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
                         size_t *n)
 {
   curl_socket_t sfd;
-  CURLcode ret;
+  CURLcode result;
   ssize_t n1;
   struct connectdata *c = NULL;
   struct SessionHandle *data = (struct SessionHandle *)curl;
 
-  ret = easy_connection(data, &sfd, &c);
-  if(ret)
-    return ret;
+  result = easy_connection(data, &sfd, &c);
+  if(result)
+    return result;
 
   *n = 0;
-  ret = Curl_write(c, sfd, buffer, buflen, &n1);
+  result = Curl_write(c, sfd, buffer, buflen, &n1);
 
   if(n1 == -1)
     return CURLE_SEND_ERROR;
 
   /* detect EAGAIN */
-  if((CURLE_OK == ret) && (0 == n1))
+  if(!result && !n1)
     return CURLE_AGAIN;
 
   *n = (size_t)n1;
 
-  return ret;
+  return result;
 }
diff --git a/Utilities/cmcurl/lib/escape.c b/Utilities/cmcurl/lib/escape.c
index d7f8a8f..24abb93 100644
--- a/Utilities/cmcurl/lib/escape.c
+++ b/Utilities/cmcurl/lib/escape.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,16 +27,14 @@
 
 #include <curl/curl.h>
 
-#include "curl_memory.h"
 #include "urldata.h"
 #include "warnless.h"
 #include "non-ascii.h"
 #include "escape.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /* Portable character check (remember EBCDIC). Do not use isalnum() because
@@ -87,7 +85,7 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
   size_t newlen = alloc;
   size_t strindex=0;
   size_t length;
-  CURLcode res;
+  CURLcode result;
 
   ns = malloc(alloc);
   if(!ns)
@@ -115,8 +113,8 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
         }
       }
 
-      res = Curl_convert_to_network(handle, &in, 1);
-      if(res) {
+      result = Curl_convert_to_network(handle, &in, 1);
+      if(result) {
         /* Curl_convert_to_network calls failf if unsuccessful */
         free(ns);
         return NULL;
@@ -152,7 +150,7 @@ CURLcode Curl_urldecode(struct SessionHandle *data,
   unsigned char in;
   size_t strindex=0;
   unsigned long hex;
-  CURLcode res;
+  CURLcode result;
 
   if(!ns)
     return CURLE_OUT_OF_MEMORY;
@@ -172,16 +170,17 @@ CURLcode Curl_urldecode(struct SessionHandle *data,
 
       in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
 
-      res = Curl_convert_from_network(data, &in, 1);
-      if(res) {
+      result = Curl_convert_from_network(data, &in, 1);
+      if(result) {
         /* Curl_convert_from_network calls failf if unsuccessful */
         free(ns);
-        return res;
+        return result;
       }
 
       string+=2;
       alloc-=2;
     }
+
     if(reject_ctrl && (in < 0x20)) {
       free(ns);
       return CURLE_URL_MALFORMAT;
@@ -228,6 +227,5 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
    the library's memory system */
 void curl_free(void *p)
 {
-  if(p)
-    free(p);
+  free(p);
 }
diff --git a/Utilities/cmcurl/lib/file.c b/Utilities/cmcurl/lib/file.c
index 73df42e..175b107 100644
--- a/Utilities/cmcurl/lib/file.c
+++ b/Utilities/cmcurl/lib/file.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -59,14 +59,12 @@
 #include "getinfo.h"
 #include "transfer.h"
 #include "url.h"
-#include "curl_memory.h"
 #include "parsedate.h" /* for the week day and month names */
 #include "warnless.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
@@ -196,8 +194,9 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
   int i;
   char *actual_path;
 #endif
+  int real_path_len;
 
-  real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
+  real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
   if(!real_path)
     return CURLE_OUT_OF_MEMORY;
 
@@ -222,16 +221,23 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
      (actual_path[2] == ':' || actual_path[2] == '|')) {
     actual_path[2] = ':';
     actual_path++;
+    real_path_len--;
   }
 
   /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
-  for(i=0; actual_path[i] != '\0'; ++i)
+  for(i=0; i < real_path_len; ++i)
     if(actual_path[i] == '/')
       actual_path[i] = '\\';
+    else if(!actual_path[i]) /* binary zero */
+      return CURLE_URL_MALFORMAT;
 
   fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
   file->path = actual_path;
 #else
+  if(memchr(real_path, 0, real_path_len))
+    /* binary zeroes indicate foul play */
+    return CURLE_URL_MALFORMAT;
+
   fd = open_readonly(real_path, O_RDONLY);
   file->path = real_path;
 #endif
@@ -295,7 +301,7 @@ static CURLcode file_upload(struct connectdata *conn)
   const char *dir = strchr(file->path, DIRSEP);
   int fd;
   int mode;
-  CURLcode res=CURLE_OK;
+  CURLcode result = CURLE_OK;
   struct SessionHandle *data = conn->data;
   char *buf = data->state.buffer;
   size_t nread;
@@ -309,8 +315,6 @@ static CURLcode file_upload(struct connectdata *conn)
    * Since FILE: doesn't do the full init, we need to provide some extra
    * assignments here.
    */
-  conn->fread_func = data->set.fread_func;
-  conn->fread_in = data->set.in;
   conn->data->req.upload_fromhere = buf;
 
   if(!dir)
@@ -351,10 +355,10 @@ static CURLcode file_upload(struct connectdata *conn)
       data->state.resume_from = (curl_off_t)file_stat.st_size;
   }
 
-  while(res == CURLE_OK) {
+  while(!result) {
     int readcount;
-    res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
-    if(res)
+    result = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
+    if(result)
       break;
 
     if(readcount <= 0)  /* fix questionable compare error. curlvms */
@@ -381,7 +385,7 @@ static CURLcode file_upload(struct connectdata *conn)
     /* write the data to the target */
     nwrite = write(fd, buf2, nread);
     if(nwrite != nread) {
-      res = CURLE_SEND_ERROR;
+      result = CURLE_SEND_ERROR;
       break;
     }
 
@@ -390,16 +394,16 @@ static CURLcode file_upload(struct connectdata *conn)
     Curl_pgrsSetUploadCounter(data, bytecount);
 
     if(Curl_pgrsUpdate(conn))
-      res = CURLE_ABORTED_BY_CALLBACK;
+      result = CURLE_ABORTED_BY_CALLBACK;
     else
-      res = Curl_speedcheck(data, now);
+      result = Curl_speedcheck(data, now);
   }
-  if(!res && Curl_pgrsUpdate(conn))
-    res = CURLE_ABORTED_BY_CALLBACK;
+  if(!result && Curl_pgrsUpdate(conn))
+    result = CURLE_ABORTED_BY_CALLBACK;
 
   close(fd);
 
-  return res;
+  return result;
 }
 
 /*
@@ -417,7 +421,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
      are supported. This means that files on remotely mounted directories
      (via NFS, Samba, NT sharing) can be accessed through a file:// URL
   */
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
   struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
                           Windows version to have a different struct without
                           having to redefine the simple word 'stat' */
@@ -464,7 +468,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
      information. Which for FILE can't be much more than the file size and
      date. */
   if(data->set.opt_no_body && data->set.include_header && fstated) {
-    CURLcode result;
     snprintf(buf, sizeof(data->state.buffer),
              "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
     result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
@@ -546,7 +549,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
 
   Curl_pgrsTime(data, TIMER_STARTTRANSFER);
 
-  while(res == CURLE_OK) {
+  while(!result) {
     /* Don't fill a whole buffer if we want less than all data */
     size_t bytestoread =
       (expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ?
@@ -563,21 +566,21 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
     bytecount += nread;
     expected_size -= nread;
 
-    res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
-    if(res)
-      return res;
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
+    if(result)
+      return result;
 
     Curl_pgrsSetDownloadCounter(data, bytecount);
 
     if(Curl_pgrsUpdate(conn))
-      res = CURLE_ABORTED_BY_CALLBACK;
+      result = CURLE_ABORTED_BY_CALLBACK;
     else
-      res = Curl_speedcheck(data, now);
+      result = Curl_speedcheck(data, now);
   }
   if(Curl_pgrsUpdate(conn))
-    res = CURLE_ABORTED_BY_CALLBACK;
+    result = CURLE_ABORTED_BY_CALLBACK;
 
-  return res;
+  return result;
 }
 
 #endif
diff --git a/Utilities/cmcurl/lib/fileinfo.c b/Utilities/cmcurl/lib/fileinfo.c
index 8c8ee98..0904937 100644
--- a/Utilities/cmcurl/lib/fileinfo.c
+++ b/Utilities/cmcurl/lib/fileinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010-2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,10 +24,6 @@
 
 #include "strdup.h"
 #include "fileinfo.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
diff --git a/Utilities/cmcurl/lib/formdata.c b/Utilities/cmcurl/lib/formdata.c
index 3260928..9e8ce4e 100644
--- a/Utilities/cmcurl/lib/formdata.c
+++ b/Utilities/cmcurl/lib/formdata.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,7 +24,7 @@
 
 #include <curl/curl.h>
 
-#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
+#ifndef CURL_DISABLE_HTTP
 
 #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
 #include <libgen.h>
@@ -34,19 +34,14 @@
 #include "formdata.h"
 #include "vtls/vtls.h"
 #include "strequal.h"
-#include "curl_memory.h"
 #include "sendf.h"
+#include "strdup.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
-#endif  /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */
-
-#ifndef CURL_DISABLE_HTTP
-
 #ifndef HAVE_BASENAME
 static char *Curl_basename(char *path);
 #define basename(x)  Curl_basename((x))
@@ -214,46 +209,6 @@ static const char *ContentTypeForFilename(const char *filename,
 
 /***************************************************************************
  *
- * memdup()
- *
- * Copies the 'source' data to a newly allocated buffer buffer (that is
- * returned). Uses buffer_length if not null, else uses strlen to determine
- * the length of the buffer to be copied
- *
- * Returns the new pointer or NULL on failure.
- *
- ***************************************************************************/
-static char *memdup(const char *src, size_t buffer_length)
-{
-  size_t length;
-  bool add = FALSE;
-  char *buffer;
-
-  if(buffer_length)
-    length = buffer_length;
-  else if(src) {
-    length = strlen(src);
-    add = TRUE;
-  }
-  else
-    /* no length and a NULL src pointer! */
-    return strdup("");
-
-  buffer = malloc(length+add);
-  if(!buffer)
-    return NULL; /* fail */
-
-  memcpy(buffer, src, length);
-
-  /* if length unknown do null termination */
-  if(add)
-    buffer[length] = '\0';
-
-  return buffer;
-}
-
-/***************************************************************************
- *
  * FormAdd()
  *
  * Stores a formpost parameter and builds the appropriate linked list.
@@ -460,7 +415,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
               else {
                 form = AddFormInfo(fname, NULL, current_form);
                 if(!form) {
-                  Curl_safefree(fname);
+                  free(fname);
                   return_value = CURL_FORMADD_MEMORY;
                 }
                 else {
@@ -549,7 +504,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
               else {
                 form = AddFormInfo(NULL, type, current_form);
                 if(!form) {
-                  Curl_safefree(type);
+                  free(type);
                   return_value = CURL_FORMADD_MEMORY;
                 }
                 else {
@@ -682,9 +637,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
            (form == first_form) ) {
           /* Note that there's small risk that form->name is NULL here if the
              app passed in a bad combo, so we better check for that first. */
-          if(form->name)
+          if(form->name) {
             /* copy name (without strdup; possibly contains null characters) */
-            form->name = memdup(form->name, form->namelength);
+            form->name = Curl_memdup(form->name, form->namelength?
+                                     form->namelength:
+                                     strlen(form->name)+1);
+          }
           if(!form->name) {
             return_value = CURL_FORMADD_MEMORY;
             break;
@@ -693,9 +651,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
         }
         if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
                             HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
-                            HTTPPOST_CALLBACK)) ) {
+                            HTTPPOST_CALLBACK)) && form->value) {
           /* copy value (without strdup; possibly contains null characters) */
-          form->value = memdup(form->value, form->contentslength);
+          form->value = Curl_memdup(form->value, form->contentslength?
+                                    form->contentslength:
+                                    strlen(form->value)+1);
           if(!form->value) {
             return_value = CURL_FORMADD_MEMORY;
             break;
@@ -751,7 +711,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
      now by the httppost linked list */
   while(first_form) {
     FormInfo *ptr = first_form->more;
-    Curl_safefree(first_form);
+    free(first_form);
     first_form = ptr;
   }
 
@@ -796,7 +756,7 @@ curl_off_t VmsRealFileSize(const char * name,
   int ret_stat;
   FILE * file;
 
-  file = fopen(name, "r");
+  file = fopen(name, "r"); /* VMS */
   if(file == NULL)
     return 0;
 
@@ -954,13 +914,13 @@ void Curl_formclean(struct FormData **form_ptr)
 int curl_formget(struct curl_httppost *form, void *arg,
                  curl_formget_callback append)
 {
-  CURLcode rc;
+  CURLcode result;
   curl_off_t size;
   struct FormData *data, *ptr;
 
-  rc = Curl_getformdata(NULL, &data, form, NULL, &size);
-  if(rc != CURLE_OK)
-    return (int)rc;
+  result = Curl_getformdata(NULL, &data, form, NULL, &size);
+  if(result)
+    return (int)result;
 
   for(ptr = data; ptr; ptr = ptr->next) {
     if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
@@ -1009,19 +969,16 @@ void curl_formfree(struct curl_httppost *form)
     next=form->next;  /* the following form line */
 
     /* recurse to sub-contents */
-    if(form->more)
-      curl_formfree(form->more);
+    curl_formfree(form->more);
 
-    if(!(form->flags & HTTPPOST_PTRNAME) && form->name)
+    if(!(form->flags & HTTPPOST_PTRNAME))
       free(form->name); /* free the name */
     if(!(form->flags &
-         (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK)) &&
-       form->contents)
+         (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK))
+      )
       free(form->contents); /* free the contents */
-    if(form->contenttype)
-      free(form->contenttype); /* free the content type */
-    if(form->showfilename)
-      free(form->showfilename); /* free the faked file name */
+    free(form->contenttype); /* free the content type */
+    free(form->showfilename); /* free the faked file name */
     free(form);       /* free the struct */
 
   } while((form = next) != NULL); /* continue */
@@ -1111,7 +1068,7 @@ static CURLcode formdata_add_filename(const struct curl_httppost *file,
     /* filename need be escaped */
     filename_escaped = malloc(strlen(filename)*2+1);
     if(!filename_escaped) {
-      Curl_safefree(filebasename);
+      free(filebasename);
       return CURLE_OUT_OF_MEMORY;
     }
     p0 = filename_escaped;
@@ -1127,8 +1084,8 @@ static CURLcode formdata_add_filename(const struct curl_httppost *file,
   result = AddFormDataf(form, size,
                         "; filename=\"%s\"",
                         filename);
-  Curl_safefree(filename_escaped);
-  Curl_safefree(filebasename);
+  free(filename_escaped);
+  free(filebasename);
   return result;
 }
 
@@ -1178,7 +1135,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
                         boundary);
 
   if(result) {
-    Curl_safefree(boundary);
+    free(boundary);
     return result;
   }
   /* we DO NOT include that line in the total size of the POST, since it'll be
@@ -1221,7 +1178,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
       /* If used, this is a link to more file names, we must then do
          the magic to include several files with the same field name */
 
-      Curl_safefree(fileboundary);
+      free(fileboundary);
       fileboundary = formboundary(data);
       if(!fileboundary) {
         result = CURLE_OUT_OF_MEMORY;
@@ -1369,22 +1326,20 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
   } while((post = post->next) != NULL); /* for each field */
 
   /* end-boundary for everything */
-  if(CURLE_OK == result)
-    result = AddFormDataf(&form, &size,
-                          "\r\n--%s--\r\n",
-                          boundary);
+  if(!result)
+    result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary);
 
   if(result) {
     Curl_formclean(&firstform);
-    Curl_safefree(fileboundary);
-    Curl_safefree(boundary);
+    free(fileboundary);
+    free(boundary);
     return result;
   }
 
   *sizep = size;
 
-  Curl_safefree(fileboundary);
-  Curl_safefree(boundary);
+  free(fileboundary);
+  free(boundary);
 
   *finalform = firstform;
 
@@ -1430,7 +1385,7 @@ static FILE * vmsfopenread(const char *file, const char *mode) {
   case FAB$C_VAR:
   case FAB$C_VFC:
   case FAB$C_STMCR:
-    return fopen(file, "r");
+    return fopen(file, "r"); /* VMS */
     break;
   default:
     return fopen(file, "r", "rfm=stmlf", "ctx=stm");
diff --git a/Utilities/cmcurl/lib/ftp.c b/Utilities/cmcurl/lib/ftp.c
index 1644983..74c4032 100644
--- a/Utilities/cmcurl/lib/ftp.c
+++ b/Utilities/cmcurl/lib/ftp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -77,9 +77,7 @@
 #include "warnless.h"
 #include "http_proxy.h"
 #include "non-ascii.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -157,7 +155,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
                                  bool connected);
 
 /* easy-to-use macro: */
-#define PPSENDF(x,y,z)  if((result = Curl_pp_sendf(x,y,z)) != CURLE_OK) \
+#define PPSENDF(x,y,z)  if((result = Curl_pp_sendf(x,y,z)))     \
                               return result
 
 
@@ -285,19 +283,17 @@ static void freedirs(struct ftp_conn *ftpc)
   int i;
   if(ftpc->dirs) {
     for(i=0; i < ftpc->dirdepth; i++) {
-      if(ftpc->dirs[i]) {
-        free(ftpc->dirs[i]);
-        ftpc->dirs[i]=NULL;
-      }
+      free(ftpc->dirs[i]);
+      ftpc->dirs[i]=NULL;
     }
     free(ftpc->dirs);
     ftpc->dirs = NULL;
     ftpc->dirdepth = 0;
   }
-  if(ftpc->file) {
-    free(ftpc->file);
-    ftpc->file = NULL;
-  }
+  Curl_safefree(ftpc->file);
+
+  /* no longer of any use */
+  Curl_safefree(ftpc->newhost);
 }
 
 /* Returns non-zero if the given string contains CR (\r) or LF (\n),
@@ -346,7 +342,7 @@ static CURLcode AcceptServerConnect(struct connectdata *conn)
   infof(data, "Connection accepted from server\n");
 
   conn->sock[SECONDARYSOCKET] = s;
-  curlx_nonblock(s, TRUE); /* enable non-blocking */
+  (void)curlx_nonblock(s, TRUE); /* enable non-blocking */
   conn->sock_accepted[SECONDARYSOCKET] = TRUE;
 
   if(data->set.fsockopt) {
@@ -541,7 +537,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
 {
   struct SessionHandle *data = conn->data;
   long timeout_ms;
-  CURLcode ret = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   *connected = FALSE;
   infof(data, "Preparing for accepting server on data port\n");
@@ -557,22 +553,22 @@ static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
   }
 
   /* see if the connection request is already here */
-  ret = ReceivedServerConnect(conn, connected);
-  if(ret)
-    return ret;
+  result = ReceivedServerConnect(conn, connected);
+  if(result)
+    return result;
 
   if(*connected) {
-    ret = AcceptServerConnect(conn);
-    if(ret)
-      return ret;
+    result = AcceptServerConnect(conn);
+    if(result)
+      return result;
 
-    ret = InitiateTransfer(conn);
-    if(ret)
-      return ret;
+    result = InitiateTransfer(conn);
+    if(result)
+      return result;
   }
   else {
     /* Add timeout to multi handle and break out of the loop */
-    if(ret == CURLE_OK && *connected == FALSE) {
+    if(!result && *connected == FALSE) {
       if(data->set.accepttimeout > 0)
         Curl_expire(data, data->set.accepttimeout);
       else
@@ -580,7 +576,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
     }
   }
 
-  return ret;
+  return result;
 }
 
 /* macro to check for a three-digit ftp status code at the start of the
@@ -821,12 +817,19 @@ static void _state(struct connectdata *conn,
   )
 {
   struct ftp_conn *ftpc = &conn->proto.ftpc;
-#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+
+#if defined(DEBUGBUILD)
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) lineno;
+#else
   if(ftpc->state != newstate)
     infof(conn->data, "FTP %p (line %d) state change from %s to %s\n",
           (void *)ftpc, lineno, ftp_state_names[ftpc->state],
           ftp_state_names[newstate]);
 #endif
+#endif
+
   ftpc->state = newstate;
 }
 
@@ -1072,8 +1075,9 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
 
     if(*addr != '\0') {
       /* attempt to get the address of the given interface name */
-      switch(Curl_if2ip(conn->ip_addr->ai_family, conn->scope, addr,
-                     hbuf, sizeof(hbuf))) {
+      switch(Curl_if2ip(conn->ip_addr->ai_family,
+                        Curl_ipv6_scope(conn->ip_addr->ai_addr),
+                        conn->scope_id, addr, hbuf, sizeof(hbuf))) {
         case IF2IP_NOT_FOUND:
           /* not an interface, use the given string as host name instead */
           host = addr;
@@ -1097,7 +1101,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
     if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
       failf(data, "getsockname() failed: %s",
           Curl_strerror(conn, SOCKERRNO) );
-      Curl_safefree(addr);
+      free(addr);
       return CURLE_FTP_PORT_FAILED;
     }
     switch(sa->sa_family) {
@@ -1129,11 +1133,11 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
 
   if(res == NULL) {
     failf(data, "failed to resolve the address provided to PORT: %s", host);
-    Curl_safefree(addr);
+    free(addr);
     return CURLE_FTP_PORT_FAILED;
   }
 
-  Curl_safefree(addr);
+  free(addr);
   host = NULL;
 
   /* step 2, create a socket for the requested address */
@@ -1246,10 +1250,10 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
       continue;
 
     if((PORT == fcmd) && sa->sa_family != AF_INET)
-      /* PORT is ipv4 only */
+      /* PORT is IPv4 only */
       continue;
 
-    switch (sa->sa_family) {
+    switch(sa->sa_family) {
     case AF_INET:
       port = ntohs(sa4->sin_port);
       break;
@@ -1487,13 +1491,13 @@ static CURLcode ftp_state_list(struct connectdata *conn)
      The other ftp_filemethods will CWD into dir/dir/ first and
      then just do LIST (in that case: nothing to do here)
   */
-  char *cmd,*lstArg,*slashPos;
+  char *cmd, *lstArg, *slashPos;
 
   lstArg = NULL;
   if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
      data->state.path &&
      data->state.path[0] &&
-     strchr(data->state.path,'/')) {
+     strchr(data->state.path, '/')) {
 
     lstArg = strdup(data->state.path);
     if(!lstArg)
@@ -1503,7 +1507,7 @@ static CURLcode ftp_state_list(struct connectdata *conn)
     if(lstArg[strlen(lstArg) - 1] != '/')  {
 
       /* chop off the file part if format is dir/dir/file */
-      slashPos = strrchr(lstArg,'/');
+      slashPos = strrchr(lstArg, '/');
       if(slashPos)
         *(slashPos+1) = '\0';
     }
@@ -1517,19 +1521,16 @@ static CURLcode ftp_state_list(struct connectdata *conn)
                  lstArg? lstArg: "" );
 
   if(!cmd) {
-    if(lstArg)
-      free(lstArg);
+    free(lstArg);
     return CURLE_OUT_OF_MEMORY;
   }
 
   result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
 
-  if(lstArg)
-    free(lstArg);
-
+  free(lstArg);
   free(cmd);
 
-  if(result != CURLE_OK)
+  if(result)
     return result;
 
   state(conn, FTP_LIST);
@@ -1669,8 +1670,8 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
             BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
 
           size_t actuallyread =
-            conn->fread_func(data->state.buffer, 1, readthisamountnow,
-                             conn->fread_in);
+            data->set.fread_func(data->state.buffer, 1, readthisamountnow,
+                                 data->set.in);
 
           passed += actuallyread;
           if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
@@ -1807,6 +1808,13 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
 static CURLcode ftp_epsv_disable(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
+
+  if(conn->bits.ipv6) {
+    /* We can't disable EPSV when doing IPv6, so this is instead a fail */
+    failf(conn->data, "Failed EPSV attempt, exiting\n");
+    return CURLE_FTP_WEIRD_SERVER_REPLY;
+  }
+
   infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
   /* disable it for next transfer */
   conn->bits.ftp_use_epsv = FALSE;
@@ -1828,9 +1836,15 @@ static CURLcode proxy_magic(struct connectdata *conn,
                             bool *magicdone)
 {
   CURLcode result = CURLE_OK;
-  struct SessionHandle *data=conn->data;
+  struct SessionHandle *data = conn->data;
+
+#if defined(CURL_DISABLE_PROXY)
+  (void) newhost;
+  (void) newport;
+#endif
 
   *magicdone = FALSE;
+
   switch(conn->proxytype) {
   case CURLPROXY_SOCKS5:
   case CURLPROXY_SOCKS5_HOSTNAME:
@@ -1873,7 +1887,7 @@ static CURLcode proxy_magic(struct connectdata *conn,
     memset(&http_proxy, 0, sizeof(http_proxy));
     data->req.protop = &http_proxy;
 
-    result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
+    result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE);
 
     data->req.protop = ftp_save;
 
@@ -1888,9 +1902,26 @@ static CURLcode proxy_magic(struct connectdata *conn,
     else
       *magicdone = TRUE;
   }
+
   return result;
 }
 
+static char *control_address(struct connectdata *conn)
+{
+  /* Returns the control connection IP address.
+     If a proxy tunnel is used, returns the original host name instead, because
+     the effective control connection address is the proxy address,
+     not the ftp host. */
+  if(conn->bits.tunnel_proxy ||
+     conn->proxytype == CURLPROXY_SOCKS5 ||
+     conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
+     conn->proxytype == CURLPROXY_SOCKS4 ||
+     conn->proxytype == CURLPROXY_SOCKS4A)
+    return conn->host.name;
+
+  return conn->ip_addr_str;
+}
+
 static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
                                     int ftpcode)
 {
@@ -1902,6 +1933,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
   unsigned short connectport; /* the local port connect() should use! */
   char *str=&data->state.buffer[4];  /* start on the first letter */
 
+  /* if we come here again, make sure the former name is cleared */
+  Curl_safefree(ftpc->newhost);
+
   if((ftpc->count1 == 0) &&
      (ftpcode == 229)) {
     /* positive EPSV response */
@@ -1910,12 +1944,12 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
       unsigned int num;
       char separator[4];
       ptr++;
-      if(5  == sscanf(ptr, "%c%c%c%u%c",
-                      &separator[0],
-                      &separator[1],
-                      &separator[2],
-                      &num,
-                      &separator[3])) {
+      if(5 == sscanf(ptr, "%c%c%c%u%c",
+                     &separator[0],
+                     &separator[1],
+                     &separator[2],
+                     &num,
+                     &separator[3])) {
         const char sep1 = separator[0];
         int i;
 
@@ -1933,19 +1967,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
         }
         if(ptr) {
           ftpc->newport = (unsigned short)(num & 0xffff);
-
-          if(conn->bits.tunnel_proxy ||
-             conn->proxytype == CURLPROXY_SOCKS5 ||
-             conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
-             conn->proxytype == CURLPROXY_SOCKS4 ||
-             conn->proxytype == CURLPROXY_SOCKS4A)
-            /* proxy tunnel -> use other host info because ip_addr_str is the
-               proxy address not the ftp host */
-            snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
-                     conn->host.name);
-          else
-            /* use the same IP we are already connected to */
-            snprintf(ftpc->newhost, NEWHOST_BUFSIZE, "%s", conn->ip_addr_str);
+          ftpc->newhost = strdup(control_address(conn));
+          if(!ftpc->newhost)
+            return CURLE_OUT_OF_MEMORY;
         }
       }
       else
@@ -1973,8 +1997,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
      */
     while(*str) {
       if(6 == sscanf(str, "%d,%d,%d,%d,%d,%d",
-                      &ip[0], &ip[1], &ip[2], &ip[3],
-                      &port[0], &port[1]))
+                     &ip[0], &ip[1], &ip[2], &ip[3],
+                     &port[0], &port[1]))
         break;
       str++;
     }
@@ -1986,26 +2010,19 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
 
     /* we got OK from server */
     if(data->set.ftp_skip_ip) {
-      /* told to ignore the remotely given IP but instead use the one we used
+      /* told to ignore the remotely given IP but instead use the host we used
          for the control connection */
-      infof(data, "Skips %d.%d.%d.%d for data connection, uses %s instead\n",
+      infof(data, "Skip %d.%d.%d.%d for data connection, re-use %s instead\n",
             ip[0], ip[1], ip[2], ip[3],
-            conn->ip_addr_str);
-      if(conn->bits.tunnel_proxy ||
-         conn->proxytype == CURLPROXY_SOCKS5 ||
-         conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
-         conn->proxytype == CURLPROXY_SOCKS4 ||
-         conn->proxytype == CURLPROXY_SOCKS4A)
-        /* proxy tunnel -> use other host info because ip_addr_str is the
-           proxy address not the ftp host */
-        snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s", conn->host.name);
-      else
-        snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
-                 conn->ip_addr_str);
+            conn->host.name);
+      ftpc->newhost = strdup(control_address(conn));
     }
     else
-      snprintf(ftpc->newhost, sizeof(ftpc->newhost),
-               "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+      ftpc->newhost = aprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+
+    if(!ftpc->newhost)
+      return CURLE_OUT_OF_MEMORY;
+
     ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
   }
   else if(ftpc->count1 == 0) {
@@ -2056,9 +2073,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
   conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
   result = Curl_connecthost(conn, addr);
 
-  Curl_resolv_unlock(data, addr); /* we're done using this address */
-
   if(result) {
+    Curl_resolv_unlock(data, addr); /* we're done using this address */
     if(ftpc->count1 == 0 && ftpcode == 229)
       return ftp_epsv_disable(conn);
 
@@ -2074,8 +2090,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
 
   if(data->set.verbose)
     /* this just dumps information about this second connection */
-    ftp_pasv_verbose(conn, conn->ip_addr, ftpc->newhost, connectport);
+    ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
 
+  Curl_resolv_unlock(data, addr); /* we're done using this address */
   conn->bits.do_more = TRUE;
   state(conn, FTP_STOP); /* this phase is completed */
 
@@ -2090,7 +2107,9 @@ static CURLcode ftp_state_port_resp(struct connectdata *conn,
   ftpport fcmd = (ftpport)ftpc->count1;
   CURLcode result = CURLE_OK;
 
-  if(ftpcode != 200) {
+  /* The FTP spec tells a positive response should have code 200.
+     Be more permissive here to tolerate deviant servers. */
+  if(ftpcode / 100 != 2) {
     /* the command failed */
 
     if(EPRT == fcmd) {
@@ -2714,7 +2733,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
            set a valid level */
         Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]);
 
-        if(Curl_sec_login(conn) != CURLE_OK)
+        if(Curl_sec_login(conn))
           infof(data, "Logging in with password in cleartext!\n");
         else
           infof(data, "Authentication successful\n");
@@ -2765,7 +2784,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
       if((ftpcode == 234) || (ftpcode == 334)) {
         /* Curl_ssl_connect is BLOCKING */
         result = Curl_ssl_connect(conn, FIRSTSOCKET);
-        if(CURLE_OK == result) {
+        if(!result) {
           conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
           result = ftp_state_user(conn);
         }
@@ -2907,7 +2926,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
           if(!ftpc->server_os && dir[0] != '/') {
 
             result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
-            if(result != CURLE_OK) {
+            if(result) {
               free(dir);
               return result;
             }
@@ -2960,7 +2979,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
         if(strequal(os, "OS/400")) {
           /* Force OS400 name format 1. */
           result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
-          if(result != CURLE_OK) {
+          if(result) {
             free(os);
             return result;
           }
@@ -3254,8 +3273,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
   }
 
   /* now store a copy of the directory we are in */
-  if(ftpc->prevpath)
-    free(ftpc->prevpath);
+  free(ftpc->prevpath);
 
   if(data->set.wildcardmatch) {
     if(data->set.chunk_end && ftpc->file) {
@@ -3304,7 +3322,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
   /* shut down the socket to inform the server we're done */
 
 #ifdef _WIN32_WCE
-  shutdown(conn->sock[SECONDARYSOCKET],2);  /* SD_BOTH */
+  shutdown(conn->sock[SECONDARYSOCKET], 2);  /* SD_BOTH */
 #endif
 
   if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
@@ -3627,7 +3645,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
     if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
       /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
          aren't used so we blank their arguments. TODO: make this nicer */
-      result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0);
+      result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0, FALSE);
 
       return result;
     }
@@ -3736,7 +3754,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
     return result;
   }
 
-  if((result == CURLE_OK) && (ftp->transfer != FTPTRANSFER_BODY))
+  if(!result && (ftp->transfer != FTPTRANSFER_BODY))
     /* no data to transfer. FIX: it feels like a kludge to have this here
        too! */
     Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
@@ -3802,7 +3820,7 @@ static void wc_data_dtor(void *ptr)
   struct ftp_wc_tmpdata *tmp = ptr;
   if(tmp)
     Curl_ftp_parselist_data_free(&tmp->parser);
-  Curl_safefree(tmp);
+  free(tmp);
 }
 
 static CURLcode init_wc_data(struct connectdata *conn)
@@ -3810,7 +3828,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
   char *last_slash;
   char *path = conn->data->state.path;
   struct WildcardData *wildcard = &(conn->data->wildcard);
-  CURLcode ret = CURLE_OK;
+  CURLcode result = CURLE_OK;
   struct ftp_wc_tmpdata *ftp_tmp;
 
   last_slash = strrchr(conn->data->state.path, '/');
@@ -3818,8 +3836,8 @@ static CURLcode init_wc_data(struct connectdata *conn)
     last_slash++;
     if(last_slash[0] == '\0') {
       wildcard->state = CURLWC_CLEAN;
-      ret = ftp_parse_url_path(conn);
-      return ret;
+      result = ftp_parse_url_path(conn);
+      return result;
     }
     else {
       wildcard->pattern = strdup(last_slash);
@@ -3837,8 +3855,8 @@ static CURLcode init_wc_data(struct connectdata *conn)
     }
     else { /* only list */
       wildcard->state = CURLWC_CLEAN;
-      ret = ftp_parse_url_path(conn);
-      return ret;
+      result = ftp_parse_url_path(conn);
+      return result;
     }
   }
 
@@ -3856,7 +3874,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
   ftp_tmp->parser = Curl_ftp_parselist_data_alloc();
   if(!ftp_tmp->parser) {
     Curl_safefree(wildcard->pattern);
-    Curl_safefree(ftp_tmp);
+    free(ftp_tmp);
     return CURLE_OUT_OF_MEMORY;
   }
 
@@ -3868,13 +3886,13 @@ static CURLcode init_wc_data(struct connectdata *conn)
     conn->data->set.ftp_filemethod = FTPFILE_MULTICWD;
 
   /* try to parse ftp url */
-  ret = ftp_parse_url_path(conn);
-  if(ret) {
+  result = ftp_parse_url_path(conn);
+  if(result) {
     Curl_safefree(wildcard->pattern);
     wildcard->tmp_dtor(wildcard->tmp);
     wildcard->tmp_dtor = ZERO_NULL;
     wildcard->tmp = NULL;
-    return ret;
+    return result;
   }
 
   wildcard->path = strdup(conn->data->state.path);
@@ -3903,16 +3921,16 @@ static CURLcode init_wc_data(struct connectdata *conn)
 static CURLcode wc_statemach(struct connectdata *conn)
 {
   struct WildcardData * const wildcard = &(conn->data->wildcard);
-  CURLcode ret = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   switch (wildcard->state) {
   case CURLWC_INIT:
-    ret = init_wc_data(conn);
+    result = init_wc_data(conn);
     if(wildcard->state == CURLWC_CLEAN)
       /* only listing! */
       break;
     else
-      wildcard->state = ret ? CURLWC_ERROR : CURLWC_MATCHING;
+      wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
     break;
 
   case CURLWC_MATCHING: {
@@ -3976,10 +3994,9 @@ static CURLcode wc_statemach(struct connectdata *conn)
     if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
       ftpc->known_filesize = finfo->size;
 
-    ret = ftp_parse_url_path(conn);
-    if(ret) {
-      return ret;
-    }
+    result = ftp_parse_url_path(conn);
+    if(result)
+      return result;
 
     /* we don't need the Curl_fileinfo of first file anymore */
     Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
@@ -4003,11 +4020,11 @@ static CURLcode wc_statemach(struct connectdata *conn)
 
   case CURLWC_CLEAN: {
     struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
-    ret = CURLE_OK;
-    if(ftp_tmp) {
-      ret = Curl_ftp_parselist_geterror(ftp_tmp->parser);
-    }
-    wildcard->state = ret ? CURLWC_ERROR : CURLWC_DONE;
+    result = CURLE_OK;
+    if(ftp_tmp)
+      result = Curl_ftp_parselist_geterror(ftp_tmp->parser);
+
+    wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
   } break;
 
   case CURLWC_DONE:
@@ -4015,7 +4032,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
     break;
   }
 
-  return ret;
+  return result;
 }
 
 /***********************************************************************
@@ -4029,31 +4046,31 @@ static CURLcode wc_statemach(struct connectdata *conn)
  */
 static CURLcode ftp_do(struct connectdata *conn, bool *done)
 {
-  CURLcode retcode = CURLE_OK;
+  CURLcode result = CURLE_OK;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
   *done = FALSE; /* default to false */
   ftpc->wait_data_conn = FALSE; /* default to no such wait */
 
   if(conn->data->set.wildcardmatch) {
-    retcode = wc_statemach(conn);
+    result = wc_statemach(conn);
     if(conn->data->wildcard.state == CURLWC_SKIP ||
       conn->data->wildcard.state == CURLWC_DONE) {
       /* do not call ftp_regular_transfer */
       return CURLE_OK;
     }
-    if(retcode) /* error, loop or skipping the file */
-      return retcode;
+    if(result) /* error, loop or skipping the file */
+      return result;
   }
   else { /* no wildcard FSM needed */
-    retcode = ftp_parse_url_path(conn);
-    if(retcode)
-      return retcode;
+    result = ftp_parse_url_path(conn);
+    if(result)
+      return result;
   }
 
-  retcode = ftp_regular_transfer(conn, done);
+  result = ftp_regular_transfer(conn, done);
 
-  return retcode;
+  return result;
 }
 
 
@@ -4065,7 +4082,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
   char s[SBUF_SIZE];
   size_t write_len;
   char *sptr=s;
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
 #ifdef HAVE_GSSAPI
   enum protection_level data_sec = conn->data_prot;
 #endif
@@ -4080,23 +4097,23 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
 
   bytes_written=0;
 
-  res = Curl_convert_to_network(conn->data, s, write_len);
+  result = Curl_convert_to_network(conn->data, s, write_len);
   /* Curl_convert_to_network calls failf if unsuccessful */
-  if(res)
-    return(res);
+  if(result)
+    return result;
 
   for(;;) {
 #ifdef HAVE_GSSAPI
     conn->data_prot = PROT_CMD;
 #endif
-    res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
-                     &bytes_written);
+    result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
+                        &bytes_written);
 #ifdef HAVE_GSSAPI
     DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
     conn->data_prot = data_sec;
 #endif
 
-    if(CURLE_OK != res)
+    if(result)
       break;
 
     if(conn->data->set.verbose)
@@ -4111,7 +4128,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
       break;
   }
 
-  return res;
+  return result;
 }
 
 /***********************************************************************
@@ -4182,14 +4199,10 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
   }
 
   freedirs(ftpc);
-  if(ftpc->prevpath) {
-    free(ftpc->prevpath);
-    ftpc->prevpath = NULL;
-  }
-  if(ftpc->server_os) {
-    free(ftpc->server_os);
-    ftpc->server_os = NULL;
-  }
+  free(ftpc->prevpath);
+  ftpc->prevpath = NULL;
+  free(ftpc->server_os);
+  ftpc->server_os = NULL;
 
   Curl_pp_disconnect(pp);
 
@@ -4480,7 +4493,7 @@ CURLcode ftp_regular_transfer(struct connectdata *conn,
                        &connected, /* have we connected after PASV/PORT */
                        dophase_done); /* all commands in the DO-phase done? */
 
-  if(CURLE_OK == result) {
+  if(!result) {
 
     if(!*dophase_done)
       /* the DO phase has not completed yet */
diff --git a/Utilities/cmcurl/lib/ftp.h b/Utilities/cmcurl/lib/ftp.h
index b6bfc02..833447b 100644
--- a/Utilities/cmcurl/lib/ftp.h
+++ b/Utilities/cmcurl/lib/ftp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -147,11 +147,10 @@ struct ftp_conn {
   curl_off_t known_filesize; /* file size is different from -1, if wildcard
                                 LIST parsing was done and wc_statemach set
                                 it */
-  /* newhost must be able to hold a full IP-style address in ASCII, which
-     in the IPv6 case means 5*8-1 = 39 letters */
-#define NEWHOST_BUFSIZE 48
-  char newhost[NEWHOST_BUFSIZE]; /* this is the pair to connect the DATA... */
-  unsigned short newport;        /* connection to */
+  /* newhost is the (allocated) IP addr or host name to connect the data
+     connection to */
+  char *newhost;          /* this is the pair to connect the DATA... */
+  unsigned short newport; /* connection to */
 
 };
 
diff --git a/Utilities/cmcurl/lib/ftplistparser.c b/Utilities/cmcurl/lib/ftplistparser.c
index 4a46dd1..17e0a66 100644
--- a/Utilities/cmcurl/lib/ftplistparser.c
+++ b/Utilities/cmcurl/lib/ftplistparser.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,13 +23,13 @@
 /**
  * Now implemented:
  *
- * 1) UNIX version 1
+ * 1) Unix version 1
  * drwxr-xr-x 1 user01 ftp  512 Jan 29 23:32 prog
- * 2) UNIX version 2
+ * 2) Unix version 2
  * drwxr-xr-x 1 user01 ftp  512 Jan 29 1997  prog
- * 3) UNIX version 3
+ * 3) Unix version 3
  * drwxr-xr-x 1      1   1  512 Jan 29 23:32 prog
- * 4) UNIX symlink
+ * 4) Unix symlink
  * lrwxr-xr-x 1 user01 ftp  512 Jan 29 23:32 prog -> prog2000
  * 5) DOS style
  * 01-29-97 11:32PM <DIR> prog
@@ -49,10 +49,6 @@
 #include "ftp.h"
 #include "ftplistparser.h"
 #include "curl_fnmatch.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -191,8 +187,7 @@ struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void)
 
 void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data)
 {
-  if(*pl_data)
-    free(*pl_data);
+  free(*pl_data);
   *pl_data = NULL;
 }
 
@@ -365,7 +360,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
   struct ftp_parselist_data *parser = tmpdata->parser;
   struct curl_fileinfo *finfo;
   unsigned long i = 0;
-  CURLcode rc;
+  CURLcode result;
 
   if(parser->error) { /* error in previous call */
     /* scenario:
@@ -758,9 +753,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
             finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
             parser->offsets.filename = parser->item_offset;
             parser->state.UNIX.main = PL_UNIX_FILETYPE;
-            rc = ftp_pl_insert_finfo(conn, finfo);
-            if(rc) {
-              PL_ERROR(conn, rc);
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
               return bufflen;
             }
           }
@@ -770,9 +765,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
             finfo->b_data[parser->item_offset + parser->item_length] = 0;
             parser->offsets.filename = parser->item_offset;
             parser->state.UNIX.main = PL_UNIX_FILETYPE;
-            rc = ftp_pl_insert_finfo(conn, finfo);
-            if(rc) {
-              PL_ERROR(conn, rc);
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
               return bufflen;
             }
           }
@@ -866,9 +861,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
           else if(c == '\n') {
             finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
             parser->offsets.symlink_target = parser->item_offset;
-            rc = ftp_pl_insert_finfo(conn, finfo);
-            if(rc) {
-              PL_ERROR(conn, rc);
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
               return bufflen;
             }
             parser->state.UNIX.main = PL_UNIX_FILETYPE;
@@ -878,9 +873,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
           if(c == '\n') {
             finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
             parser->offsets.symlink_target = parser->item_offset;
-            rc = ftp_pl_insert_finfo(conn, finfo);
-            if(rc) {
-              PL_ERROR(conn, rc);
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
               return bufflen;
             }
             parser->state.UNIX.main = PL_UNIX_FILETYPE;
@@ -1011,9 +1006,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
             parser->offsets.filename = parser->item_offset;
             finfo->b_data[finfo->b_used - 1] = 0;
             parser->offsets.filename = parser->item_offset;
-            rc = ftp_pl_insert_finfo(conn, finfo);
-            if(rc) {
-              PL_ERROR(conn, rc);
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
               return bufflen;
             }
             parser->state.NT.main = PL_WINNT_DATE;
@@ -1023,9 +1018,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
         case PL_WINNT_FILENAME_WINEOL:
           if(c == '\n') {
             parser->offsets.filename = parser->item_offset;
-            rc = ftp_pl_insert_finfo(conn, finfo);
-            if(rc) {
-              PL_ERROR(conn, rc);
+            result = ftp_pl_insert_finfo(conn, finfo);
+            if(result) {
+              PL_ERROR(conn, result);
               return bufflen;
             }
             parser->state.NT.main = PL_WINNT_DATE;
@@ -1041,7 +1036,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
       }
       break;
     default:
-      return bufflen+1;
+      return bufflen + 1;
     }
 
     i++;
diff --git a/Utilities/cmcurl/lib/getinfo.c b/Utilities/cmcurl/lib/getinfo.c
index 8905d36..910f520 100644
--- a/Utilities/cmcurl/lib/getinfo.c
+++ b/Utilities/cmcurl/lib/getinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,12 +27,12 @@
 #include "urldata.h"
 #include "getinfo.h"
 
-#include "curl_memory.h"
 #include "vtls/vtls.h"
 #include "connect.h" /* Curl_getconnectinfo() */
 #include "progress.h"
 
-/* Make this the last #include */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /*
@@ -42,7 +42,7 @@
 CURLcode Curl_initinfo(struct SessionHandle *data)
 {
   struct Progress *pro = &data->progress;
-  struct PureInfo *info =&data->info;
+  struct PureInfo *info = &data->info;
 
   pro->t_nslookup = 0;
   pro->t_connect = 0;
@@ -58,8 +58,7 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
   info->filetime = -1; /* -1 is an illegal time and thus means unknown */
   info->timecond = FALSE;
 
-  if(info->contenttype)
-    free(info->contenttype);
+  free(info->contenttype);
   info->contenttype = NULL;
 
   info->header_size = 0;
@@ -116,6 +115,7 @@ static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
   default:
     return CURLE_BAD_FUNCTION_ARGUMENT;
   }
+
   return CURLE_OK;
 }
 
@@ -202,6 +202,7 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
   default:
     return CURLE_BAD_FUNCTION_ARGUMENT;
   }
+
   return CURLE_OK;
 }
 
@@ -254,6 +255,7 @@ static CURLcode getinfo_double(struct SessionHandle *data, CURLINFO info,
   default:
     return CURLE_BAD_FUNCTION_ARGUMENT;
   }
+
   return CURLE_OK;
 }
 
@@ -261,8 +263,8 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
                               struct curl_slist **param_slistp)
 {
   union {
-    struct curl_certinfo * to_certinfo;
-    struct curl_slist    * to_slist;
+    struct curl_certinfo *to_certinfo;
+    struct curl_slist    *to_slist;
   } ptr;
 
   switch(info) {
@@ -303,7 +305,7 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
         break; /* no SSL session found */
 
       /* Return the TLS session information from the relevant backend */
-#ifdef USE_SSLEAY
+#ifdef USE_OPENSSL
       internals = conn->ssl[sockindex].ctx;
 #endif
 #ifdef USE_GNUTLS
@@ -312,9 +314,6 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
 #ifdef USE_NSS
       internals = conn->ssl[sockindex].handle;
 #endif
-#ifdef USE_QSOSSL
-      internals = conn->ssl[sockindex].handle;
-#endif
 #ifdef USE_GSKIT
       internals = conn->ssl[sockindex].handle;
 #endif
@@ -331,22 +330,23 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
   default:
     return CURLE_BAD_FUNCTION_ARGUMENT;
   }
+
   return CURLE_OK;
 }
 
 CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
 {
   va_list arg;
-  long *param_longp=NULL;
-  double *param_doublep=NULL;
-  char **param_charp=NULL;
-  struct curl_slist **param_slistp=NULL;
+  long *param_longp = NULL;
+  double *param_doublep = NULL;
+  char **param_charp = NULL;
+  struct curl_slist **param_slistp = NULL;
   int type;
   /* default return code is to error out! */
-  CURLcode ret = CURLE_BAD_FUNCTION_ARGUMENT;
+  CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
 
   if(!data)
-    return ret;
+    return result;
 
   va_start(arg, info);
 
@@ -354,28 +354,29 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
   switch(type) {
   case CURLINFO_STRING:
     param_charp = va_arg(arg, char **);
-    if(NULL != param_charp)
-      ret = getinfo_char(data, info, param_charp);
+    if(param_charp)
+      result = getinfo_char(data, info, param_charp);
     break;
   case CURLINFO_LONG:
     param_longp = va_arg(arg, long *);
-    if(NULL != param_longp)
-      ret = getinfo_long(data, info, param_longp);
+    if(param_longp)
+      result = getinfo_long(data, info, param_longp);
     break;
   case CURLINFO_DOUBLE:
     param_doublep = va_arg(arg, double *);
-    if(NULL != param_doublep)
-      ret = getinfo_double(data, info, param_doublep);
+    if(param_doublep)
+      result = getinfo_double(data, info, param_doublep);
     break;
   case CURLINFO_SLIST:
     param_slistp = va_arg(arg, struct curl_slist **);
-    if(NULL != param_slistp)
-      ret = getinfo_slist(data, info, param_slistp);
+    if(param_slistp)
+      result = getinfo_slist(data, info, param_slistp);
     break;
   default:
     break;
   }
 
   va_end(arg);
-  return ret;
+
+  return result;
 }
diff --git a/Utilities/cmcurl/lib/gopher.c b/Utilities/cmcurl/lib/gopher.c
index b1dd65f..954cad8 100644
--- a/Utilities/cmcurl/lib/gopher.c
+++ b/Utilities/cmcurl/lib/gopher.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -36,10 +36,6 @@
 #include "select.h"
 #include "url.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -121,10 +117,10 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
 
   for(;;) {
     result = Curl_write(conn, sockfd, sel, k, &amount);
-    if(CURLE_OK == result) { /* Which may not have written it all! */
+    if(!result) { /* Which may not have written it all! */
       result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
       if(result) {
-        Curl_safefree(sel_org);
+        free(sel_org);
         return result;
       }
       k -= amount;
@@ -134,7 +130,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
     }
     else {
       failf(data, "Failed sending Gopher request");
-      Curl_safefree(sel_org);
+      free(sel_org);
       return result;
     }
     /* Don't busyloop. The entire loop thing is a work-around as it causes a
@@ -149,12 +145,12 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
     Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
   }
 
-  Curl_safefree(sel_org);
+  free(sel_org);
 
   /* We can use Curl_sendf to send the terminal \r\n relatively safely and
      save allocing another string/doing another _write loop. */
   result = Curl_sendf(sockfd, conn, "\r\n");
-  if(result != CURLE_OK) {
+  if(result) {
     failf(data, "Failed sending Gopher request");
     return result;
   }
diff --git a/Utilities/cmcurl/lib/hash.c b/Utilities/cmcurl/lib/hash.c
index 4a12e1a..c46760a 100644
--- a/Utilities/cmcurl/lib/hash.c
+++ b/Utilities/cmcurl/lib/hash.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,10 +24,6 @@
 
 #include "hash.h"
 #include "llist.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -93,32 +89,6 @@ Curl_hash_init(struct curl_hash *h,
   }
 }
 
-struct curl_hash *
-Curl_hash_alloc(int slots,
-                hash_function hfunc,
-                comp_function comparator,
-                curl_hash_dtor dtor)
-{
-  struct curl_hash *h;
-
-  if(!slots || !hfunc || !comparator ||!dtor) {
-    return NULL; /* failure */
-  }
-
-  h = malloc(sizeof(struct curl_hash));
-  if(h) {
-    if(Curl_hash_init(h, slots, hfunc, comparator, dtor)) {
-      /* failure */
-      free(h);
-      h = NULL;
-    }
-  }
-
-  return h;
-}
-
-
-
 static struct curl_hash_element *
 mk_hash_element(const void *key, size_t key_len, const void *p)
 {
@@ -242,8 +212,11 @@ Curl_hash_apply(curl_hash *h, void *user,
 }
 #endif
 
+/* Destroys all the entries in the given hash and resets its attributes,
+ * prepping the given hash for [static|dynamic] deallocation.
+ */
 void
-Curl_hash_clean(struct curl_hash *h)
+Curl_hash_destroy(struct curl_hash *h)
 {
   int i;
 
@@ -257,6 +230,17 @@ Curl_hash_clean(struct curl_hash *h)
   h->slots = 0;
 }
 
+/* Removes all the entries in the given hash.
+ *
+ * @unittest: 1602
+ */
+void
+Curl_hash_clean(struct curl_hash *h)
+{
+  Curl_hash_clean_with_criterium(h, NULL, NULL);
+}
+
+/* Cleans all entries that pass the comp function criteria. */
 void
 Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
                                int (*comp)(void *, void *))
@@ -276,7 +260,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
       struct curl_hash_element *he = le->ptr;
       lnext = le->next;
       /* ask the callback function if we shall remove this entry or not */
-      if(comp(user, he->ptr)) {
+      if(comp == NULL || comp(user, he->ptr)) {
         Curl_llist_remove(list, le, (void *) h);
         --h->size; /* one less entry in the hash now */
       }
@@ -285,17 +269,6 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
   }
 }
 
-void
-Curl_hash_destroy(struct curl_hash *h)
-{
-  if(!h)
-    return;
-
-  Curl_hash_clean(h);
-
-  free(h);
-}
-
 size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num)
 {
   const char* key_str = (const char *) key;
@@ -310,16 +283,11 @@ size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num)
   return (h % slots_num);
 }
 
-size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2, size_t key2_len)
+size_t Curl_str_key_compare(void *k1, size_t key1_len,
+                            void *k2, size_t key2_len)
 {
-  char *key1 = (char *)k1;
-  char *key2 = (char *)k2;
-
-  if(key1_len == key2_len &&
-      *key1 == *key2 &&
-      memcmp(key1, key2, key1_len) == 0) {
+  if((key1_len == key2_len) && !memcmp(k1, k2, key1_len))
     return 1;
-  }
 
   return 0;
 }
diff --git a/Utilities/cmcurl/lib/hash.h b/Utilities/cmcurl/lib/hash.h
index aa935d4..b13a236 100644
--- a/Utilities/cmcurl/lib/hash.h
+++ b/Utilities/cmcurl/lib/hash.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -74,22 +74,16 @@ int Curl_hash_init(struct curl_hash *h,
                    comp_function comparator,
                    curl_hash_dtor dtor);
 
-struct curl_hash *Curl_hash_alloc(int slots,
-                                  hash_function hfunc,
-                                  comp_function comparator,
-                                  curl_hash_dtor dtor);
-
 void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p);
 int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len);
 void *Curl_hash_pick(struct curl_hash *, void * key, size_t key_len);
 void Curl_hash_apply(struct curl_hash *h, void *user,
                      void (*cb)(void *user, void *ptr));
 int Curl_hash_count(struct curl_hash *h);
+void Curl_hash_destroy(struct curl_hash *h);
 void Curl_hash_clean(struct curl_hash *h);
 void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
                                     int (*comp)(void *, void *));
-void Curl_hash_destroy(struct curl_hash *h);
-
 size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num);
 size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2,
                             size_t key2_len);
diff --git a/Utilities/cmcurl/lib/hmac.c b/Utilities/cmcurl/lib/hmac.c
index dace820..0d2d5f4 100644
--- a/Utilities/cmcurl/lib/hmac.c
+++ b/Utilities/cmcurl/lib/hmac.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,10 +27,6 @@
 #ifndef CURL_DISABLE_CRYPTO_AUTH
 
 #include "curl_hmac.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
diff --git a/Utilities/cmcurl/lib/hostasyn.c b/Utilities/cmcurl/lib/hostasyn.c
index 8151b67..17b8be0 100644
--- a/Utilities/cmcurl/lib/hostasyn.c
+++ b/Utilities/cmcurl/lib/hostasyn.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -47,10 +47,6 @@
 #include "share.h"
 #include "strerror.h"
 #include "url.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -75,7 +71,7 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
                                 struct Curl_addrinfo *ai)
 {
   struct Curl_dns_entry *dns = NULL;
-  CURLcode rc = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   conn->async.status = status;
 
@@ -92,14 +88,14 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
       if(!dns) {
         /* failed to store, cleanup and return error */
         Curl_freeaddrinfo(ai);
-        rc = CURLE_OUT_OF_MEMORY;
+        result = CURLE_OUT_OF_MEMORY;
       }
 
       if(data->share)
         Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
     }
     else {
-      rc = CURLE_OUT_OF_MEMORY;
+      result = CURLE_OUT_OF_MEMORY;
     }
   }
 
@@ -110,9 +106,9 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
     async struct */
   conn->async.done = TRUE;
 
-  /* ipv4: The input hostent struct will be freed by ares when we return from
+  /* IPv4: The input hostent struct will be freed by ares when we return from
      this function */
-  return rc;
+  return result;
 }
 
 /* Call this function after Curl_connect() has returned async=TRUE and
@@ -123,21 +119,21 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
 CURLcode Curl_async_resolved(struct connectdata *conn,
                              bool *protocol_done)
 {
-  CURLcode code;
+  CURLcode result;
 
   if(conn->async.dns) {
     conn->dns_entry = conn->async.dns;
     conn->async.dns = NULL;
   }
 
-  code = Curl_setup_conn(conn, protocol_done);
+  result = Curl_setup_conn(conn, protocol_done);
 
-  if(code)
+  if(result)
     /* We're not allowed to return failure with memory left allocated
        in the connectdata struct, free those here */
     Curl_disconnect(conn, FALSE); /* close the connection */
 
-  return code;
+  return result;
 }
 
 /*
diff --git a/Utilities/cmcurl/lib/hostcheck.c b/Utilities/cmcurl/lib/hostcheck.c
index 42eb2ee..62a26e4 100644
--- a/Utilities/cmcurl/lib/hostcheck.c
+++ b/Utilities/cmcurl/lib/hostcheck.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,8 +22,7 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_SSLEAY) || defined(USE_AXTLS) || defined(USE_QSOSSL) || \
-    defined(USE_GSKIT)
+#if defined(USE_OPENSSL) || defined(USE_AXTLS) || defined(USE_GSKIT)
 /* these backends use functions from this file */
 
 #ifdef HAVE_NETINET_IN_H
@@ -145,4 +144,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
   return res;
 }
 
-#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT */
+#endif /* OPENSSL or AXTLS or GSKIT */
diff --git a/Utilities/cmcurl/lib/hostip.c b/Utilities/cmcurl/lib/hostip.c
index 73b3f82..82f3897 100644
--- a/Utilities/cmcurl/lib/hostip.c
+++ b/Utilities/cmcurl/lib/hostip.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -56,10 +56,7 @@
 #include "url.h"
 #include "inet_ntop.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -98,8 +95,8 @@
  * hostip.c   - method-independent resolver functions and utility functions
  * hostasyn.c - functions for asynchronous name resolves
  * hostsyn.c  - functions for synchronous name resolves
- * hostip4.c  - ipv4-specific functions
- * hostip6.c  - ipv6-specific functions
+ * hostip4.c  - IPv4 specific functions
+ * hostip6.c  - IPv6 specific functions
  *
  * The two asynchronous name resolver backends are implemented in:
  * asyn-ares.c   - functions for ares-using name resolves
@@ -140,11 +137,7 @@ struct curl_hash *Curl_global_host_cache_init(void)
 void Curl_global_host_cache_dtor(void)
 {
   if(host_cache_initialized) {
-    /* first make sure that any custom "CURLOPT_RESOLVE" names are
-       cleared off */
-    Curl_hostcache_clean(NULL, &hostname_cache);
-    /* then free the remaining hash completely */
-    Curl_hash_clean(&hostname_cache);
+    Curl_hash_destroy(&hostname_cache);
     host_cache_initialized = 0;
   }
 }
@@ -237,7 +230,8 @@ hostcache_timestamp_remove(void *datap, void *hc)
     (struct hostcache_prune_data *) datap;
   struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
 
-  return !c->inuse && (data->now - c->timestamp >= data->cache_timeout);
+  return (0 != c->timestamp)
+    && (data->now - c->timestamp >= data->cache_timeout);
 }
 
 /*
@@ -283,40 +277,54 @@ void Curl_hostcache_prune(struct SessionHandle *data)
     Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
 }
 
-/*
- * Check if the entry should be pruned. Assumes a locked cache.
- */
-static int
-remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
+#ifdef HAVE_SIGSETJMP
+/* Beware this is a global and unique instance. This is used to store the
+   return address that we can jump back to from inside a signal handler. This
+   is not thread-safe stuff. */
+sigjmp_buf curl_jmpenv;
+#endif
+
+/* lookup address, returns entry if found and not stale */
+static struct Curl_dns_entry *
+fetch_addr(struct connectdata *conn,
+                const char *hostname,
+                int port)
 {
-  struct hostcache_prune_data user;
+  char *entry_id = NULL;
+  struct Curl_dns_entry *dns = NULL;
+  size_t entry_len;
+  struct SessionHandle *data = conn->data;
 
-  if(!dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache ||
-     dns->inuse)
-    /* cache forever means never prune, and NULL hostcache means we can't do
-       it, if it still is in use then we leave it */
-    return 0;
+  /* Create an entry id, based upon the hostname and port */
+  entry_id = create_hostcache_id(hostname, port);
+  /* If we can't create the entry id, fail */
+  if(!entry_id)
+    return dns;
 
-  time(&user.now);
-  user.cache_timeout = data->set.dns_cache_timeout;
+  entry_len = strlen(entry_id);
 
-  if(!hostcache_timestamp_remove(&user,dns) )
-    return 0;
+  /* See if its already in our dns cache */
+  dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
 
-  Curl_hash_clean_with_criterium(data->dns.hostcache,
-                                 (void *) &user,
-                                 hostcache_timestamp_remove);
+  if(dns && (data->set.dns_cache_timeout != -1))  {
+    /* See whether the returned entry is stale. Done before we release lock */
+    struct hostcache_prune_data user;
 
-  return 1;
-}
+    time(&user.now);
+    user.cache_timeout = data->set.dns_cache_timeout;
 
+    if(hostcache_timestamp_remove(&user, dns)) {
+      infof(data, "Hostname in DNS cache was stale, zapped\n");
+      dns = NULL; /* the memory deallocation is being handled by the hash */
+      Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1);
+    }
+  }
 
-#ifdef HAVE_SIGSETJMP
-/* Beware this is a global and unique instance. This is used to store the
-   return address that we can jump back to from inside a signal handler. This
-   is not thread-safe stuff. */
-sigjmp_buf curl_jmpenv;
-#endif
+  /* free the allocated entry_id again */
+  free(entry_id);
+
+  return dns;
+}
 
 /*
  * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
@@ -328,35 +336,27 @@ sigjmp_buf curl_jmpenv;
  * lookups for the same hostname requested by different handles.
  *
  * Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
  */
 struct Curl_dns_entry *
 Curl_fetch_addr(struct connectdata *conn,
                 const char *hostname,
-                int port, int *stale)
+                int port)
 {
-  char *entry_id = NULL;
-  struct Curl_dns_entry *dns = NULL;
-  size_t entry_len;
   struct SessionHandle *data = conn->data;
+  struct Curl_dns_entry *dns = NULL;
 
-  /* Create an entry id, based upon the hostname and port */
-  entry_id = create_hostcache_id(hostname, port);
-  /* If we can't create the entry id, fail */
-  if(!entry_id)
-    return dns;
-
-  entry_len = strlen(entry_id);
+  if(data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
 
-  /* See if its already in our dns cache */
-  dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
+  dns = fetch_addr(conn, hostname, port);
 
-  /* free the allocated entry_id again */
-  free(entry_id);
+  if(dns) dns->inuse++; /* we use it! */
 
-  /* See whether the returned entry is stale. Done before we release lock */
-  *stale = remove_entry_if_stale(data, dns);
-  if(*stale)
-    dns = NULL; /* the memory deallocation is being handled by the hash */
+  if(data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
 
   return dns;
 }
@@ -395,11 +395,11 @@ Curl_cache_addr(struct SessionHandle *data,
     return NULL;
   }
 
-  dns->inuse = 0;   /* init to not used */
+  dns->inuse = 1;   /* the cache has the first reference */
   dns->addr = addr; /* this is the address(es) */
   time(&dns->timestamp);
   if(dns->timestamp == 0)
-    dns->timestamp = 1;   /* zero indicates that entry isn't in hash table */
+    dns->timestamp = 1;   /* zero indicates CURLOPT_RESOLVE entry */
 
   /* Store the resolved data in our DNS cache. */
   dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len+1,
@@ -448,21 +448,17 @@ int Curl_resolv(struct connectdata *conn,
   struct Curl_dns_entry *dns = NULL;
   struct SessionHandle *data = conn->data;
   CURLcode result;
-  int stale, rc = CURLRESOLV_ERROR; /* default to failure */
+  int rc = CURLRESOLV_ERROR; /* default to failure */
 
   *entry = NULL;
 
   if(data->share)
     Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
 
-  dns = Curl_fetch_addr(conn, hostname, port, &stale);
-
-  infof(data, "Hostname was %sfound in DNS cache\n", dns||stale?"":"NOT ");
-  if(stale)
-    infof(data, "Hostname in DNS cache was stale, zapped\n");
-
+  dns = fetch_addr(conn, hostname, port);
 
   if(dns) {
+    infof(data, "Hostname %s was found in DNS cache\n", hostname);
     dns->inuse++; /* we use it! */
     rc = CURLRESOLV_RESOLVED;
   }
@@ -611,32 +607,6 @@ int Curl_resolv_timeout(struct connectdata *conn,
        we want to wait less than one second we must bail out already now. */
     return CURLRESOLV_TIMEDOUT;
 
-  /*************************************************************
-   * Set signal handler to catch SIGALRM
-   * Store the old value to be able to set it back later!
-   *************************************************************/
-#ifdef HAVE_SIGACTION
-  sigaction(SIGALRM, NULL, &sigact);
-  keep_sigact = sigact;
-  keep_copysig = TRUE; /* yes, we have a copy */
-  sigact.sa_handler = alarmfunc;
-#ifdef SA_RESTART
-  /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
-  sigact.sa_flags &= ~SA_RESTART;
-#endif
-  /* now set the new struct */
-  sigaction(SIGALRM, &sigact, NULL);
-#else /* HAVE_SIGACTION */
-  /* no sigaction(), revert to the much lamer signal() */
-#ifdef HAVE_SIGNAL
-  keep_sigact = signal(SIGALRM, alarmfunc);
-#endif
-#endif /* HAVE_SIGACTION */
-
-  /* alarm() makes a signal get sent when the timeout fires off, and that
-     will abort system calls */
-  prev_alarm = alarm(curlx_sltoui(timeout/1000L));
-
   /* This allows us to time-out from the name resolver, as the timeout
      will generate a signal and we will siglongjmp() from that here.
      This technique has problems (see alarmfunc).
@@ -649,6 +619,33 @@ int Curl_resolv_timeout(struct connectdata *conn,
     rc = CURLRESOLV_ERROR;
     goto clean_up;
   }
+  else {
+    /*************************************************************
+     * Set signal handler to catch SIGALRM
+     * Store the old value to be able to set it back later!
+     *************************************************************/
+#ifdef HAVE_SIGACTION
+    sigaction(SIGALRM, NULL, &sigact);
+    keep_sigact = sigact;
+    keep_copysig = TRUE; /* yes, we have a copy */
+    sigact.sa_handler = alarmfunc;
+#ifdef SA_RESTART
+    /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
+    sigact.sa_flags &= ~SA_RESTART;
+#endif
+    /* now set the new struct */
+    sigaction(SIGALRM, &sigact, NULL);
+#else /* HAVE_SIGACTION */
+    /* no sigaction(), revert to the much lamer signal() */
+#ifdef HAVE_SIGNAL
+    keep_sigact = signal(SIGALRM, alarmfunc);
+#endif
+#endif /* HAVE_SIGACTION */
+
+    /* alarm() makes a signal get sent when the timeout fires off, and that
+       will abort system calls */
+    prev_alarm = alarm(curlx_sltoui(timeout/1000L));
+  }
 
 #else
 #ifndef CURLRES_ASYNCH
@@ -720,54 +717,37 @@ clean_up:
  */
 void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
 {
-  DEBUGASSERT(dns && (dns->inuse>0));
-
   if(data && data->share)
     Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
 
-  dns->inuse--;
-  /* only free if nobody is using AND it is not in hostcache (timestamp ==
-     0) */
-  if(dns->inuse == 0 && dns->timestamp == 0) {
-    Curl_freeaddrinfo(dns->addr);
-    free(dns);
-  }
+  freednsentry(dns);
 
   if(data && data->share)
     Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
 }
 
 /*
- * File-internal: free a cache dns entry.
+ * File-internal: release cache dns entry reference, free if inuse drops to 0
  */
 static void freednsentry(void *freethis)
 {
-  struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis;
+  struct Curl_dns_entry *dns = (struct Curl_dns_entry *) freethis;
+  DEBUGASSERT(dns && (dns->inuse>0));
 
-  /* mark the entry as not in hostcache */
-  p->timestamp = 0;
-  if(p->inuse == 0) {
-    Curl_freeaddrinfo(p->addr);
-    free(p);
+  dns->inuse--;
+  if(dns->inuse == 0) {
+    Curl_freeaddrinfo(dns->addr);
+    free(dns);
   }
 }
 
 /*
- * Curl_mk_dnscache() creates a new DNS cache and returns the handle for it.
+ * Curl_mk_dnscache() inits a new DNS cache and returns success/failure.
  */
-struct curl_hash *Curl_mk_dnscache(void)
+int Curl_mk_dnscache(struct curl_hash *hash)
 {
-  return Curl_hash_alloc(7, Curl_hash_str, Curl_str_key_compare, freednsentry);
-}
-
-static int hostcache_inuse(void *data, void *hc)
-{
-  struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
-
-  if(c->inuse == 1)
-    Curl_resolv_unlock(data, c);
-
-  return 1; /* free all entries */
+  return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
+                        freednsentry);
 }
 
 /*
@@ -780,11 +760,13 @@ static int hostcache_inuse(void *data, void *hc)
 void Curl_hostcache_clean(struct SessionHandle *data,
                           struct curl_hash *hash)
 {
-  /* Entries added to the hostcache with the CURLOPT_RESOLVE function are
-   * still present in the cache with the inuse counter set to 1. Detect them
-   * and cleanup!
-   */
-  Curl_hash_clean_with_criterium(hash, data, hostcache_inuse);
+  if(data && data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  Curl_hash_clean(hash);
+
+  if(data && data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
 }
 
 
@@ -799,18 +781,52 @@ CURLcode Curl_loadhostpairs(struct SessionHandle *data)
     if(!hostp->data)
       continue;
     if(hostp->data[0] == '-') {
-      /* TODO: mark an entry for removal */
+      char *entry_id;
+      size_t entry_len;
+
+      if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) {
+        infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n",
+              hostp->data);
+        continue;
+      }
+
+      /* Create an entry id, based upon the hostname and port */
+      entry_id = create_hostcache_id(hostname, port);
+      /* If we can't create the entry id, fail */
+      if(!entry_id) {
+        return CURLE_OUT_OF_MEMORY;
+      }
+
+      entry_len = strlen(entry_id);
+
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      /* delete entry, ignore if it didn't exist */
+      Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1);
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+      /* free the allocated entry_id again */
+      free(entry_id);
     }
-    else if(3 == sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port,
-                        address)) {
+    else {
       struct Curl_dns_entry *dns;
       Curl_addrinfo *addr;
       char *entry_id;
       size_t entry_len;
 
+      if(3 != sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port,
+                     address)) {
+        infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n",
+              hostp->data);
+        continue;
+      }
+
       addr = Curl_str2addr(address, port);
       if(!addr) {
-        infof(data, "Resolve %s found illegal!\n", hostp->data);
+        infof(data, "Address in '%s' found illegal!\n", hostp->data);
         continue;
       }
 
@@ -833,9 +849,16 @@ CURLcode Curl_loadhostpairs(struct SessionHandle *data)
       /* free the allocated entry_id again */
       free(entry_id);
 
-      if(!dns)
+      if(!dns) {
         /* if not in the cache already, put this host in the cache */
         dns = Curl_cache_addr(data, addr, hostname, port);
+        if(dns) {
+          dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
+          /* release the returned reference; the cache itself will keep the
+           * entry alive: */
+          dns->inuse--;
+        }
+      }
       else
         /* this is a duplicate, free it again */
         Curl_freeaddrinfo(addr);
diff --git a/Utilities/cmcurl/lib/hostip.h b/Utilities/cmcurl/lib/hostip.h
index 4404651..d5b44bc 100644
--- a/Utilities/cmcurl/lib/hostip.h
+++ b/Utilities/cmcurl/lib/hostip.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -65,11 +65,10 @@ void Curl_global_host_cache_dtor(void);
 
 struct Curl_dns_entry {
   Curl_addrinfo *addr;
-  /* timestamp == 0 -- entry not in hostcache
-     timestamp != 0 -- entry is in hostcache */
+  /* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */
   time_t timestamp;
-  long inuse;      /* use-counter, make very sure you decrease this
-                      when you're done using the address you received */
+  /* use-counter, use Curl_resolv_unlock to release reference */
+  long inuse;
 };
 
 /*
@@ -92,7 +91,7 @@ int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
 
 #ifdef CURLRES_IPV6
 /*
- * Curl_ipv6works() returns TRUE if ipv6 seems to work.
+ * Curl_ipv6works() returns TRUE if IPv6 seems to work.
  */
 bool Curl_ipv6works(void);
 #else
@@ -125,8 +124,8 @@ void Curl_resolv_unlock(struct SessionHandle *data,
 /* for debugging purposes only: */
 void Curl_scan_cache_used(void *user, void *ptr);
 
-/* make a new dns cache and return the handle */
-struct curl_hash *Curl_mk_dnscache(void);
+/* init a new dns cache and return success */
+int Curl_mk_dnscache(struct curl_hash *hash);
 
 /* prune old entries from the DNS cache */
 void Curl_hostcache_prune(struct SessionHandle *data);
@@ -175,13 +174,14 @@ const char *Curl_printable_address(const Curl_addrinfo *ip,
  * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
  *
  * Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
  */
 struct Curl_dns_entry *
 Curl_fetch_addr(struct connectdata *conn,
                 const char *hostname,
-                int port,
-                int *stale);
-
+                int port);
 /*
  * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
  *
diff --git a/Utilities/cmcurl/lib/hostip4.c b/Utilities/cmcurl/lib/hostip4.c
index 1e39f4a..37b0369 100644
--- a/Utilities/cmcurl/lib/hostip4.c
+++ b/Utilities/cmcurl/lib/hostip4.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -48,18 +48,15 @@
 #include "strerror.h"
 #include "url.h"
 #include "inet_pton.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
 /***********************************************************************
- * Only for plain-ipv4 builds
+ * Only for plain IPv4 builds
  **********************************************************************/
-#ifdef CURLRES_IPV4 /* plain ipv4 code coming up */
+#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */
 /*
  * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
  * been set and returns TRUE if they are OK.
@@ -67,7 +64,7 @@
 bool Curl_ipvalid(struct connectdata *conn)
 {
   if(conn->ip_version == CURL_IPRESOLVE_V6)
-    /* an ipv6 address was requested and we can't get/use one */
+    /* An IPv6 address was requested and we can't get/use one */
     return FALSE;
 
   return TRUE; /* OK, proceed */
@@ -76,7 +73,7 @@ bool Curl_ipvalid(struct connectdata *conn)
 #ifdef CURLRES_SYNCH
 
 /*
- * Curl_getaddrinfo() - the ipv4 synchronous version.
+ * Curl_getaddrinfo() - the IPv4 synchronous version.
  *
  * The original code to this function was from the Dancer source code, written
  * by Bjorn Reese, it has since been patched and modified considerably.
diff --git a/Utilities/cmcurl/lib/hostip6.c b/Utilities/cmcurl/lib/hostip6.c
index 8327004..6ab131a 100644
--- a/Utilities/cmcurl/lib/hostip6.c
+++ b/Utilities/cmcurl/lib/hostip6.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -49,16 +49,13 @@
 #include "url.h"
 #include "inet_pton.h"
 #include "connect.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
 /***********************************************************************
- * Only for ipv6-enabled builds
+ * Only for IPv6-enabled builds
  **********************************************************************/
 #ifdef CURLRES_IPV6
 
@@ -97,7 +94,7 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
 #endif /* defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) */
 
 /*
- * Curl_ipv6works() returns TRUE if ipv6 seems to work.
+ * Curl_ipv6works() returns TRUE if IPv6 seems to work.
  */
 bool Curl_ipv6works(void)
 {
@@ -109,7 +106,7 @@ bool Curl_ipv6works(void)
     /* probe to see if we have a working IPv6 stack */
     curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
     if(s == CURL_SOCKET_BAD)
-      /* an ipv6 address was requested but we can't get/use one */
+      /* an IPv6 address was requested but we can't get/use one */
       ipv6_works = 0;
     else {
       ipv6_works = 1;
@@ -152,7 +149,7 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
 #endif
 
 /*
- * Curl_getaddrinfo() when built ipv6-enabled (non-threading and
+ * Curl_getaddrinfo() when built IPv6-enabled (non-threading and
  * non-ares version).
  *
  * Returns name information about the given hostname and port number. If
@@ -192,7 +189,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
   }
 
   if((pf != PF_INET) && !Curl_ipv6works())
-    /* the stack seems to be a non-ipv6 one */
+    /* The stack seems to be a non-IPv6 one */
     pf = PF_INET;
 
   memset(&hints, 0, sizeof(hints));
diff --git a/Utilities/cmcurl/lib/hostsyn.c b/Utilities/cmcurl/lib/hostsyn.c
index 4ad3c63..fb1de35 100644
--- a/Utilities/cmcurl/lib/hostsyn.c
+++ b/Utilities/cmcurl/lib/hostsyn.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -47,10 +47,6 @@
 #include "share.h"
 #include "strerror.h"
 #include "url.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
diff --git a/Utilities/cmcurl/lib/http.c b/Utilities/cmcurl/lib/http.c
index 35baa34..9817d72 100644
--- a/Utilities/cmcurl/lib/http.c
+++ b/Utilities/cmcurl/lib/http.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -63,7 +63,6 @@
 #include "share.h"
 #include "hostip.h"
 #include "http.h"
-#include "curl_memory.h"
 #include "select.h"
 #include "parsedate.h" /* for the week day and month names */
 #include "strtoofft.h"
@@ -73,15 +72,14 @@
 #include "http_proxy.h"
 #include "warnless.h"
 #include "non-ascii.h"
-#include "bundles.h"
+#include "conncache.h"
 #include "pipeline.h"
 #include "http2.h"
 #include "connect.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /*
@@ -155,12 +153,18 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn)
 {
   /* allocate the HTTP-specific struct for the SessionHandle, only to survive
      during this request */
+  struct HTTP *http;
   DEBUGASSERT(conn->data->req.protop == NULL);
 
-  conn->data->req.protop = calloc(1, sizeof(struct HTTP));
-  if(!conn->data->req.protop)
+  http = calloc(1, sizeof(struct HTTP));
+  if(!http)
     return CURLE_OUT_OF_MEMORY;
 
+  conn->data->req.protop = http;
+
+  Curl_http2_setup_conn(conn);
+  Curl_http2_setup_req(conn->data);
+
   return CURLE_OK;
 }
 
@@ -279,7 +283,7 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
   char **userp;
   const char *user;
   const char *pwd;
-  CURLcode error;
+  CURLcode result;
 
   if(proxy) {
     userp = &conn->allocptr.proxyuserpwd;
@@ -294,16 +298,16 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
 
   snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
 
-  error = Curl_base64_encode(data,
-                             data->state.buffer, strlen(data->state.buffer),
-                             &authorization, &size);
-  if(error)
-    return error;
+  result = Curl_base64_encode(data,
+                              data->state.buffer, strlen(data->state.buffer),
+                              &authorization, &size);
+  if(result)
+    return result;
 
   if(!authorization)
     return CURLE_REMOTE_ACCESS_DENIED;
 
-  Curl_safefree(*userp);
+  free(*userp);
   *userp = aprintf("%sAuthorization: Basic %s\r\n",
                    proxy?"Proxy-":"",
                    authorization);
@@ -392,16 +396,21 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
 
   bytessent = http->writebytecount;
 
-  if(conn->bits.authneg)
+  if(conn->bits.authneg) {
     /* This is a state where we are known to be negotiating and we don't send
        any data then. */
     expectsend = 0;
+  }
+  else if(!conn->bits.protoconnstart) {
+    /* HTTP CONNECT in progress: there is no body */
+    expectsend = 0;
+  }
   else {
     /* figure out how much data we are expected to send */
     switch(data->set.httpreq) {
     case HTTPREQ_POST:
-      if(data->set.postfieldsize != -1)
-        expectsend = data->set.postfieldsize;
+      if(data->state.infilesize != -1)
+        expectsend = data->state.infilesize;
       else if(data->set.postfields)
         expectsend = (curl_off_t)strlen(data->set.postfields);
       break;
@@ -420,6 +429,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
   conn->bits.rewindaftersend = FALSE; /* default */
 
   if((expectsend == -1) || (expectsend > bytessent)) {
+#if defined(USE_NTLM)
     /* There is still data left to send */
     if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
        (data->state.authhost.picked == CURLAUTH_NTLM) ||
@@ -439,6 +449,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
 
         return CURLE_OK;
       }
+
       if(conn->bits.close)
         /* this is already marked to get closed */
         return CURLE_OK;
@@ -447,9 +458,9 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
             CURL_FORMAT_CURL_OFF_T " bytes\n",
             (curl_off_t)(expectsend - bytessent));
     }
+#endif
 
-    /* This is not NTLM or many bytes left to send: close
-     */
+    /* This is not NTLM or many bytes left to send: close */
     connclose(conn, "Mid-auth HTTP and much data left to send");
     data->req.size = 0; /* don't download any more than 0 bytes */
 
@@ -476,7 +487,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
   struct SessionHandle *data = conn->data;
   bool pickhost = FALSE;
   bool pickproxy = FALSE;
-  CURLcode code = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
     /* this is a transient response code, ignore */
@@ -512,9 +523,9 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
     if((data->set.httpreq != HTTPREQ_GET) &&
        (data->set.httpreq != HTTPREQ_HEAD) &&
        !conn->bits.rewindaftersend) {
-      code = http_perhapsrewind(conn);
-      if(code)
-        return code;
+      result = http_perhapsrewind(conn);
+      if(result)
+        return result;
     }
   }
 
@@ -536,10 +547,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
   if(http_should_fail(conn)) {
     failf (data, "The requested URL returned error: %d",
            data->req.httpcode);
-    code = CURLE_HTTP_RETURNED_ERROR;
+    result = CURLE_HTTP_RETURNED_ERROR;
   }
 
-  return code;
+  return result;
 }
 
 
@@ -554,9 +565,11 @@ output_auth_headers(struct connectdata *conn,
                     const char *path,
                     bool proxy)
 {
-  struct SessionHandle *data = conn->data;
-  const char *auth=NULL;
+  const char *auth = NULL;
   CURLcode result = CURLE_OK;
+#if defined(USE_SPNEGO) || !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  struct SessionHandle *data = conn->data;
+#endif
 #ifdef USE_SPNEGO
   struct negotiatedata *negdata = proxy?
     &data->state.proxyneg:&data->state.negotiate;
@@ -672,7 +685,7 @@ Curl_http_output_auth(struct connectdata *conn,
 
   if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
      conn->bits.user_passwd)
-    /* continue please */ ;
+    /* continue please */;
   else {
     authhost->done = TRUE;
     authproxy->done = TRUE;
@@ -773,14 +786,13 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
   while(*auth) {
 #ifdef USE_SPNEGO
     if(checkprefix("Negotiate", auth)) {
-      int neg;
       *availp |= CURLAUTH_NEGOTIATE;
       authp->avail |= CURLAUTH_NEGOTIATE;
 
       if(authp->picked == CURLAUTH_NEGOTIATE) {
         if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
-          neg = Curl_input_negotiate(conn, proxy, auth);
-          if(neg == 0) {
+          CURLcode result = Curl_input_negotiate(conn, proxy, auth);
+          if(!result) {
             DEBUGASSERT(!data->req.newurl);
             data->req.newurl = strdup(data->change.url);
             if(!data->req.newurl)
@@ -804,9 +816,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
         if(authp->picked == CURLAUTH_NTLM ||
            authp->picked == CURLAUTH_NTLM_WB) {
           /* NTLM authentication is picked and activated */
-          CURLcode ntlm =
-            Curl_input_ntlm(conn, proxy, auth);
-          if(CURLE_OK == ntlm) {
+          CURLcode result = Curl_input_ntlm(conn, proxy, auth);
+          if(!result) {
             data->state.authproblem = FALSE;
 #ifdef NTLM_WB_ENABLED
             if(authp->picked == CURLAUTH_NTLM_WB) {
@@ -844,7 +855,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
             infof(data, "Ignoring duplicate digest auth header.\n");
           }
           else {
-            CURLdigest dig;
+            CURLcode result;
             *availp |= CURLAUTH_DIGEST;
             authp->avail |= CURLAUTH_DIGEST;
 
@@ -852,9 +863,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
              * authentication isn't activated yet, as we need to store the
              * incoming data from this header in case we are gonna use
              * Digest. */
-            dig = Curl_input_digest(conn, proxy, auth);
-
-            if(CURLDIGEST_FINE != dig) {
+            result = Curl_input_digest(conn, proxy, auth);
+            if(result) {
               infof(data, "Authentication problem. Ignoring this.\n");
               data->state.authproblem = TRUE;
             }
@@ -991,8 +1001,8 @@ static size_t readmoredata(char *buffer,
       /* move backup data into focus and continue on that */
       http->postdata = http->backup.postdata;
       http->postsize = http->backup.postsize;
-      conn->fread_func = http->backup.fread_func;
-      conn->fread_in = http->backup.fread_in;
+      conn->data->set.fread_func = http->backup.fread_func;
+      conn->data->set.in = http->backup.fread_in;
 
       http->sending++; /* move one step up */
 
@@ -1023,6 +1033,16 @@ Curl_send_buffer *Curl_add_buffer_init(void)
 }
 
 /*
+ * Curl_add_buffer_free() frees all associated resources.
+ */
+void Curl_add_buffer_free(Curl_send_buffer *buff)
+{
+  if(buff) /* deal with NULL input */
+    free(buff->buffer);
+  free(buff);
+}
+
+/*
  * Curl_add_buffer_send() sends a header buffer and frees all associated
  * memory.  Body data may be appended to the header data if desired.
  *
@@ -1041,7 +1061,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
 
 {
   ssize_t amount;
-  CURLcode res;
+  CURLcode result;
   char *ptr;
   size_t size;
   struct HTTP *http = conn->data->req.protop;
@@ -1064,14 +1084,12 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
 
   DEBUGASSERT(size > included_body_bytes);
 
-  res = Curl_convert_to_network(conn->data, ptr, headersize);
+  result = Curl_convert_to_network(conn->data, ptr, headersize);
   /* Curl_convert_to_network calls failf if unsuccessful */
-  if(res) {
+  if(result) {
     /* conversion failed, free memory and return to the caller */
-    if(in->buffer)
-      free(in->buffer);
-    free(in);
-    return res;
+    Curl_add_buffer_free(in);
+    return result;
   }
 
 
@@ -1096,9 +1114,9 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
   else
     sendsize = size;
 
-  res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
+  result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
 
-  if(CURLE_OK == res) {
+  if(!result) {
     /*
      * Note that we may not send the entire chunk at once, and we have a set
      * number of data bytes at the end of the big buffer (out of which we may
@@ -1139,14 +1157,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
         ptr = in->buffer + amount;
 
         /* backup the currently set pointers */
-        http->backup.fread_func = conn->fread_func;
-        http->backup.fread_in = conn->fread_in;
+        http->backup.fread_func = conn->data->set.fread_func;
+        http->backup.fread_in = conn->data->set.in;
         http->backup.postdata = http->postdata;
         http->backup.postsize = http->postsize;
 
         /* set the new pointers for the request-sending */
-        conn->fread_func = (curl_read_callback)readmoredata;
-        conn->fread_in = (void *)conn;
+        conn->data->set.fread_func = (curl_read_callback)readmoredata;
+        conn->data->set.in = (void *)conn;
         http->postdata = ptr;
         http->postsize = (curl_off_t)size;
 
@@ -1169,14 +1187,12 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
         */
         return CURLE_SEND_ERROR;
       else
-        conn->writechannel_inuse = FALSE;
+        Curl_pipeline_leave_write(conn);
     }
   }
-  if(in->buffer)
-    free(in->buffer);
-  free(in);
+  Curl_add_buffer_free(in);
 
-  return res;
+  return result;
 }
 
 
@@ -1197,8 +1213,7 @@ CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
     return result;
   }
   /* If we failed, we cleanup the whole buffer and return error */
-  if(in->buffer)
-    free(in->buffer);
+  free(in->buffer);
   free(in);
   return CURLE_OUT_OF_MEMORY;
 }
@@ -1378,7 +1393,7 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
 }
 #endif
 
-#if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
+#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
     defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS)
 /* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
    It should be made to query the generic SSL layer instead. */
@@ -1417,7 +1432,7 @@ static int https_getsock(struct connectdata *conn,
   return GETSOCK_BLANK;
 }
 #endif /* USE_SSL */
-#endif /* USE_SSLEAY || USE_GNUTLS || USE_SCHANNEL */
+#endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */
 
 /*
  * Curl_http_done() gets called from Curl_done() after a single HTTP request
@@ -1428,19 +1443,26 @@ CURLcode Curl_http_done(struct connectdata *conn,
                         CURLcode status, bool premature)
 {
   struct SessionHandle *data = conn->data;
-  struct HTTP *http =data->req.protop;
+  struct HTTP *http = data->req.protop;
+#ifdef USE_NGHTTP2
+  struct http_conn *httpc = &conn->proto.httpc;
+#endif
 
   Curl_unencode_cleanup(conn);
 
 #ifdef USE_SPNEGO
   if(data->state.proxyneg.state == GSS_AUTHSENT ||
-      data->state.negotiate.state == GSS_AUTHSENT)
+     data->state.negotiate.state == GSS_AUTHSENT) {
+    /* add forbid re-use if http-code != 401/407 as a WA only needed for
+     * 401/407 that signal auth failure (empty) otherwise state will be RECV
+     * with current code */
+    if((data->req.httpcode != 401) && (data->req.httpcode != 407))
+      connclose(conn, "Negotiate transfer completed");
     Curl_cleanup_negotiate(data);
+  }
 #endif
 
   /* set the proper values (possibly modified on POST) */
-  conn->fread_func = data->set.fread_func; /* restore */
-  conn->fread_in = data->set.in; /* restore */
   conn->seek_func = data->set.seek_func; /* restore */
   conn->seek_client = data->set.seek_client; /* restore */
 
@@ -1448,13 +1470,27 @@ CURLcode Curl_http_done(struct connectdata *conn,
     return CURLE_OK;
 
   if(http->send_buffer) {
-    Curl_send_buffer *buff = http->send_buffer;
-
-    free(buff->buffer);
-    free(buff);
+    Curl_add_buffer_free(http->send_buffer);
     http->send_buffer = NULL; /* clear the pointer */
   }
 
+#ifdef USE_NGHTTP2
+  if(http->header_recvbuf) {
+    DEBUGF(infof(data, "free header_recvbuf!!\n"));
+    Curl_add_buffer_free(http->header_recvbuf);
+    http->header_recvbuf = NULL; /* clear the pointer */
+    for(; http->push_headers_used > 0; --http->push_headers_used) {
+      free(http->push_headers[http->push_headers_used - 1]);
+    }
+    free(http->push_headers);
+    http->push_headers = NULL;
+  }
+  if(http->stream_id) {
+    nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
+    http->stream_id = 0;
+  }
+#endif
+
   if(HTTPREQ_POST_FORM == data->set.httpreq) {
     data->req.bytecount = http->readbytecount + http->writebytecount;
 
@@ -1468,8 +1504,8 @@ CURLcode Curl_http_done(struct connectdata *conn,
   else if(HTTPREQ_PUT == data->set.httpreq)
     data->req.bytecount = http->readbytecount + http->writebytecount;
 
-  if(status != CURLE_OK)
-    return (status);
+  if(status)
+    return status;
 
   if(!premature && /* this check is pointless when DONE is called before the
                       entire operation is complete */
@@ -1517,10 +1553,11 @@ static CURLcode expect100(struct SessionHandle *data,
   const char *ptr;
   data->state.expect100header = FALSE; /* default to false unless it is set
                                           to TRUE below */
-  if(use_http_1_1plus(data, conn)) {
-    /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
-       100-continue to the headers which actually speeds up post operations
-       (as there is one packet coming back from the web server) */
+  if(use_http_1_1plus(data, conn) &&
+     (conn->httpversion != 20)) {
+    /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
+       Expect: 100-continue to the headers which actually speeds up post
+       operations (as there is one packet coming back from the web server) */
     ptr = Curl_checkheaders(conn, "Expect:");
     if(ptr) {
       data->state.expect100header =
@@ -1529,7 +1566,7 @@ static CURLcode expect100(struct SessionHandle *data,
     else {
       result = Curl_add_bufferf(req_buffer,
                          "Expect: 100-continue\r\n");
-      if(result == CURLE_OK)
+      if(!result)
         data->state.expect100header = TRUE;
     }
   }
@@ -1659,10 +1696,8 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data,
 {
   const struct tm *tm;
   char *buf = data->state.buffer;
-  CURLcode result = CURLE_OK;
   struct tm keeptime;
-
-  result = Curl_gmtime(data->set.timevalue, &keeptime);
+  CURLcode result = Curl_gmtime(data->set.timevalue, &keeptime);
   if(result) {
     failf(data, "Invalid TIMEVALUE");
     return result;
@@ -1713,8 +1748,8 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data,
  */
 CURLcode Curl_http(struct connectdata *conn, bool *done)
 {
-  struct SessionHandle *data=conn->data;
-  CURLcode result=CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  CURLcode result = CURLE_OK;
   struct HTTP *http;
   const char *ppath = data->state.path;
   bool paste_ftp_userpwd = FALSE;
@@ -1724,7 +1759,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   const char *ptr;
   const char *request;
   Curl_HttpReq httpreq = data->set.httpreq;
+#if !defined(CURL_DISABLE_COOKIES)
   char *addcookies = NULL;
+#endif
   curl_off_t included_body = 0;
   const char *httpstring;
   Curl_send_buffer *req_buffer;
@@ -1738,8 +1775,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
 
   if(conn->httpversion < 20) { /* unless the connection is re-used and already
                                   http2 */
-    switch (conn->negnpn) {
-    case NPN_HTTP2:
+    switch(conn->negnpn) {
+    case CURL_HTTP_VERSION_2_0:
+      conn->httpversion = 20; /* we know we're on HTTP/2 now */
       result = Curl_http2_init(conn);
       if(result)
         return result;
@@ -1748,11 +1786,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       if(result)
         return result;
 
-      result = Curl_http2_switched(conn);
+      result = Curl_http2_switched(conn, NULL, 0);
       if(result)
         return result;
       break;
-    case NPN_HTTP1_1:
+    case CURL_HTTP_VERSION_1_1:
       /* continue with HTTP/1.1 when explicitly requested */
       break;
     default:
@@ -1770,10 +1808,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   http = data->req.protop;
 
   if(!data->state.this_is_a_follow) {
-    /* this is not a followed location, get the original host name */
-    if(data->state.first_host)
-      /* Free to avoid leaking memory on multiple requests*/
-      free(data->state.first_host);
+    /* Free to avoid leaking memory on multiple requests*/
+    free(data->state.first_host);
 
     data->state.first_host = strdup(conn->host.name);
     if(!data->state.first_host)
@@ -1817,7 +1853,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
      it might have been used in the proxy connect, but if we have got a header
      with the user-agent string specified, we erase the previously made string
      here. */
-  if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) {
+  if(Curl_checkheaders(conn, "User-Agent:")) {
     free(conn->allocptr.uagent);
     conn->allocptr.uagent=NULL;
   }
@@ -1846,8 +1882,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   else
     conn->allocptr.ref = NULL;
 
+#if !defined(CURL_DISABLE_COOKIES)
   if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
     addcookies = data->set.str[STRING_COOKIE];
+#endif
 
   if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
      data->set.str[STRING_ENCODING]) {
@@ -1958,7 +1996,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     }
 #endif
 
-    conn->allocptr.host = NULL;
+    if(strcmp("Host:", ptr)) {
+      conn->allocptr.host = aprintf("%s\r\n", ptr);
+      if(!conn->allocptr.host)
+        return CURLE_OUT_OF_MEMORY;
+    }
+    else
+      /* when clearing the header */
+      conn->allocptr.host = NULL;
   }
   else {
     /* When building Host: headers, we must put the host name within
@@ -2153,8 +2198,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
        !Curl_checkheaders(conn, "Range:")) {
       /* if a line like this was already allocated, free the previous one */
-      if(conn->allocptr.rangeline)
-        free(conn->allocptr.rangeline);
+      free(conn->allocptr.rangeline);
       conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
                                          data->state.range);
     }
@@ -2162,8 +2206,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
             !Curl_checkheaders(conn, "Content-Range:")) {
 
       /* if a line like this was already allocated, free the previous one */
-      if(conn->allocptr.rangeline)
-        free(conn->allocptr.rangeline);
+      free(conn->allocptr.rangeline);
 
       if(data->set.set_resume_from < 0) {
         /* Upload resume was asked for, but we don't know the size of the
@@ -2227,11 +2270,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     Curl_add_bufferf(req_buffer,
                      "%s" /* ftp typecode (;type=x) */
                      " HTTP/%s\r\n" /* HTTP version */
+                     "%s" /* host */
                      "%s" /* proxyuserpwd */
                      "%s" /* userpwd */
                      "%s" /* range */
                      "%s" /* user agent */
-                     "%s" /* host */
                      "%s" /* accept */
                      "%s" /* TE: */
                      "%s" /* accept-encoding */
@@ -2241,6 +2284,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
 
                      ftp_typecode,
                      httpstring,
+                     (conn->allocptr.host?conn->allocptr.host:""),
                      conn->allocptr.proxyuserpwd?
                      conn->allocptr.proxyuserpwd:"",
                      conn->allocptr.userpwd?conn->allocptr.userpwd:"",
@@ -2250,7 +2294,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
                       *data->set.str[STRING_USERAGENT] &&
                       conn->allocptr.uagent)?
                      conn->allocptr.uagent:"",
-                     (conn->allocptr.host?conn->allocptr.host:""),
                      http->p_accept?http->p_accept:"",
                      conn->allocptr.te?conn->allocptr.te:"",
                      (data->set.str[STRING_ENCODING] &&
@@ -2266,18 +2309,26 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
                      te
       );
 
+  /* clear userpwd to avoid re-using credentials from re-used connections */
+  Curl_safefree(conn->allocptr.userpwd);
+
   /*
-   * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
-   * with basic and digest, it will be freed anyway by the next request
+   * Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
+   * with the connection and shouldn't be repeated over it either.
    */
-
-  Curl_safefree (conn->allocptr.userpwd);
-  conn->allocptr.userpwd = NULL;
+  switch (data->state.authproxy.picked) {
+  case CURLAUTH_NEGOTIATE:
+  case CURLAUTH_NTLM:
+  case CURLAUTH_NTLM_WB:
+    Curl_safefree(conn->allocptr.proxyuserpwd);
+    break;
+  }
 
   if(result)
     return result;
 
   if(!(conn->handler->flags&PROTOPT_SSL) &&
+     conn->httpversion != 20 &&
      (data->set.httpversion == CURL_HTTP_VERSION_2_0)) {
     /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
        over SSL */
@@ -2322,17 +2373,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       }
       Curl_cookie_freelist(store, FALSE); /* free the cookie list */
     }
-    if(addcookies && (CURLE_OK == result)) {
+    if(addcookies && !result) {
       if(!count)
         result = Curl_add_bufferf(req_buffer, "Cookie: ");
-      if(CURLE_OK == result) {
-        result = Curl_add_bufferf(req_buffer, "%s%s",
-                                  count?"; ":"",
+      if(!result) {
+        result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
                                   addcookies);
         count++;
       }
     }
-    if(count && (CURLE_OK == result))
+    if(count && !result)
       result = Curl_add_buffer(req_buffer, "\r\n", 2);
 
     if(result)
@@ -2384,14 +2434,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
 
     /* Get the currently set callback function pointer and store that in the
        form struct since we might want the actual user-provided callback later
-       on. The conn->fread_func pointer itself will be changed for the
+       on. The data->set.fread_func pointer itself will be changed for the
        multipart case to the function that returns a multipart formatted
        stream. */
-    http->form.fread_func = conn->fread_func;
+    http->form.fread_func = data->set.fread_func;
 
     /* Set the read function to read from the generated form data */
-    conn->fread_func = (curl_read_callback)Curl_FormReader;
-    conn->fread_in = &http->form;
+    data->set.fread_func = (curl_read_callback)Curl_FormReader;
+    data->set.in = &http->form;
 
     http->sending = HTTPSEND_BODY;
 
@@ -2511,8 +2561,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
       postsize = 0;
     else {
       /* figure out the size of the postfields */
-      postsize = (data->set.postfieldsize != -1)?
-        data->set.postfieldsize:
+      postsize = (data->state.infilesize != -1)?
+        data->state.infilesize:
         (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
     }
 
@@ -2584,17 +2634,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
           if(postsize) {
             /* Append the POST data chunky-style */
             result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
-            if(CURLE_OK == result) {
+            if(!result) {
               result = Curl_add_buffer(req_buffer, data->set.postfields,
                                        (size_t)postsize);
-              if(CURLE_OK == result)
-                 result = Curl_add_buffer(req_buffer, "\r\n", 2);
+              if(!result)
+                result = Curl_add_buffer(req_buffer, "\r\n", 2);
               included_body = postsize + 2;
             }
           }
-          if(CURLE_OK == result)
-            result = Curl_add_buffer(req_buffer,
-                                     "\x30\x0d\x0a\x0d\x0a", 5);
+          if(!result)
+            result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
           /* 0  CR  LF  CR  LF */
           included_body += 5;
         }
@@ -2610,8 +2659,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
 
         http->sending = HTTPSEND_BODY;
 
-        conn->fread_func = (curl_read_callback)readmoredata;
-        conn->fread_in = (void *)conn;
+        data->set.fread_func = (curl_read_callback)readmoredata;
+        data->set.in = (void *)conn;
 
         /* set the upload size to the progress meter */
         Curl_pgrsSetUploadSize(data, http->postsize);
@@ -2636,7 +2685,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
           return result;
       }
 
-      else if(data->set.postfieldsize) {
+      else if(data->state.infilesize) {
         /* set the upload size to the progress meter */
         Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
 
@@ -2997,10 +3046,12 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
             infof(data, "Received 101\n");
             k->upgr101 = UPGR101_RECEIVED;
 
-            /* switch to http2 now */
-            result = Curl_http2_switched(conn);
+            /* switch to http2 now. The bytes after response headers
+               are also processed here, otherwise they are lost. */
+            result = Curl_http2_switched(conn, k->str, *nread);
             if(result)
               return result;
+            *nread = 0;
           }
           break;
         default:
@@ -3025,6 +3076,19 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
         }
       }
 
+      /* At this point we have some idea about the fate of the connection.
+         If we are closing the connection it may result auth failure. */
+#if defined(USE_NTLM)
+      if(conn->bits.close &&
+         (((data->req.httpcode == 401) &&
+           (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
+          ((data->req.httpcode == 407) &&
+           (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
+        infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
+        data->state.authproblem = TRUE;
+      }
+#endif
+
       /*
        * When all the headers have been parsed, see if we should give
        * up and return an error.
@@ -3203,13 +3267,26 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
 #endif /* CURL_DOES_CONVERSIONS */
 
       if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+        /*
+         * https://tools.ietf.org/html/rfc7230#section-3.1.2
+         *
+         * The reponse code is always a three-digit number in HTTP as the spec
+         * says. We try to allow any number here, but we cannot make
+         * guarantees on future behaviors since it isn't within the protocol.
+         */
         nc = sscanf(HEADER1,
-                    " HTTP/%d.%d %3d",
+                    " HTTP/%d.%d %d",
                     &httpversion_major,
                     &conn->httpversion,
                     &k->httpcode);
         if(nc==3) {
           conn->httpversion += 10 * httpversion_major;
+
+          if(k->upgr101 == UPGR101_RECEIVED) {
+            /* supposedly upgraded to http2 now */
+            if(conn->httpversion != 20)
+              infof(data, "Lying server, not serving HTTP/2\n");
+          }
         }
         else {
           /* this is the real world, not a Nirvana
@@ -3287,20 +3364,25 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
           infof(data, "HTTP 1.0, assume close after body\n");
           connclose(conn, "HTTP/1.0 close after body");
         }
+        else if(conn->httpversion == 20 ||
+                (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
+          DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
+
+          /* HTTP/2 cannot blacklist multiplexing since it is a core
+             functionality of the protocol */
+          conn->bundle->multiuse = BUNDLE_MULTIPLEX;
+        }
         else if(conn->httpversion >= 11 &&
                 !conn->bits.close) {
-          struct connectbundle *cb_ptr;
-
           /* If HTTP version is >= 1.1 and connection is persistent
              server supports pipelining. */
           DEBUGF(infof(data,
                        "HTTP 1.1 or later with persistent connection, "
                        "pipelining supported\n"));
           /* Activate pipelining if needed */
-          cb_ptr = conn->bundle;
-          if(cb_ptr) {
+          if(conn->bundle) {
             if(!Curl_pipeline_site_blacklisted(data, conn))
-              cb_ptr->server_supports_pipelining = TRUE;
+              conn->bundle->multiuse = BUNDLE_PIPELINING;
           }
         }
 
@@ -3379,14 +3461,17 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
       }
     }
     else if(checkprefix("Server:", k->p)) {
-      char *server_name = Curl_copy_header_value(k->p);
-
-      /* Turn off pipelining if the server version is blacklisted */
-      if(conn->bundle && conn->bundle->server_supports_pipelining) {
-        if(Curl_pipeline_server_blacklisted(data, server_name))
-          conn->bundle->server_supports_pipelining = FALSE;
+      if(conn->httpversion < 20) {
+        /* only do this for non-h2 servers */
+        char *server_name = Curl_copy_header_value(k->p);
+
+        /* Turn off pipelining if the server version is blacklisted  */
+        if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
+          if(Curl_pipeline_server_blacklisted(data, server_name))
+            conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
+        }
+        free(server_name);
       }
-      Curl_safefree(server_name);
     }
     else if((conn->httpversion == 10) &&
             conn->bits.httpproxy &&
@@ -3483,14 +3568,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
           k->auto_decoding = GZIP;
           start += 6;
         }
-        else if(checkprefix("compress", start)) {
-          k->auto_decoding = COMPRESS;
-          start += 8;
-        }
-        else if(checkprefix("x-compress", start)) {
-          k->auto_decoding = COMPRESS;
-          start += 10;
-        }
         else
           /* unknown! */
           break;
@@ -3523,9 +3600,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
       else if(checkprefix("gzip", start)
               || checkprefix("x-gzip", start))
         k->auto_decoding = GZIP;
-      else if(checkprefix("compress", start)
-              || checkprefix("x-compress", start))
-        k->auto_decoding = COMPRESS;
     }
     else if(checkprefix("Content-Range:", k->p)) {
       /* Content-Range: bytes [num]-
@@ -3591,7 +3665,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
 
       result = Curl_http_input_auth(conn, proxy, auth);
 
-      Curl_safefree(auth);
+      free(auth);
 
       if(result)
         return result;
diff --git a/Utilities/cmcurl/lib/http.h b/Utilities/cmcurl/lib/http.h
index 907755a..fe4f39b 100644
--- a/Utilities/cmcurl/lib/http.h
+++ b/Utilities/cmcurl/lib/http.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -60,6 +60,7 @@ struct Curl_send_buffer {
 typedef struct Curl_send_buffer Curl_send_buffer;
 
 Curl_send_buffer *Curl_add_buffer_init(void);
+void Curl_add_buffer_free(Curl_send_buffer *buff);
 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...);
 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size);
 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
@@ -152,42 +153,69 @@ struct HTTP {
 
   void *send_buffer; /* used if the request couldn't be sent in one chunk,
                         points to an allocated send_buffer struct */
+
+#ifdef USE_NGHTTP2
+  /*********** for HTTP/2 we store stream-local data here *************/
+  int32_t stream_id; /* stream we are interested in */
+
+  bool bodystarted;
+  /* We store non-final and final response headers here, per-stream */
+  Curl_send_buffer *header_recvbuf;
+  size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
+                                  upper layer */
+  int status_code; /* HTTP status code */
+  const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
+  size_t pauselen; /* the number of bytes left in data */
+  bool closed; /* TRUE on HTTP2 stream close */
+  uint32_t error_code; /* HTTP/2 error code */
+
+  char *mem;     /* points to a buffer in memory to store received data */
+  size_t len;    /* size of the buffer 'mem' points to */
+  size_t memlen; /* size of data copied to mem */
+
+  const uint8_t *upload_mem; /* points to a buffer to read from */
+  size_t upload_len; /* size of the buffer 'upload_mem' points to */
+  curl_off_t upload_left; /* number of bytes left to upload */
+
+  char **push_headers;       /* allocated array */
+  size_t push_headers_used;  /* number of entries filled in */
+  size_t push_headers_alloc; /* number of entries allocated */
+#endif
 };
 
 typedef int (*sending)(void); /* Curl_send */
 typedef int (*recving)(void); /* Curl_recv */
 
+#ifdef USE_NGHTTP2
+/* h2 settings for this connection */
+struct h2settings {
+  uint32_t max_concurrent_streams;
+  bool enable_push;
+};
+#endif
+
+
 struct http_conn {
 #ifdef USE_NGHTTP2
 #define H2_BINSETTINGS_LEN 80
   nghttp2_session *h2;
   uint8_t binsettings[H2_BINSETTINGS_LEN];
   size_t  binlen; /* length of the binsettings data */
-  char *mem;     /* points to a buffer in memory to store */
-  size_t len;    /* size of the buffer 'mem' points to */
-  bool bodystarted;
   sending send_underlying; /* underlying send Curl_send callback */
   recving recv_underlying; /* underlying recv Curl_recv callback */
-  bool closed; /* TRUE on HTTP2 stream close */
-  Curl_send_buffer *header_recvbuf; /* store response headers.  We
-                                       store non-final and final
-                                       response headers into it. */
-  size_t nread_header_recvbuf; /* number of bytes in header_recvbuf
-                                  fed into upper layer */
-  int32_t stream_id; /* stream we are interested in */
-  const uint8_t *data; /* pointer to data chunk, received in
-                          on_data_chunk */
-  size_t datalen; /* the number of bytes left in data */
   char *inbuf; /* buffer to receive data from underlying socket */
+  size_t inbuflen; /* number of bytes filled in inbuf */
+  size_t nread_inbuf; /* number of bytes read from in inbuf */
   /* We need separate buffer for transmission and reception because we
      may call nghttp2_session_send() after the
      nghttp2_session_mem_recv() but mem buffer is still not full. In
      this case, we wrongly sends the content of mem buffer if we share
      them for both cases. */
-  const uint8_t *upload_mem; /* points to a buffer to read from */
-  size_t upload_len; /* size of the buffer 'upload_mem' points to */
-  size_t upload_left; /* number of bytes left to upload */
-  int status_code; /* HTTP status code */
+  int32_t pause_stream_id; /* stream ID which paused
+                              nghttp2_session_mem_recv */
+
+  /* this is a hash of all individual streams (SessionHandle structs) */
+  struct h2settings settings;
 #else
   int unused; /* prevent a compiler warning */
 #endif
diff --git a/Utilities/cmcurl/lib/http2.c b/Utilities/cmcurl/lib/http2.c
index 604514d..0024add 100644
--- a/Utilities/cmcurl/lib/http2.c
+++ b/Utilities/cmcurl/lib/http2.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,22 +23,24 @@
 #include "curl_setup.h"
 
 #ifdef USE_NGHTTP2
-#define _MPRINTF_REPLACE
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include <nghttp2/nghttp2.h>
 #include "urldata.h"
 #include "http2.h"
 #include "http.h"
 #include "sendf.h"
 #include "curl_base64.h"
-#include "curl_memory.h"
 #include "rawstr.h"
 #include "multiif.h"
+#include "conncache.h"
+#include "url.h"
 
-/* include memdebug.h last */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
+#define MIN(x,y) ((x)<(y)?(x):(y))
+
 #if (NGHTTP2_VERSION_NUM < 0x000600)
 #error too old nghttp2 version, upgrade!
 #endif
@@ -50,7 +52,7 @@ static int http2_perform_getsock(const struct connectdata *conn,
                                                          sockets */
                                  int numsocks)
 {
-  const struct http_conn *httpc = &conn->proto.httpc;
+  const struct http_conn *c = &conn->proto.httpc;
   int bitmap = GETSOCK_BLANK;
   (void)numsocks;
 
@@ -58,10 +60,10 @@ static int http2_perform_getsock(const struct connectdata *conn,
      because of renegotiation. */
   sock[0] = conn->sock[FIRSTSOCKET];
 
-  if(nghttp2_session_want_read(httpc->h2))
+  if(nghttp2_session_want_read(c->h2))
     bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
 
-  if(nghttp2_session_want_write(httpc->h2))
+  if(nghttp2_session_want_write(c->h2))
     bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
 
   return bitmap;
@@ -78,23 +80,54 @@ static int http2_getsock(struct connectdata *conn,
 static CURLcode http2_disconnect(struct connectdata *conn,
                                  bool dead_connection)
 {
-  struct http_conn *httpc = &conn->proto.httpc;
+  struct HTTP *http = conn->data->req.protop;
+  struct http_conn *c = &conn->proto.httpc;
   (void)dead_connection;
 
-  infof(conn->data, "HTTP/2 DISCONNECT starts now\n");
-
-  nghttp2_session_del(httpc->h2);
+  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
 
-  Curl_safefree(httpc->header_recvbuf->buffer);
-  Curl_safefree(httpc->header_recvbuf);
+  nghttp2_session_del(c->h2);
+  Curl_safefree(c->inbuf);
 
-  Curl_safefree(httpc->inbuf);
+  if(http) {
+    Curl_add_buffer_free(http->header_recvbuf);
+    http->header_recvbuf = NULL; /* clear the pointer */
+    for(; http->push_headers_used > 0; --http->push_headers_used) {
+      free(http->push_headers[http->push_headers_used - 1]);
+    }
+    free(http->push_headers);
+    http->push_headers = NULL;
+  }
 
-  infof(conn->data, "HTTP/2 DISCONNECT done\n");
+  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
 
   return CURLE_OK;
 }
 
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_req(struct SessionHandle *data)
+{
+  struct HTTP *http = data->req.protop;
+
+  http->nread_header_recvbuf = 0;
+  http->bodystarted = FALSE;
+  http->status_code = -1;
+  http->pausedata = NULL;
+  http->pauselen = 0;
+  http->error_code = NGHTTP2_NO_ERROR;
+  http->closed = FALSE;
+  http->mem = data->state.buffer;
+  http->len = BUFSIZE;
+  http->memlen = 0;
+}
+
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_conn(struct connectdata *conn)
+{
+  conn->proto.httpc.settings.max_concurrent_streams =
+    DEFAULT_MAX_CONCURRENT_STREAMS;
+}
+
 /*
  * HTTP2 handler interface. This isn't added to the general list of protocols
  * but will be used at run-time when the protocol is dynamically switched from
@@ -104,7 +137,7 @@ const struct Curl_handler Curl_handler_http2 = {
   "HTTP2",                              /* scheme */
   ZERO_NULL,                            /* setup_connection */
   Curl_http,                            /* do_it */
-  ZERO_NULL,                            /* done */
+  Curl_http_done,                       /* done */
   ZERO_NULL,                            /* do_more */
   ZERO_NULL,                            /* connect_it */
   ZERO_NULL,                            /* connecting */
@@ -124,7 +157,7 @@ const struct Curl_handler Curl_handler_http2_ssl = {
   "HTTP2",                              /* scheme */
   ZERO_NULL,                            /* setup_connection */
   Curl_http,                            /* do_it */
-  ZERO_NULL,                            /* done */
+  Curl_http_done,                       /* done */
   ZERO_NULL,                            /* do_more */
   ZERO_NULL,                            /* connect_it */
   ZERO_NULL,                            /* connecting */
@@ -160,17 +193,17 @@ static ssize_t send_callback(nghttp2_session *h2,
                              void *userp)
 {
   struct connectdata *conn = (struct connectdata *)userp;
-  struct http_conn *httpc = &conn->proto.httpc;
+  struct http_conn *c = &conn->proto.httpc;
   ssize_t written;
-  CURLcode rc;
+  CURLcode result = CURLE_OK;
+
   (void)h2;
   (void)flags;
 
-  rc = 0;
-  written = ((Curl_send*)httpc->send_underlying)(conn, FIRSTSOCKET,
-                                                 data, length, &rc);
+  written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
+                                             data, length, &result);
 
-  if(rc == CURLE_AGAIN) {
+  if(result == CURLE_AGAIN) {
     return NGHTTP2_ERR_WOULDBLOCK;
   }
 
@@ -185,25 +218,205 @@ static ssize_t send_callback(nghttp2_session *h2,
   return written;
 }
 
+
+/* We pass a pointer to this struct in the push callback, but the contents of
+   the struct are hidden from the user. */
+struct curl_pushheaders {
+  struct SessionHandle *data;
+  const nghttp2_push_promise *frame;
+};
+
+/*
+ * push header access function. Only to be used from within the push callback
+ */
+char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
+{
+  /* Verify that we got a good easy handle in the push header struct, mostly to
+     detect rubbish input fast(er). */
+  if(!h || !GOOD_EASY_HANDLE(h->data))
+    return NULL;
+  else {
+    struct HTTP *stream = h->data->req.protop;
+    if(num < stream->push_headers_used)
+      return stream->push_headers[num];
+  }
+  return NULL;
+}
+
+/*
+ * push header access function. Only to be used from within the push callback
+ */
+char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
+{
+  /* Verify that we got a good easy handle in the push header struct,
+     mostly to detect rubbish input fast(er). Also empty header name
+     is just a rubbish too. We have to allow ":" at the beginning of
+     the header, but header == ":" must be rejected. If we have ':' in
+     the middle of header, it could be matched in middle of the value,
+     this is because we do prefix match.*/
+  if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] ||
+     Curl_raw_equal(header, ":") || strchr(header + 1, ':'))
+    return NULL;
+  else {
+    struct HTTP *stream = h->data->req.protop;
+    size_t len = strlen(header);
+    size_t i;
+    for(i=0; i<stream->push_headers_used; i++) {
+      if(!strncmp(header, stream->push_headers[i], len)) {
+        /* sub-match, make sure that it us followed by a colon */
+        if(stream->push_headers[i][len] != ':')
+          continue;
+        return &stream->push_headers[i][len+1];
+      }
+    }
+  }
+  return NULL;
+}
+
+static CURL *duphandle(struct SessionHandle *data)
+{
+  struct SessionHandle *second = curl_easy_duphandle(data);
+  if(second) {
+    /* setup the request struct */
+    struct HTTP *http = calloc(1, sizeof(struct HTTP));
+    if(!http) {
+      (void)Curl_close(second);
+      second = NULL;
+    }
+    else {
+      second->req.protop = http;
+      http->header_recvbuf = Curl_add_buffer_init();
+      if(!http->header_recvbuf) {
+        free(http);
+        (void)Curl_close(second);
+        second = NULL;
+      }
+      else
+        Curl_http2_setup_req(second);
+    }
+  }
+  return second;
+}
+
+
+static int push_promise(struct SessionHandle *data,
+                        struct connectdata *conn,
+                        const nghttp2_push_promise *frame)
+{
+  int rv;
+  DEBUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
+               frame->promised_stream_id));
+  if(data->multi->push_cb) {
+    struct HTTP *stream;
+    struct curl_pushheaders heads;
+    CURLMcode rc;
+    struct http_conn *httpc;
+    size_t i;
+    /* clone the parent */
+    CURL *newhandle = duphandle(data);
+    if(!newhandle) {
+      infof(data, "failed to duplicate handle\n");
+      rv = 1; /* FAIL HARD */
+      goto fail;
+    }
+
+    heads.data = data;
+    heads.frame = frame;
+    /* ask the application */
+    DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
+
+    stream = data->req.protop;
+    if(!stream) {
+      failf(data, "Internal NULL stream!\n");
+      rv = 1;
+      goto fail;
+    }
+
+    rv = data->multi->push_cb(data, newhandle,
+                              stream->push_headers_used, &heads,
+                              data->multi->push_userp);
+
+    /* free the headers again */
+    for(i=0; i<stream->push_headers_used; i++)
+      free(stream->push_headers[i]);
+    free(stream->push_headers);
+    stream->push_headers = NULL;
+
+    if(rv) {
+      /* denied, kill off the new handle again */
+      (void)Curl_close(newhandle);
+      goto fail;
+    }
+
+    /* approved, add to the multi handle and immediately switch to PERFORM
+       state with the given connection !*/
+    rc = Curl_multi_add_perform(data->multi, newhandle, conn);
+    if(rc) {
+      infof(data, "failed to add handle to multi\n");
+      Curl_close(newhandle);
+      rv = 1;
+      goto fail;
+    }
+
+    httpc = &conn->proto.httpc;
+    nghttp2_session_set_stream_user_data(httpc->h2,
+                                         frame->promised_stream_id, newhandle);
+  }
+  else {
+    DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
+    rv = 1;
+  }
+  fail:
+  return rv;
+}
+
 static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
                          void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  struct http_conn *c = &conn->proto.httpc;
+  struct connectdata *conn = NULL;
+  struct http_conn *httpc = NULL;
+  struct SessionHandle *data_s = NULL;
+  struct HTTP *stream = NULL;
+  static int lastStream = -1;
   int rv;
   size_t left, ncopy;
+  int32_t stream_id = frame->hd.stream_id;
 
-  (void)session;
-  (void)frame;
-  infof(conn->data, "on_frame_recv() was called with header %x\n",
-        frame->hd.type);
+  (void)userp;
+
+  if(!stream_id) {
+    /* stream ID zero is for connection-oriented stuff */
+    return 0;
+  }
+  data_s = nghttp2_session_get_stream_user_data(session,
+                                                frame->hd.stream_id);
+  if(lastStream != frame->hd.stream_id) {
+    lastStream = frame->hd.stream_id;
+  }
+  if(!data_s) {
+    DEBUGF(infof(conn->data,
+                 "No SessionHandle associated with stream: %x\n",
+                 stream_id));
+    return 0;
+  }
+
+  stream = data_s->req.protop;
+  if(!stream)
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
+               frame->hd.type, stream_id));
+
+  conn = data_s->easy_conn;
+  assert(conn);
+  assert(conn->data == data_s);
+  httpc = &conn->proto.httpc;
   switch(frame->hd.type) {
   case NGHTTP2_DATA:
-    /* If body started, then receiving DATA is illegal. */
-    if(!c->bodystarted) {
+    /* If body started on this stream, then receiving DATA is illegal. */
+    if(!stream->bodystarted) {
       rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
-                                     frame->hd.stream_id,
-                                     NGHTTP2_PROTOCOL_ERROR);
+                                     stream_id, NGHTTP2_PROTOCOL_ERROR);
 
       if(nghttp2_is_fatal(rv)) {
         return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -214,74 +427,96 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
     if(frame->headers.cat == NGHTTP2_HCAT_REQUEST)
       break;
 
-    if(c->bodystarted) {
-      /* Only valid HEADERS after body started is trailer header,
-         which is not fully supported in this code.  If HEADERS is not
-         trailer, then it is a PROTOCOL_ERROR. */
-      if((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
-        rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
-                                       frame->hd.stream_id,
-                                       NGHTTP2_PROTOCOL_ERROR);
-
-        if(nghttp2_is_fatal(rv)) {
-          return NGHTTP2_ERR_CALLBACK_FAILURE;
-        }
-      }
+    if(stream->bodystarted) {
+      /* Only valid HEADERS after body started is trailer HEADERS.  We
+         ignores trailer HEADERS for now.  nghttp2 guarantees that it
+         has END_STREAM flag set. */
       break;
     }
 
-    if(c->status_code == -1) {
-      /* No :status header field means PROTOCOL_ERROR. */
-      rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
-                                     frame->hd.stream_id,
-                                     NGHTTP2_PROTOCOL_ERROR);
-
-      if(nghttp2_is_fatal(rv)) {
-        return NGHTTP2_ERR_CALLBACK_FAILURE;
-      }
-
-      break;
-    }
+    /* nghttp2 guarantees that :status is received, and we store it to
+       stream->status_code */
+    DEBUGASSERT(stream->status_code != -1);
 
     /* Only final status code signals the end of header */
-    if(c->status_code / 100 != 1) {
-      c->bodystarted = TRUE;
+    if(stream->status_code / 100 != 1) {
+      stream->bodystarted = TRUE;
+      stream->status_code = -1;
     }
 
-    c->status_code = -1;
+    Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
 
-    Curl_add_buffer(c->header_recvbuf, "\r\n", 2);
+    left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+    ncopy = MIN(stream->len, left);
+
+    memcpy(&stream->mem[stream->memlen],
+           stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
+           ncopy);
+    stream->nread_header_recvbuf += ncopy;
 
-    left = c->header_recvbuf->size_used - c->nread_header_recvbuf;
-    ncopy = c->len < left ? c->len : left;
+    DEBUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n",
+                 ncopy, stream_id, stream->mem));
 
-    memcpy(c->mem, c->header_recvbuf->buffer + c->nread_header_recvbuf, ncopy);
-    c->nread_header_recvbuf += ncopy;
+    stream->len -= ncopy;
+    stream->memlen += ncopy;
 
-    c->mem += ncopy;
-    c->len -= ncopy;
+    data_s->state.drain++;
+    Curl_expire(data_s, 1);
     break;
   case NGHTTP2_PUSH_PROMISE:
-    rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
-                                   frame->push_promise.promised_stream_id,
-                                   NGHTTP2_CANCEL);
-    if(nghttp2_is_fatal(rv)) {
-      return rv;
+    rv = push_promise(data_s, conn, &frame->push_promise);
+    if(rv) { /* deny! */
+      rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
+                                     frame->push_promise.promised_stream_id,
+                                     NGHTTP2_CANCEL);
+      if(nghttp2_is_fatal(rv)) {
+        return rv;
+      }
     }
     break;
+  case NGHTTP2_SETTINGS:
+  {
+    uint32_t max_conn = httpc->settings.max_concurrent_streams;
+    DEBUGF(infof(conn->data, "Got SETTINGS for stream %u!\n", stream_id));
+    httpc->settings.max_concurrent_streams =
+      nghttp2_session_get_remote_settings(
+        session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
+    httpc->settings.enable_push =
+      nghttp2_session_get_remote_settings(
+        session, NGHTTP2_SETTINGS_ENABLE_PUSH);
+    DEBUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n",
+                 httpc->settings.max_concurrent_streams));
+    DEBUGF(infof(conn->data, "ENABLE_PUSH == %s\n",
+                 httpc->settings.enable_push?"TRUE":"false"));
+    if(max_conn != httpc->settings.max_concurrent_streams) {
+      /* only signal change if the value actually changed */
+      infof(conn->data,
+            "Connection state changed (MAX_CONCURRENT_STREAMS updated)!\n");
+      Curl_multi_connchanged(conn->data->multi);
+    }
+  }
+  break;
+  default:
+    DEBUGF(infof(conn->data, "Got frame type %x for stream %u!\n",
+                 frame->hd.type, stream_id));
+    break;
   }
   return 0;
 }
 
 static int on_invalid_frame_recv(nghttp2_session *session,
                                  const nghttp2_frame *frame,
-                                 uint32_t error_code, void *userp)
+                                 int lib_error_code, void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  (void)session;
-  (void)frame;
-  infof(conn->data, "on_invalid_frame_recv() was called, error_code = %d\n",
-        error_code);
+  struct SessionHandle *data_s = NULL;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s,
+                 "on_invalid_frame_recv() was called, error=%d:%s\n",
+                 lib_error_code, nghttp2_strerror(lib_error_code)));
+  }
   return 0;
 }
 
@@ -289,30 +524,50 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
                               int32_t stream_id,
                               const uint8_t *data, size_t len, void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  struct http_conn *c = &conn->proto.httpc;
+  struct HTTP *stream;
+  struct SessionHandle *data_s;
   size_t nread;
   (void)session;
   (void)flags;
   (void)data;
-  infof(conn->data, "on_data_chunk_recv() "
-        "len = %u, stream = %x\n", len, stream_id);
+  (void)userp;
 
-  if(stream_id != c->stream_id) {
-    return 0;
-  }
+  DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
 
-  nread = c->len < len ? c->len : len;
-  memcpy(c->mem, data, nread);
+  /* get the stream from the hash based on Stream ID */
+  data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+  if(!data_s)
+    /* Receiving a Stream ID not in the hash should not happen, this is an
+       internal error more than anything else! */
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  stream = data_s->req.protop;
+  if(!stream)
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
 
-  c->mem += nread;
-  c->len -= nread;
+  nread = MIN(stream->len, len);
+  memcpy(&stream->mem[stream->memlen], data, nread);
 
-  infof(conn->data, "%zu data written\n", nread);
+  stream->len -= nread;
+  stream->memlen += nread;
+
+  data_s->state.drain++;
+  Curl_expire(data_s, 1); /* TODO: fix so that this can be set to 0 for
+                             immediately? */
+
+  DEBUGF(infof(data_s, "%zu data received for stream %u "
+               "(%zu left in buffer %p, total %zu)\n",
+               nread, stream_id,
+               stream->len, stream->mem,
+               stream->memlen));
 
   if(nread < len) {
-    c->data = data + nread;
-    c->datalen = len - nread;
+    stream->pausedata = data + nread;
+    stream->pauselen = len - nread;
+    DEBUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
+                 ", stream %u\n",
+                 len - nread, stream_id));
+    data_s->easy_conn->proto.httpc.pause_stream_id = stream_id;
     return NGHTTP2_ERR_PAUSE;
   }
   return 0;
@@ -322,59 +577,89 @@ static int before_frame_send(nghttp2_session *session,
                              const nghttp2_frame *frame,
                              void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  (void)session;
-  (void)frame;
-  infof(conn->data, "before_frame_send() was called\n");
+  struct SessionHandle *data_s;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s, "before_frame_send() was called\n"));
+  }
+
   return 0;
 }
 static int on_frame_send(nghttp2_session *session,
                          const nghttp2_frame *frame,
                          void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  (void)session;
-  (void)frame;
-  infof(conn->data, "on_frame_send() was called\n");
+  struct SessionHandle *data_s;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
+                 frame->hd.length));
+  }
   return 0;
 }
 static int on_frame_not_send(nghttp2_session *session,
                              const nghttp2_frame *frame,
                              int lib_error_code, void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  (void)session;
-  (void)frame;
-  infof(conn->data, "on_frame_not_send() was called, lib_error_code = %d\n",
-        lib_error_code);
+  struct SessionHandle *data_s;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s,
+                 "on_frame_not_send() was called, lib_error_code = %d\n",
+                 lib_error_code));
+  }
   return 0;
 }
 static int on_stream_close(nghttp2_session *session, int32_t stream_id,
                            uint32_t error_code, void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  struct http_conn *c = &conn->proto.httpc;
+  struct SessionHandle *data_s;
+  struct HTTP *stream;
   (void)session;
   (void)stream_id;
-  infof(conn->data, "on_stream_close() was called, error_code = %d\n",
-        error_code);
-
-  if(stream_id != c->stream_id) {
-    return 0;
-  }
+  (void)userp;
+
+  if(stream_id) {
+    /* get the stream from the hash based on Stream ID, stream ID zero is for
+       connection-oriented stuff */
+    data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+    if(!data_s) {
+      /* We could get stream ID not in the hash.  For example, if we
+         decided to reject stream (e.g., PUSH_PROMISE). */
+      return 0;
+    }
+    DEBUGF(infof(data_s, "on_stream_close(), error_code = %d, stream %u\n",
+                 error_code, stream_id));
+    stream = data_s->req.protop;
+    if(!stream)
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
 
-  c->closed = TRUE;
+    stream->error_code = error_code;
+    stream->closed = TRUE;
 
+    /* remove the entry from the hash as the stream is now gone */
+    nghttp2_session_set_stream_user_data(session, stream_id, 0);
+    DEBUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
+  }
   return 0;
 }
 
 static int on_begin_headers(nghttp2_session *session,
                             const nghttp2_frame *frame, void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  (void)session;
-  (void)frame;
-  infof(conn->data, "on_begin_headers() was called\n");
+  struct SessionHandle *data_s = NULL;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s, "on_begin_headers() was called\n"));
+  }
   return 0;
 }
 
@@ -405,8 +690,6 @@ static int decode_status_code(const uint8_t *value, size_t len)
   return res;
 }
 
-static const char STATUS[] = ":status";
-
 /* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */
 static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
                      const uint8_t *name, size_t namelen,
@@ -414,93 +697,94 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
                      uint8_t flags,
                      void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  struct http_conn *c = &conn->proto.httpc;
-  int rv;
-  int goodname;
-  int goodheader;
+  struct HTTP *stream;
+  struct SessionHandle *data_s;
+  int32_t stream_id = frame->hd.stream_id;
 
-  (void)session;
-  (void)frame;
   (void)flags;
+  (void)userp;
 
-  if(frame->hd.stream_id != c->stream_id) {
-    return 0;
+  DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
+
+  /* get the stream from the hash based on Stream ID */
+  data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+  if(!data_s)
+    /* Receiving a Stream ID not in the hash should not happen, this is an
+       internal error more than anything else! */
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  stream = data_s->req.protop;
+  if(!stream) {
+    failf(data_s, "Internal NULL stream! 5\n");
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
   }
 
-  if(c->bodystarted) {
+  if(stream->bodystarted)
     /* Ignore trailer or HEADERS not mapped to HTTP semantics.  The
        consequence is handled in on_frame_recv(). */
     return 0;
-  }
 
-  goodname = nghttp2_check_header_name(name, namelen);
-  goodheader = nghttp2_check_header_value(value, valuelen);
+  /* Store received PUSH_PROMISE headers to be used when the subsequent
+     PUSH_PROMISE callback comes */
+  if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+    char *h;
 
-  if(!goodname || !goodheader) {
-
-    infof(conn->data, "Detected bad incoming header %s%s, reset stream!\n",
-          goodname?"":"name",
-          goodheader?"":"value");
-
-    rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
-                                   frame->hd.stream_id,
-                                   NGHTTP2_PROTOCOL_ERROR);
-
-    if(nghttp2_is_fatal(rv)) {
-      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    if(!stream->push_headers) {
+      stream->push_headers_alloc = 10;
+      stream->push_headers = malloc(stream->push_headers_alloc *
+                                    sizeof(char *));
+      stream->push_headers_used = 0;
     }
-
-    return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
-  }
-
-  if(namelen == sizeof(":status") - 1 &&
-     memcmp(STATUS, name, namelen) == 0) {
-
-    /* :status must appear exactly once. */
-    if(c->status_code != -1 ||
-       (c->status_code = decode_status_code(value, valuelen)) == -1) {
-
-      rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
-                                     frame->hd.stream_id,
-                                     NGHTTP2_PROTOCOL_ERROR);
-      if(nghttp2_is_fatal(rv)) {
-        return NGHTTP2_ERR_CALLBACK_FAILURE;
+    else if(stream->push_headers_used ==
+            stream->push_headers_alloc) {
+      char **headp;
+      stream->push_headers_alloc *= 2;
+      headp = realloc(stream->push_headers,
+                      stream->push_headers_alloc * sizeof(char *));
+      if(!headp) {
+        free(stream->push_headers);
+        stream->push_headers = NULL;
+        return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
       }
-
-      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+      stream->push_headers = headp;
     }
-
-    Curl_add_buffer(c->header_recvbuf, "HTTP/2.0 ", 9);
-    Curl_add_buffer(c->header_recvbuf, value, valuelen);
-    Curl_add_buffer(c->header_recvbuf, "\r\n", 2);
-
+    h = aprintf("%s:%s", name, value);
+    if(h)
+      stream->push_headers[stream->push_headers_used++] = h;
     return 0;
   }
-  else {
-    /* Here we are sure that namelen > 0 because of
-       nghttp2_check_header_name().  Pseudo header other than :status
-       is illegal. */
-    if(c->status_code == -1 || name[0] == ':') {
-      rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
-                                     frame->hd.stream_id,
-                                     NGHTTP2_PROTOCOL_ERROR);
-      if(nghttp2_is_fatal(rv)) {
-        return NGHTTP2_ERR_CALLBACK_FAILURE;
-      }
 
-      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
-    }
+  if(namelen == sizeof(":status") - 1 &&
+     memcmp(":status", name, namelen) == 0) {
+    /* nghttp2 guarantees :status is received first and only once, and
+       value is 3 digits status code, and decode_status_code always
+       succeeds. */
+    stream->status_code = decode_status_code(value, valuelen);
+    DEBUGASSERT(stream->status_code != -1);
+
+    Curl_add_buffer(stream->header_recvbuf, "HTTP/2.0 ", 9);
+    Curl_add_buffer(stream->header_recvbuf, value, valuelen);
+    Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+    data_s->state.drain++;
+    Curl_expire(data_s, 1);
+
+    DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d\n",
+                 stream->status_code));
+    return 0;
+  }
 
-    /* convert to a HTTP1-style header */
-    Curl_add_buffer(c->header_recvbuf, name, namelen);
-    Curl_add_buffer(c->header_recvbuf, ":", 1);
-    Curl_add_buffer(c->header_recvbuf, value, valuelen);
-    Curl_add_buffer(c->header_recvbuf, "\r\n", 2);
+  /* nghttp2 guarantees that namelen > 0, and :status was already
+     received, and this is not pseudo-header field . */
+  /* convert to a HTTP1-style header */
+  Curl_add_buffer(stream->header_recvbuf, name, namelen);
+  Curl_add_buffer(stream->header_recvbuf, ":", 1);
+  Curl_add_buffer(stream->header_recvbuf, value, valuelen);
+  Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+  data_s->state.drain++;
+  Curl_expire(data_s, 1);
 
-    infof(conn->data, "got http2 header: %.*s: %.*s\n",
-          namelen, name, valuelen, value);
-  }
+  DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
+               value));
 
   return 0; /* 0 is successful */
 }
@@ -512,26 +796,45 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
                                          nghttp2_data_source *source,
                                          void *userp)
 {
-  struct connectdata *conn = (struct connectdata *)userp;
-  struct http_conn *c = &conn->proto.httpc;
+  struct SessionHandle *data_s;
+  struct HTTP *stream = NULL;
   size_t nread;
-  (void)session;
-  (void)stream_id;
   (void)source;
+  (void)userp;
+
+  if(stream_id) {
+    /* get the stream from the hash based on Stream ID, stream ID zero is for
+       connection-oriented stuff */
+    data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+    if(!data_s)
+      /* Receiving a Stream ID not in the hash should not happen, this is an
+         internal error more than anything else! */
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
 
-  nread = c->upload_len < length ? c->upload_len : length;
+    stream = data_s->req.protop;
+    if(!stream)
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+  else
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+
+  nread = MIN(stream->upload_len, length);
   if(nread > 0) {
-    memcpy(buf, c->upload_mem, nread);
-    c->upload_mem += nread;
-    c->upload_len -= nread;
-    c->upload_left -= nread;
+    memcpy(buf, stream->upload_mem, nread);
+    stream->upload_mem += nread;
+    stream->upload_len -= nread;
+    stream->upload_left -= nread;
   }
 
-  if(c->upload_left == 0)
+  if(stream->upload_left == 0)
     *data_flags = 1;
   else if(nread == 0)
     return NGHTTP2_ERR_DEFERRED;
 
+  DEBUGF(infof(data_s, "data_source_read_callback: "
+               "returns %zu bytes stream %u\n",
+               nread, stream_id));
+
   return nread;
 }
 
@@ -543,7 +846,7 @@ static nghttp2_settings_entry settings[] = {
   { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, NGHTTP2_INITIAL_WINDOW_SIZE },
 };
 
-#define H2_BUFSIZE 4096
+#define H2_BUFSIZE 32768
 
 /*
  * Initialize nghttp2 for a Curl connection
@@ -595,8 +898,7 @@ CURLcode Curl_http2_init(struct connectdata *conn)
     nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header);
 
     /* The nghttp2 session is not yet setup, do it */
-    rc = nghttp2_session_client_new(&conn->proto.httpc.h2,
-                                    callbacks, conn);
+    rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn);
 
     nghttp2_session_callbacks_del(callbacks);
 
@@ -604,6 +906,11 @@ CURLcode Curl_http2_init(struct connectdata *conn)
       failf(conn->data, "Couldn't initialize nghttp2!");
       return CURLE_OUT_OF_MEMORY; /* most likely at least */
     }
+
+    if(rc) {
+      failf(conn->data, "Couldn't init stream hash!");
+      return CURLE_OUT_OF_MEMORY; /* most likely at least */
+    }
   }
   return CURLE_OK;
 }
@@ -630,14 +937,6 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
   struct SingleRequest *k = &conn->data->req;
   uint8_t *binsettings = conn->proto.httpc.binsettings;
 
-  result = Curl_http2_init(conn);
-  if(result)
-    return result;
-
-  result = Curl_http2_setup(conn);
-  if(result)
-    return result;
-
   /* As long as we have a fixed set of settings, we don't have to dynamically
    * figure out the base64 strings since it'll always be the same. However,
    * the settings will likely not be fixed every time in the future.
@@ -663,13 +962,32 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
                             "Upgrade: %s\r\n"
                             "HTTP2-Settings: %s\r\n",
                             NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
-  Curl_safefree(base64);
+  free(base64);
 
   k->upgr101 = UPGR101_REQUESTED;
 
   return result;
 }
 
+static ssize_t http2_handle_stream_close(struct http_conn *httpc,
+                                         struct SessionHandle *data,
+                                         struct HTTP *stream, CURLcode *err) {
+  if(httpc->pause_stream_id == stream->stream_id) {
+    httpc->pause_stream_id = 0;
+  }
+  /* Reset to FALSE to prevent infinite loop in readwrite_data
+   function. */
+  stream->closed = FALSE;
+  if(stream->error_code != NGHTTP2_NO_ERROR) {
+    failf(data, "HTTP/2 stream %u was not closed cleanly: error_code = %d",
+          stream->stream_id, stream->error_code);
+    *err = CURLE_HTTP2;
+    return -1;
+  }
+  DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
+  return 0;
+}
+
 /*
  * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
  * a regular CURLcode value.
@@ -677,102 +995,188 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
 static ssize_t http2_recv(struct connectdata *conn, int sockindex,
                           char *mem, size_t len, CURLcode *err)
 {
-  CURLcode rc;
+  CURLcode result = CURLE_OK;
   ssize_t rv;
   ssize_t nread;
   struct http_conn *httpc = &conn->proto.httpc;
+  struct SessionHandle *data = conn->data;
+  struct HTTP *stream = data->req.protop;
 
   (void)sockindex; /* we always do HTTP2 on sockindex 0 */
 
-  if(httpc->closed) {
-    /* Reset to FALSE to prevent infinite loop in readwrite_data
-       function. */
-    httpc->closed = FALSE;
-    return 0;
+  /* If stream is closed, return 0 to signal the http routine to close
+     the connection.  We need to handle stream closure here,
+     otherwise, we may be going to read from underlying connection,
+     and gets EAGAIN, and we will get stuck there. */
+  if(stream->memlen == 0 && stream->closed) {
+    return http2_handle_stream_close(httpc, data, stream, err);
   }
 
   /* Nullify here because we call nghttp2_session_send() and they
      might refer to the old buffer. */
-  httpc->upload_mem = NULL;
-  httpc->upload_len = 0;
+  stream->upload_mem = NULL;
+  stream->upload_len = 0;
 
-  if(httpc->bodystarted &&
-     httpc->nread_header_recvbuf < httpc->header_recvbuf->size_used) {
+  /*
+   * At this point 'stream' is just in the SessionHandle the connection
+   * identifies as its owner at this time.
+   */
+
+  if(stream->bodystarted &&
+     stream->nread_header_recvbuf < stream->header_recvbuf->size_used) {
+    /* If there is body data pending for this stream to return, do that */
     size_t left =
-      httpc->header_recvbuf->size_used - httpc->nread_header_recvbuf;
-    size_t ncopy = len < left ? len : left;
-    memcpy(mem, httpc->header_recvbuf->buffer + httpc->nread_header_recvbuf,
+      stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+    size_t ncopy = MIN(len, left);
+    memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
            ncopy);
-    httpc->nread_header_recvbuf += ncopy;
+    stream->nread_header_recvbuf += ncopy;
+
+    infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
+          (int)ncopy);
     return ncopy;
   }
 
-  if(httpc->data) {
-    nread = len < httpc->datalen ? len : httpc->datalen;
-    memcpy(mem, httpc->data, nread);
+  infof(data, "http2_recv: %d bytes buffer at %p (stream %u)\n",
+        len, mem, stream->stream_id);
+
+  if((data->state.drain) && stream->memlen) {
+    DEBUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
+                 stream->memlen, stream->stream_id,
+                 stream->mem, mem));
+    if(mem != stream->mem) {
+      /* if we didn't get the same buffer this time, we must move the data to
+         the beginning */
+      memmove(mem, stream->mem, stream->memlen);
+      stream->len = len - stream->memlen;
+      stream->mem = mem;
+    }
+  }
+  else if(stream->pausedata) {
+    nread = MIN(len, stream->pauselen);
+    memcpy(mem, stream->pausedata, nread);
+
+    stream->pausedata += nread;
+    stream->pauselen -= nread;
 
-    httpc->data += nread;
-    httpc->datalen -= nread;
+    infof(data, "%zu data bytes written\n", nread);
+    if(stream->pauselen == 0) {
+      DEBUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
+      assert(httpc->pause_stream_id == stream->stream_id);
+      httpc->pause_stream_id = 0;
 
-    infof(conn->data, "%zu data written\n", nread);
-    if(httpc->datalen == 0) {
-      httpc->data = NULL;
-      httpc->datalen = 0;
+      stream->pausedata = NULL;
+      stream->pauselen = 0;
     }
+    infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
+          nread, stream->stream_id);
     return nread;
   }
+  else if(httpc->pause_stream_id) {
+    /* If a stream paused nghttp2_session_mem_recv previously, and has
+       not processed all data, it still refers to the buffer in
+       nghttp2_session.  If we call nghttp2_session_mem_recv(), we may
+       overwrite that buffer.  To avoid that situation, just return
+       here with CURLE_AGAIN.  This could be busy loop since data in
+       socket is not read.  But it seems that usually streams are
+       notified with its drain property, and socket is read again
+       quickly. */
+    *err = CURLE_AGAIN;
+    return -1;
+  }
+  else {
+    char *inbuf;
+    /* remember where to store incoming data for this stream and how big the
+       buffer is */
+    stream->mem = mem;
+    stream->len = len;
+    stream->memlen = 0;
+
+    if(httpc->inbuflen == 0) {
+      nread = ((Curl_recv *)httpc->recv_underlying)(
+          conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
+
+      if(result == CURLE_AGAIN) {
+        *err = result;
+        return -1;
+      }
 
-  conn->proto.httpc.mem = mem;
-  conn->proto.httpc.len = len;
-
-  infof(conn->data, "http2_recv: %d bytes buffer\n",
-        conn->proto.httpc.len);
+      if(nread == -1) {
+        failf(data, "Failed receiving HTTP2 data");
+        *err = result;
+        return 0;
+      }
 
-  rc = 0;
-  nread = ((Curl_recv*)httpc->recv_underlying)(conn, FIRSTSOCKET,
-                                               httpc->inbuf, H2_BUFSIZE, &rc);
+      if(nread == 0) {
+        failf(data, "Unexpected EOF");
+        *err = CURLE_RECV_ERROR;
+        return -1;
+      }
 
-  if(rc == CURLE_AGAIN) {
-    *err = rc;
-    return -1;
-  }
+      DEBUGF(infof(data, "nread=%zd\n", nread));
 
-  if(nread == -1) {
-    failf(conn->data, "Failed receiving HTTP2 data");
-    *err = rc;
-    return 0;
-  }
+      httpc->inbuflen = nread;
+      inbuf = httpc->inbuf;
+    }
+    else {
+      nread = httpc->inbuflen - httpc->nread_inbuf;
+      inbuf = httpc->inbuf + httpc->nread_inbuf;
 
-  infof(conn->data, "nread=%zd\n", nread);
-  rv = nghttp2_session_mem_recv(httpc->h2,
-                                (const uint8_t *)httpc->inbuf, nread);
+      DEBUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
+                   nread));
+    }
+    rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
 
-  if(nghttp2_is_fatal((int)rv)) {
-    failf(conn->data, "nghttp2_session_mem_recv() returned %d:%s\n",
-          rv, nghttp2_strerror((int)rv));
-    *err = CURLE_RECV_ERROR;
-    return 0;
-  }
-  infof(conn->data, "nghttp2_session_mem_recv() returns %zd\n", rv);
-  /* Always send pending frames in nghttp2 session, because
-     nghttp2_session_mem_recv() may queue new frame */
-  rv = nghttp2_session_send(httpc->h2);
-  if(rv != 0) {
-    *err = CURLE_SEND_ERROR;
-    return 0;
+    if(nghttp2_is_fatal((int)rv)) {
+      failf(data, "nghttp2_session_mem_recv() returned %d:%s\n",
+            rv, nghttp2_strerror((int)rv));
+      *err = CURLE_RECV_ERROR;
+      return 0;
+    }
+    DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
+    if(nread == rv) {
+      DEBUGF(infof(data, "All data in connection buffer processed\n"));
+      httpc->inbuflen = 0;
+      httpc->nread_inbuf = 0;
+    }
+    else {
+      httpc->nread_inbuf += rv;
+      DEBUGF(infof(data, "%zu bytes left in connection buffer\n",
+                   httpc->inbuflen - httpc->nread_inbuf));
+    }
+    /* Always send pending frames in nghttp2 session, because
+       nghttp2_session_mem_recv() may queue new frame */
+    rv = nghttp2_session_send(httpc->h2);
+    if(rv != 0) {
+      *err = CURLE_SEND_ERROR;
+      return 0;
+    }
   }
-  if(len != httpc->len) {
-    return len - conn->proto.httpc.len;
+  if(stream->memlen) {
+    ssize_t retlen = stream->memlen;
+    infof(data, "http2_recv: returns %zd for stream %u\n",
+          retlen, stream->stream_id);
+    stream->memlen = 0;
+
+    if(httpc->pause_stream_id == stream->stream_id) {
+      /* data for this stream is returned now, but this stream caused a pause
+         already so we need it called again asap */
+      DEBUGF(infof(data, "Data returned for PAUSED stream %u\n",
+                   stream->stream_id));
+    }
+    else
+      data->state.drain = 0; /* this stream is hereby drained */
+
+    return retlen;
   }
   /* If stream is closed, return 0 to signal the http routine to close
      the connection */
-  if(httpc->closed) {
-    /* Reset to FALSE to prevent infinite loop in readwrite_data
-       function. */
-    httpc->closed = FALSE;
-    return 0;
+  if(stream->closed) {
+    return http2_handle_stream_close(httpc, data, stream, err);
   }
   *err = CURLE_AGAIN;
+  DEBUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
+               stream->stream_id));
   return -1;
 }
 
@@ -791,6 +1195,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
    */
   int rv;
   struct http_conn *httpc = &conn->proto.httpc;
+  struct HTTP *stream = conn->data->req.protop;
   nghttp2_nv *nva;
   size_t nheader;
   size_t i;
@@ -799,23 +1204,41 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   char *end;
   nghttp2_data_provider data_prd;
   int32_t stream_id;
+  nghttp2_session *h2 = httpc->h2;
 
   (void)sockindex;
 
-  infof(conn->data, "http2_send len=%zu\n", len);
+  DEBUGF(infof(conn->data, "http2_send len=%zu\n", len));
 
-  if(httpc->stream_id != -1) {
+  if(stream->stream_id != -1) {
     /* If stream_id != -1, we have dispatched request HEADERS, and now
        are going to send or sending request body in DATA frame */
-    httpc->upload_mem = mem;
-    httpc->upload_len = len;
-    nghttp2_session_resume_data(httpc->h2, httpc->stream_id);
-    rv = nghttp2_session_send(httpc->h2);
+    stream->upload_mem = mem;
+    stream->upload_len = len;
+    nghttp2_session_resume_data(h2, stream->stream_id);
+    rv = nghttp2_session_send(h2);
     if(nghttp2_is_fatal(rv)) {
       *err = CURLE_SEND_ERROR;
       return -1;
     }
-    return len - httpc->upload_len;
+    len -= stream->upload_len;
+
+    /* Nullify here because we call nghttp2_session_send() and they
+       might refer to the old buffer. */
+    stream->upload_mem = NULL;
+    stream->upload_len = 0;
+
+    if(stream->upload_left) {
+      /* we are sure that we have more data to send here.  Calling the
+         following API will make nghttp2_session_want_write() return
+         nonzero if remote window allows it, which then libcurl checks
+         socket is writable or not.  See http2_perform_getsock(). */
+      nghttp2_session_resume_data(h2, stream->stream_id);
+    }
+
+    DEBUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len,
+                 stream->stream_id));
+    return len;
   }
 
   /* Calculate number of headers contained in [mem, mem + len) */
@@ -838,6 +1261,8 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   }
   /* Extract :method, :path from request line */
   end = strchr(hdbuf, ' ');
+  if(!end)
+    goto fail;
   nva[0].name = (unsigned char *)":method";
   nva[0].namelen = (uint16_t)strlen((char *)nva[0].name);
   nva[0].value = (unsigned char *)hdbuf;
@@ -847,6 +1272,8 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   hdbuf = end + 1;
 
   end = strchr(hdbuf, ' ');
+  if(!end)
+    goto fail;
   nva[1].name = (unsigned char *)":path";
   nva[1].namelen = (uint16_t)strlen((char *)nva[1].name);
   nva[1].value = (unsigned char *)hdbuf;
@@ -863,13 +1290,16 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   nva[2].flags = NGHTTP2_NV_FLAG_NONE;
 
   hdbuf = strchr(hdbuf, 0x0a);
+  if(!hdbuf)
+    goto fail;
   ++hdbuf;
 
   authority_idx = 0;
 
   for(i = 3; i < nheader; ++i) {
     end = strchr(hdbuf, ':');
-    assert(end);
+    if(!end)
+      goto fail;
     if(end - hdbuf == 4 && Curl_raw_nequal("host", hdbuf, 4)) {
       authority_idx = i;
       nva[i].name = (unsigned char *)":authority";
@@ -882,7 +1312,8 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
     hdbuf = end + 1;
     for(; *hdbuf == ' '; ++hdbuf);
     end = strchr(hdbuf, 0x0d);
-    assert(end);
+    if(!end)
+      goto fail;
     nva[i].value = (unsigned char *)hdbuf;
     nva[i].valuelen = (uint16_t)(end - hdbuf);
     nva[i].flags = NGHTTP2_NV_FLAG_NONE;
@@ -894,11 +1325,15 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
     if(nva[i].namelen == 14 &&
        Curl_raw_nequal("content-length", (char*)nva[i].name, 14)) {
       size_t j;
+      stream->upload_left = 0;
       for(j = 0; j < nva[i].valuelen; ++j) {
-        httpc->upload_left *= 10;
-        httpc->upload_left += nva[i].value[j] - '0';
+        stream->upload_left *= 10;
+        stream->upload_left += nva[i].value[j] - '0';
       }
-      infof(conn->data, "request content-length=%zu\n", httpc->upload_left);
+      DEBUGF(infof(conn->data,
+                   "request content-length=%"
+                   CURL_FORMAT_CURL_OFF_T
+                   "\n", stream->upload_left));
     }
   }
 
@@ -917,31 +1352,34 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   case HTTPREQ_PUT:
     data_prd.read_callback = data_source_read_callback;
     data_prd.source.ptr = NULL;
-    stream_id = nghttp2_submit_request(httpc->h2, NULL, nva, nheader,
-                                       &data_prd, NULL);
+    stream_id = nghttp2_submit_request(h2, NULL, nva, nheader,
+                                       &data_prd, conn->data);
     break;
   default:
-    stream_id = nghttp2_submit_request(httpc->h2, NULL, nva, nheader,
-                                       NULL, NULL);
+    stream_id = nghttp2_submit_request(h2, NULL, nva, nheader,
+                                       NULL, conn->data);
   }
 
   Curl_safefree(nva);
 
   if(stream_id < 0) {
+    DEBUGF(infof(conn->data, "http2_send() send error\n"));
     *err = CURLE_SEND_ERROR;
     return -1;
   }
 
-  httpc->stream_id = stream_id;
+  infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
+        stream_id, conn->data);
+  stream->stream_id = stream_id;
 
-  rv = nghttp2_session_send(httpc->h2);
+  rv = nghttp2_session_send(h2);
 
   if(rv != 0) {
     *err = CURLE_SEND_ERROR;
     return -1;
   }
 
-  if(httpc->stream_id != -1) {
+  if(stream->stream_id != -1) {
     /* If whole HEADERS frame was sent off to the underlying socket,
        the nghttp2 library calls data_source_read_callback. But only
        it found that no data available, so it deferred the DATA
@@ -950,67 +1388,83 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
        writable socket check is performed. To workaround this, we
        issue nghttp2_session_resume_data() here to bring back DATA
        transmission from deferred state. */
-    nghttp2_session_resume_data(httpc->h2, httpc->stream_id);
+    nghttp2_session_resume_data(h2, stream->stream_id);
   }
 
   return len;
+
+  fail:
+  free(nva);
+  *err = CURLE_SEND_ERROR;
+  return -1;
 }
 
 CURLcode Curl_http2_setup(struct connectdata *conn)
 {
+  CURLcode result;
   struct http_conn *httpc = &conn->proto.httpc;
+  struct HTTP *stream = conn->data->req.protop;
+
+  stream->stream_id = -1;
+
+  if(!stream->header_recvbuf)
+    stream->header_recvbuf = Curl_add_buffer_init();
+
+  if((conn->handler == &Curl_handler_http2_ssl) ||
+     (conn->handler == &Curl_handler_http2))
+    return CURLE_OK; /* already done */
+
   if(conn->handler->flags & PROTOPT_SSL)
     conn->handler = &Curl_handler_http2_ssl;
   else
     conn->handler = &Curl_handler_http2;
 
-  infof(conn->data, "Using HTTP2\n");
-  httpc->bodystarted = FALSE;
-  httpc->closed = FALSE;
-  httpc->header_recvbuf = Curl_add_buffer_init();
-  httpc->nread_header_recvbuf = 0;
-  httpc->data = NULL;
-  httpc->datalen = 0;
-  httpc->upload_left = 0;
-  httpc->upload_mem = NULL;
-  httpc->upload_len = 0;
-  httpc->stream_id = -1;
-  httpc->status_code = -1;
+  result = Curl_http2_init(conn);
+  if(result)
+    return result;
+
+  infof(conn->data, "Using HTTP2, server supports multi-use\n");
+  stream->upload_left = 0;
+  stream->upload_mem = NULL;
+  stream->upload_len = 0;
 
+  httpc->inbuflen = 0;
+  httpc->nread_inbuf = 0;
+
+  httpc->pause_stream_id = 0;
+
+  conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
   conn->httpversion = 20;
+  conn->bundle->multiuse = BUNDLE_MULTIPLEX;
 
-  return 0;
+  infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
+  Curl_multi_connchanged(conn->data->multi);
+
+  return CURLE_OK;
 }
 
-CURLcode Curl_http2_switched(struct connectdata *conn)
+CURLcode Curl_http2_switched(struct connectdata *conn,
+                             const char *mem, size_t nread)
 {
-  CURLcode rc;
+  CURLcode result;
   struct http_conn *httpc = &conn->proto.httpc;
   int rv;
+  ssize_t nproc;
   struct SessionHandle *data = conn->data;
+  struct HTTP *stream = conn->data->req.protop;
+
+  result = Curl_http2_setup(conn);
+  if(result)
+    return result;
 
   httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET];
   httpc->send_underlying = (sending)conn->send[FIRSTSOCKET];
   conn->recv[FIRSTSOCKET] = http2_recv;
   conn->send[FIRSTSOCKET] = http2_send;
 
-  rv = (int) ((Curl_send*)httpc->send_underlying)
-    (conn, FIRSTSOCKET,
-     NGHTTP2_CLIENT_CONNECTION_PREFACE,
-     NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN,
-     &rc);
-  if(rc)
-    /* TODO: This may get CURLE_AGAIN */
-    return rc;
-
-  if(rv != 24) {
-    failf(data, "Only sent partial HTTP2 packet");
-    return CURLE_SEND_ERROR;
-  }
-
   if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
     /* stream 1 is opened implicitly on upgrade */
-    httpc->stream_id = 1;
+    stream->stream_id = 1;
     /* queue SETTINGS frame (again) */
     rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,
                                  httpc->binlen, NULL);
@@ -1019,10 +1473,14 @@ CURLcode Curl_http2_switched(struct connectdata *conn)
             nghttp2_strerror(rv), rv);
       return CURLE_HTTP2;
     }
+
+    nghttp2_session_set_stream_user_data(httpc->h2,
+                                         stream->stream_id,
+                                         conn->data);
   }
   else {
     /* stream ID is unknown at this point */
-    httpc->stream_id = -1;
+    stream->stream_id = -1;
     rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);
     if(rv != 0) {
       failf(data, "nghttp2_submit_settings() failed: %s(%d)",
@@ -1030,7 +1488,75 @@ CURLcode Curl_http2_switched(struct connectdata *conn)
       return CURLE_HTTP2;
     }
   }
+
+  /* we are going to copy mem to httpc->inbuf.  This is required since
+     mem is part of buffer pointed by stream->mem, and callbacks
+     called by nghttp2_session_mem_recv() will write stream specific
+     data into stream->mem, overwriting data already there. */
+  if(H2_BUFSIZE < nread) {
+    failf(data, "connection buffer size is too small to store data following "
+                "HTTP Upgrade response header: buflen=%zu, datalen=%zu",
+          H2_BUFSIZE, nread);
+    return CURLE_HTTP2;
+  }
+
+  infof(conn->data, "Copying HTTP/2 data in stream buffer to connection buffer"
+                    " after upgrade: len=%zu\n",
+        nread);
+
+  memcpy(httpc->inbuf, mem, nread);
+  httpc->inbuflen = nread;
+
+  nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
+                                   httpc->inbuflen);
+
+  if(nghttp2_is_fatal((int)nproc)) {
+    failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
+          nghttp2_strerror((int)nproc), (int)nproc);
+    return CURLE_HTTP2;
+  }
+
+  DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
+
+  if((ssize_t)nread == nproc) {
+    httpc->inbuflen = 0;
+    httpc->nread_inbuf = 0;
+  }
+  else {
+    httpc->nread_inbuf += nproc;
+  }
+
+  /* Try to send some frames since we may read SETTINGS already. */
+  rv = nghttp2_session_send(httpc->h2);
+
+  if(rv != 0) {
+    failf(data, "nghttp2_session_send() failed: %s(%d)",
+          nghttp2_strerror(rv), rv);
+    return CURLE_HTTP2;
+  }
+
   return CURLE_OK;
 }
 
-#endif
+#else /* !USE_NGHTTP2 */
+
+/* Satisfy external references even if http2 is not compiled in. */
+
+#define CURL_DISABLE_TYPECHECK
+#include <curl/curl.h>
+
+char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
+{
+  (void) h;
+  (void) num;
+  return NULL;
+}
+
+char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
+{
+  (void) h;
+  (void) header;
+  return NULL;
+}
+
+#endif /* USE_NGHTTP2 */
diff --git a/Utilities/cmcurl/lib/http2.h b/Utilities/cmcurl/lib/http2.h
index 66aa6fd..bb7ad9c 100644
--- a/Utilities/cmcurl/lib/http2.h
+++ b/Utilities/cmcurl/lib/http2.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,6 +26,11 @@
 
 #ifdef USE_NGHTTP2
 #include "http.h"
+
+/* value for MAX_CONCURRENT_STREAMS we use until we get an updated setting
+   from the peer */
+#define DEFAULT_MAX_CONCURRENT_STREAMS 13
+
 /*
  * Store nghttp2 version info in this buffer, Prefix with a space.  Return
  * total length written.
@@ -37,13 +42,19 @@ CURLcode Curl_http2_send_request(struct connectdata *conn);
 CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
                                     struct connectdata *conn);
 CURLcode Curl_http2_setup(struct connectdata *conn);
-CURLcode Curl_http2_switched(struct connectdata *conn);
+CURLcode Curl_http2_switched(struct connectdata *conn,
+                             const char *data, size_t nread);
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_conn(struct connectdata *conn);
+void Curl_http2_setup_req(struct SessionHandle *data);
 #else /* USE_NGHTTP2 */
 #define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
-#define Curl_http2_switched(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_setup_conn(x)
+#define Curl_http2_setup_req(x)
 #endif
 
 #endif /* HEADER_CURL_HTTP2_H */
diff --git a/Utilities/cmcurl/lib/http_chunks.c b/Utilities/cmcurl/lib/http_chunks.c
index 61a6098..7e91b37 100644
--- a/Utilities/cmcurl/lib/http_chunks.c
+++ b/Utilities/cmcurl/lib/http_chunks.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -29,15 +29,12 @@
 
 #include "content_encoding.h"
 #include "http.h"
-#include "curl_memory.h"
 #include "non-ascii.h" /* for Curl_convert_to_network prototype */
 #include "strtoofft.h"
 #include "warnless.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /*
@@ -158,7 +155,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
         if(result) {
           /* Curl_convert_from_network calls failf if unsuccessful */
           /* Treat it as a bad hex character */
-          return CHUNKE_ILLEGAL_HEX ;
+          return CHUNKE_ILLEGAL_HEX;
         }
 
         ch->datasize=curlx_strtoofft(ch->hexbuffer, &endptr, 16);
@@ -221,7 +218,6 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
                                           (ssize_t)piece);
         break;
 
-      case COMPRESS:
       default:
         failf (conn->data,
                "Unrecognized content encoding type. "
diff --git a/Utilities/cmcurl/lib/http_digest.c b/Utilities/cmcurl/lib/http_digest.c
index 55f5108..929e2c6 100644
--- a/Utilities/cmcurl/lib/http_digest.c
+++ b/Utilities/cmcurl/lib/http_digest.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,94 +26,14 @@
 
 #include "urldata.h"
 #include "rawstr.h"
-#include "curl_base64.h"
-#include "curl_md5.h"
+#include "curl_sasl.h"
 #include "http_digest.h"
-#include "strtok.h"
-#include "curl_memory.h"
-#include "vtls/vtls.h" /* for Curl_rand() */
-#include "non-ascii.h" /* included for Curl_convert_... prototypes */
-#include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
-#define MAX_VALUE_LENGTH 256
-#define MAX_CONTENT_LENGTH 1024
-
-static void digest_cleanup_one(struct digestdata *dig);
-
-/*
- * Return 0 on success and then the buffers are filled in fine.
- *
- * Non-zero means failure to parse.
- */
-static int get_pair(const char *str, char *value, char *content,
-                    const char **endptr)
-{
-  int c;
-  bool starts_with_quote = FALSE;
-  bool escape = FALSE;
-
-  for(c=MAX_VALUE_LENGTH-1; (*str && (*str != '=') && c--); )
-    *value++ = *str++;
-  *value=0;
-
-  if('=' != *str++)
-    /* eek, no match */
-    return 1;
-
-  if('\"' == *str) {
-    /* this starts with a quote so it must end with one as well! */
-    str++;
-    starts_with_quote = TRUE;
-  }
-
-  for(c=MAX_CONTENT_LENGTH-1; *str && c--; str++) {
-    switch(*str) {
-    case '\\':
-      if(!escape) {
-        /* possibly the start of an escaped quote */
-        escape = TRUE;
-        *content++ = '\\'; /* even though this is an escape character, we still
-                              store it as-is in the target buffer */
-        continue;
-      }
-      break;
-    case ',':
-      if(!starts_with_quote) {
-        /* this signals the end of the content if we didn't get a starting
-           quote and then we do "sloppy" parsing */
-        c=0; /* the end */
-        continue;
-      }
-      break;
-    case '\r':
-    case '\n':
-      /* end of string */
-      c=0;
-      continue;
-    case '\"':
-      if(!escape && starts_with_quote) {
-        /* end of string */
-        c=0;
-        continue;
-      }
-      break;
-    }
-    escape = FALSE;
-    *content++ = *str;
-  }
-  *content=0;
-
-  *endptr = str;
-
-  return 0; /* all is fine! */
-}
-
 /* Test example headers:
 
 WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
@@ -121,177 +41,31 @@ Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
 
 */
 
-CURLdigest Curl_input_digest(struct connectdata *conn,
-                             bool proxy,
-                             const char *header) /* rest of the *-authenticate:
-                                                    header */
+CURLcode Curl_input_digest(struct connectdata *conn,
+                           bool proxy,
+                           const char *header) /* rest of the *-authenticate:
+                                                  header */
 {
-  char *token = NULL;
-  char *tmp = NULL;
-  bool foundAuth = FALSE;
-  bool foundAuthInt = FALSE;
-  struct SessionHandle *data=conn->data;
-  bool before = FALSE; /* got a nonce before */
-  struct digestdata *d;
+  struct SessionHandle *data = conn->data;
+
+  /* Point to the correct struct with this */
+  struct digestdata *digest;
 
   if(proxy) {
-    d = &data->state.proxydigest;
+    digest = &data->state.proxydigest;
   }
   else {
-    d = &data->state.digest;
-  }
-
-  if(checkprefix("Digest", header)) {
-    header += strlen("Digest");
-
-    /* If we already have received a nonce, keep that in mind */
-    if(d->nonce)
-      before = TRUE;
-
-    /* clear off any former leftovers and init to defaults */
-    digest_cleanup_one(d);
-
-    for(;;) {
-      char value[MAX_VALUE_LENGTH];
-      char content[MAX_CONTENT_LENGTH];
-
-      while(*header && ISSPACE(*header))
-        header++;
-
-      /* extract a value=content pair */
-      if(!get_pair(header, value, content, &header)) {
-        if(Curl_raw_equal(value, "nonce")) {
-          d->nonce = strdup(content);
-          if(!d->nonce)
-            return CURLDIGEST_NOMEM;
-        }
-        else if(Curl_raw_equal(value, "stale")) {
-          if(Curl_raw_equal(content, "true")) {
-            d->stale = TRUE;
-            d->nc = 1; /* we make a new nonce now */
-          }
-        }
-        else if(Curl_raw_equal(value, "realm")) {
-          d->realm = strdup(content);
-          if(!d->realm)
-            return CURLDIGEST_NOMEM;
-        }
-        else if(Curl_raw_equal(value, "opaque")) {
-          d->opaque = strdup(content);
-          if(!d->opaque)
-            return CURLDIGEST_NOMEM;
-        }
-        else if(Curl_raw_equal(value, "qop")) {
-          char *tok_buf;
-          /* tokenize the list and choose auth if possible, use a temporary
-             clone of the buffer since strtok_r() ruins it */
-          tmp = strdup(content);
-          if(!tmp)
-            return CURLDIGEST_NOMEM;
-          token = strtok_r(tmp, ",", &tok_buf);
-          while(token != NULL) {
-            if(Curl_raw_equal(token, "auth")) {
-              foundAuth = TRUE;
-            }
-            else if(Curl_raw_equal(token, "auth-int")) {
-              foundAuthInt = TRUE;
-            }
-            token = strtok_r(NULL, ",", &tok_buf);
-          }
-          free(tmp);
-          /*select only auth o auth-int. Otherwise, ignore*/
-          if(foundAuth) {
-            d->qop = strdup("auth");
-            if(!d->qop)
-              return CURLDIGEST_NOMEM;
-          }
-          else if(foundAuthInt) {
-            d->qop = strdup("auth-int");
-            if(!d->qop)
-              return CURLDIGEST_NOMEM;
-          }
-        }
-        else if(Curl_raw_equal(value, "algorithm")) {
-          d->algorithm = strdup(content);
-          if(!d->algorithm)
-            return CURLDIGEST_NOMEM;
-          if(Curl_raw_equal(content, "MD5-sess"))
-            d->algo = CURLDIGESTALGO_MD5SESS;
-          else if(Curl_raw_equal(content, "MD5"))
-            d->algo = CURLDIGESTALGO_MD5;
-          else
-            return CURLDIGEST_BADALGO;
-        }
-        else {
-          /* unknown specifier, ignore it! */
-        }
-      }
-      else
-        break; /* we're done here */
-
-      /* pass all additional spaces here */
-      while(*header && ISSPACE(*header))
-        header++;
-      if(',' == *header)
-        /* allow the list to be comma-separated */
-        header++;
-    }
-    /* We had a nonce since before, and we got another one now without
-       'stale=true'. This means we provided bad credentials in the previous
-       request */
-    if(before && !d->stale)
-      return CURLDIGEST_BAD;
-
-    /* We got this header without a nonce, that's a bad Digest line! */
-    if(!d->nonce)
-      return CURLDIGEST_BAD;
+    digest = &data->state.digest;
   }
-  else
-    /* else not a digest, get out */
-    return CURLDIGEST_NONE;
-
-  return CURLDIGEST_FINE;
-}
 
-/* convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
-static void md5_to_ascii(unsigned char *source, /* 16 bytes */
-                         unsigned char *dest) /* 33 bytes */
-{
-  int i;
-  for(i=0; i<16; i++)
-    snprintf((char *)&dest[i*2], 3, "%02x", source[i]);
-}
-
-/* Perform quoted-string escaping as described in RFC2616 and its errata */
-static char *string_quoted(const char *source)
-{
-  char *dest, *d;
-  const char *s = source;
-  size_t n = 1; /* null terminator */
-
-  /* Calculate size needed */
-  while(*s) {
-    ++n;
-    if(*s == '"' || *s == '\\') {
-      ++n;
-    }
-    ++s;
-  }
+  if(!checkprefix("Digest", header))
+    return CURLE_BAD_CONTENT_ENCODING;
 
-  dest = malloc(n);
-  if(dest) {
-    s = source;
-    d = dest;
-    while(*s) {
-      if(*s == '"' || *s == '\\') {
-        *d++ = '\\';
-      }
-      *d++ = *s++;
-    }
-    *d = 0;
-  }
+  header += strlen("Digest");
+  while(*header && ISSPACE(*header))
+    header++;
 
-  return dest;
+  return Curl_sasl_decode_digest_http_message(header, digest);
 }
 
 CURLcode Curl_output_digest(struct connectdata *conn,
@@ -299,49 +73,35 @@ CURLcode Curl_output_digest(struct connectdata *conn,
                             const unsigned char *request,
                             const unsigned char *uripath)
 {
-  /* We have a Digest setup for this, use it!  Now, to get all the details for
-     this sorted out, I must urge you dear friend to read up on the RFC2617
-     section 3.2.2, */
-  size_t urilen;
-  unsigned char md5buf[16]; /* 16 bytes/128 bits */
-  unsigned char request_digest[33];
-  unsigned char *md5this;
-  unsigned char ha1[33];/* 32 digits and 1 zero byte */
-  unsigned char ha2[33];/* 32 digits and 1 zero byte */
-  char cnoncebuf[33];
-  char *cnonce = NULL;
-  size_t cnonce_sz = 0;
-  char *tmp = NULL;
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  unsigned char *path;
+  char *tmp;
+  char *response;
+  size_t len;
+  bool have_chlg;
+
+  /* Point to the address of the pointer that holds the string to send to the
+     server, which is for a plain host or for a HTTP proxy */
   char **allocuserpwd;
-  size_t userlen;
+
+  /* Point to the name and password for this */
   const char *userp;
-  char *userp_quoted;
   const char *passwdp;
-  struct auth *authp;
 
-  struct SessionHandle *data = conn->data;
-  struct digestdata *d;
-  CURLcode rc;
-/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
-   It converts digest text to ASCII so the MD5 will be correct for
-   what ultimately goes over the network.
-*/
-#define CURL_OUTPUT_DIGEST_CONV(a, b) \
-  rc = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
-  if(rc != CURLE_OK) { \
-    free(b); \
-    return rc; \
-  }
+  /* Point to the correct struct with this */
+  struct digestdata *digest;
+  struct auth *authp;
 
   if(proxy) {
-    d = &data->state.proxydigest;
+    digest = &data->state.proxydigest;
     allocuserpwd = &conn->allocptr.proxyuserpwd;
     userp = conn->proxyuser;
     passwdp = conn->proxypasswd;
     authp = &data->state.authproxy;
   }
   else {
-    d = &data->state.digest;
+    digest = &data->state.digest;
     allocuserpwd = &conn->allocptr.userpwd;
     userp = conn->user;
     passwdp = conn->passwd;
@@ -352,75 +112,21 @@ CURLcode Curl_output_digest(struct connectdata *conn,
 
   /* not set means empty */
   if(!userp)
-    userp="";
+    userp = "";
 
   if(!passwdp)
-    passwdp="";
+    passwdp = "";
+
+#if defined(USE_WINDOWS_SSPI)
+  have_chlg = digest->input_token ? TRUE : FALSE;
+#else
+  have_chlg = digest->nonce ? TRUE : FALSE;
+#endif
 
-  if(!d->nonce) {
+  if(!have_chlg) {
     authp->done = FALSE;
     return CURLE_OK;
   }
-  authp->done = TRUE;
-
-  if(!d->nc)
-    d->nc = 1;
-
-  if(!d->cnonce) {
-    snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
-             Curl_rand(data), Curl_rand(data),
-             Curl_rand(data), Curl_rand(data));
-    rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
-                            &cnonce, &cnonce_sz);
-    if(rc)
-      return rc;
-    d->cnonce = cnonce;
-  }
-
-  /*
-    if the algorithm is "MD5" or unspecified (which then defaults to MD5):
-
-    A1 = unq(username-value) ":" unq(realm-value) ":" passwd
-
-    if the algorithm is "MD5-sess" then:
-
-    A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
-         ":" unq(nonce-value) ":" unq(cnonce-value)
-  */
-
-  md5this = (unsigned char *)
-    aprintf("%s:%s:%s", userp, d->realm, passwdp);
-  if(!md5this)
-    return CURLE_OUT_OF_MEMORY;
-
-  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
-  Curl_md5it(md5buf, md5this);
-  Curl_safefree(md5this);
-  md5_to_ascii(md5buf, ha1);
-
-  if(d->algo == CURLDIGESTALGO_MD5SESS) {
-    /* nonce and cnonce are OUTSIDE the hash */
-    tmp = aprintf("%s:%s:%s", ha1, d->nonce, d->cnonce);
-    if(!tmp)
-      return CURLE_OUT_OF_MEMORY;
-    CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
-    Curl_md5it(md5buf, (unsigned char *)tmp);
-    Curl_safefree(tmp);
-    md5_to_ascii(md5buf, ha1);
-  }
-
-  /*
-    If the "qop" directive's value is "auth" or is unspecified, then A2 is:
-
-      A2       = Method ":" digest-uri-value
-
-          If the "qop" value is "auth-int", then A2 is:
-
-      A2       = Method ":" digest-uri-value ":" H(entity-body)
-
-    (The "Method" value is the HTTP request method as specified in section
-    5.1.1 of RFC 2616)
-  */
 
   /* So IE browsers < v7 cut off the URI part at the query part when they
      evaluate the MD5 and some (IIS?) servers work with them so we may need to
@@ -435,164 +141,39 @@ CURLcode Curl_output_digest(struct connectdata *conn,
      http://www.fngtps.com/2006/09/http-authentication
   */
 
-  if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL))
-    urilen = tmp - (char *)uripath;
-  else
-    urilen = strlen((char *)uripath);
-
-  md5this = (unsigned char *)aprintf("%s:%.*s", request, urilen, uripath);
+  if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL)) {
+    size_t urilen = tmp - (char *)uripath;
 
-  if(d->qop && Curl_raw_equal(d->qop, "auth-int")) {
-    /* We don't support auth-int for PUT or POST at the moment.
-       TODO: replace md5 of empty string with entity-body for PUT/POST */
-    unsigned char *md5this2 = (unsigned char *)
-      aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e");
-    Curl_safefree(md5this);
-    md5this = md5this2;
+    path = (unsigned char *) aprintf("%.*s", urilen, uripath);
   }
+  else
+    path = (unsigned char *) strdup((char *) uripath);
 
-  if(!md5this)
-    return CURLE_OUT_OF_MEMORY;
-
-  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
-  Curl_md5it(md5buf, md5this);
-  Curl_safefree(md5this);
-  md5_to_ascii(md5buf, ha2);
-
-  if(d->qop) {
-    md5this = (unsigned char *)aprintf("%s:%s:%08x:%s:%s:%s",
-                                       ha1,
-                                       d->nonce,
-                                       d->nc,
-                                       d->cnonce,
-                                       d->qop,
-                                       ha2);
-  }
-  else {
-    md5this = (unsigned char *)aprintf("%s:%s:%s",
-                                       ha1,
-                                       d->nonce,
-                                       ha2);
-  }
-  if(!md5this)
+  if(!path)
     return CURLE_OUT_OF_MEMORY;
 
-  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
-  Curl_md5it(md5buf, md5this);
-  Curl_safefree(md5this);
-  md5_to_ascii(md5buf, request_digest);
-
-  /* for test case 64 (snooped from a Mozilla 1.3a request)
-
-    Authorization: Digest username="testuser", realm="testrealm", \
-    nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
-
-    Digest parameters are all quoted strings.  Username which is provided by
-    the user will need double quotes and backslashes within it escaped.  For
-    the other fields, this shouldn't be an issue.  realm, nonce, and opaque
-    are copied as is from the server, escapes and all.  cnonce is generated
-    with web-safe characters.  uri is already percent encoded.  nc is 8 hex
-    characters.  algorithm and qop with standard values only contain web-safe
-    chracters.
-  */
-  userp_quoted = string_quoted(userp);
-  if(!userp_quoted)
-    return CURLE_OUT_OF_MEMORY;
+  result = Curl_sasl_create_digest_http_message(data, userp, passwdp, request,
+                                                path, digest, &response, &len);
+  free(path);
+  if(result)
+    return result;
 
-  if(d->qop) {
-    *allocuserpwd =
-      aprintf( "%sAuthorization: Digest "
-               "username=\"%s\", "
-               "realm=\"%s\", "
-               "nonce=\"%s\", "
-               "uri=\"%.*s\", "
-               "cnonce=\"%s\", "
-               "nc=%08x, "
-               "qop=%s, "
-               "response=\"%s\"",
-               proxy?"Proxy-":"",
-               userp_quoted,
-               d->realm,
-               d->nonce,
-               urilen, uripath, /* this is the PATH part of the URL */
-               d->cnonce,
-               d->nc,
-               d->qop,
-               request_digest);
-
-    if(Curl_raw_equal(d->qop, "auth"))
-      d->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 padded
-                  which tells to the server how many times you are using the
-                  same nonce in the qop=auth mode. */
-  }
-  else {
-    *allocuserpwd =
-      aprintf( "%sAuthorization: Digest "
-               "username=\"%s\", "
-               "realm=\"%s\", "
-               "nonce=\"%s\", "
-               "uri=\"%.*s\", "
-               "response=\"%s\"",
-               proxy?"Proxy-":"",
-               userp_quoted,
-               d->realm,
-               d->nonce,
-               urilen, uripath, /* this is the PATH part of the URL */
-               request_digest);
-  }
-  Curl_safefree(userp_quoted);
+  *allocuserpwd = aprintf("%sAuthorization: Digest %s\r\n",
+                          proxy ? "Proxy-" : "",
+                          response);
+  free(response);
   if(!*allocuserpwd)
     return CURLE_OUT_OF_MEMORY;
 
-  /* Add optional fields */
-  if(d->opaque) {
-    /* append opaque */
-    tmp = aprintf("%s, opaque=\"%s\"", *allocuserpwd, d->opaque);
-    if(!tmp)
-      return CURLE_OUT_OF_MEMORY;
-    free(*allocuserpwd);
-    *allocuserpwd = tmp;
-  }
-
-  if(d->algorithm) {
-    /* append algorithm */
-    tmp = aprintf("%s, algorithm=\"%s\"", *allocuserpwd, d->algorithm);
-    if(!tmp)
-      return CURLE_OUT_OF_MEMORY;
-    free(*allocuserpwd);
-    *allocuserpwd = tmp;
-  }
-
-  /* append CRLF + zero (3 bytes) to the userpwd header */
-  userlen = strlen(*allocuserpwd);
-  tmp = realloc(*allocuserpwd, userlen + 3);
-  if(!tmp)
-    return CURLE_OUT_OF_MEMORY;
-  strcpy(&tmp[userlen], "\r\n"); /* append the data */
-  *allocuserpwd = tmp;
+  authp->done = TRUE;
 
   return CURLE_OK;
 }
 
-static void digest_cleanup_one(struct digestdata *d)
-{
-  Curl_safefree(d->nonce);
-  Curl_safefree(d->cnonce);
-  Curl_safefree(d->realm);
-  Curl_safefree(d->opaque);
-  Curl_safefree(d->qop);
-  Curl_safefree(d->algorithm);
-
-  d->nc = 0;
-  d->algo = CURLDIGESTALGO_MD5; /* default algorithm */
-  d->stale = FALSE; /* default means normal, not stale */
-}
-
-
 void Curl_digest_cleanup(struct SessionHandle *data)
 {
-  digest_cleanup_one(&data->state.digest);
-  digest_cleanup_one(&data->state.proxydigest);
+  Curl_sasl_digest_cleanup(&data->state.digest);
+  Curl_sasl_digest_cleanup(&data->state.proxydigest);
 }
 
 #endif
diff --git a/Utilities/cmcurl/lib/http_digest.h b/Utilities/cmcurl/lib/http_digest.h
index c6a4e91..d13d563 100644
--- a/Utilities/cmcurl/lib/http_digest.h
+++ b/Utilities/cmcurl/lib/http_digest.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,24 +23,9 @@
  ***************************************************************************/
 #include "curl_setup.h"
 
-typedef enum {
-  CURLDIGEST_NONE, /* not a digest */
-  CURLDIGEST_BAD,  /* a digest, but one we don't like */
-  CURLDIGEST_BADALGO, /* unsupported algorithm requested */
-  CURLDIGEST_NOMEM,
-  CURLDIGEST_FINE, /* a digest we act on */
-
-  CURLDIGEST_LAST  /* last entry in this enum, don't use */
-} CURLdigest;
-
-enum {
-  CURLDIGESTALGO_MD5,
-  CURLDIGESTALGO_MD5SESS
-};
-
 /* this is for digest header input */
-CURLdigest Curl_input_digest(struct connectdata *conn,
-                             bool proxy, const char *header);
+CURLcode Curl_input_digest(struct connectdata *conn,
+                           bool proxy, const char *header);
 
 /* this is for creating digest header output */
 CURLcode Curl_output_digest(struct connectdata *conn,
diff --git a/Utilities/cmcurl/lib/http_negotiate.c b/Utilities/cmcurl/lib/http_negotiate.c
index c8bfa29..a1baf29 100644
--- a/Utilities/cmcurl/lib/http_negotiate.c
+++ b/Utilities/cmcurl/lib/http_negotiate.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,13 +22,7 @@
 
 #include "curl_setup.h"
 
-#ifdef HAVE_GSSAPI
-#ifdef HAVE_OLD_GSSMIT
-#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
-#define NCOMPAT 1
-#endif
-
-#ifndef CURL_DISABLE_HTTP
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
 
 #include "urldata.h"
 #include "sendf.h"
@@ -36,97 +30,63 @@
 #include "rawstr.h"
 #include "curl_base64.h"
 #include "http_negotiate.h"
-#include "curl_memory.h"
+#include "curl_sasl.h"
 #include "url.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
-static int
-get_gss_name(struct connectdata *conn, bool proxy, gss_name_t *server)
-{
-  OM_uint32 major_status, minor_status;
-  gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
-  char name[2048];
-  const char* service = "HTTP";
-
-  token.length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name :
-                                              conn->host.name) + 1;
-  if(token.length + 1 > sizeof(name))
-    return EMSGSIZE;
-
-  snprintf(name, sizeof(name), "%s@%s", service, proxy ? conn->proxy.name :
-           conn->host.name);
-
-  token.value = (void *) name;
-  major_status = gss_import_name(&minor_status,
-                                 &token,
-                                 GSS_C_NT_HOSTBASED_SERVICE,
-                                 server);
-
-  return GSS_ERROR(major_status) ? -1 : 0;
-}
-
-static void
-log_gss_error(struct connectdata *conn, OM_uint32 error_status,
-              const char *prefix)
-{
-  OM_uint32 maj_stat, min_stat;
-  OM_uint32 msg_ctx = 0;
-  gss_buffer_desc status_string;
-  char buf[1024];
-  size_t len;
-
-  snprintf(buf, sizeof(buf), "%s", prefix);
-  len = strlen(buf);
-  do {
-    maj_stat = gss_display_status(&min_stat,
-                                  error_status,
-                                  GSS_C_MECH_CODE,
-                                  GSS_C_NO_OID,
-                                  &msg_ctx,
-                                  &status_string);
-      if(sizeof(buf) > len + status_string.length + 1) {
-        snprintf(buf + len, sizeof(buf) - len,
-                 ": %s", (char*) status_string.value);
-      len += status_string.length;
-    }
-    gss_release_buffer(&min_stat, &status_string);
-  } while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
-
-  infof(conn->data, "%s\n", buf);
-}
-
-/* returning zero (0) means success, everything else is treated as "failure"
-   with no care exactly what the failure was */
-int Curl_input_negotiate(struct connectdata *conn, bool proxy,
-                         const char *header)
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+                              const char *header)
 {
   struct SessionHandle *data = conn->data;
   struct negotiatedata *neg_ctx = proxy?&data->state.proxyneg:
     &data->state.negotiate;
   OM_uint32 major_status, minor_status, discard_st;
+  gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
   gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
   gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
-  int ret;
   size_t len;
   size_t rawlen = 0;
-  CURLcode error;
+  CURLcode result;
 
   if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
     /* We finished successfully our part of authentication, but server
      * rejected it (since we're again here). Exit with an error since we
      * can't invent anything better */
     Curl_cleanup_negotiate(data);
-    return -1;
+    return CURLE_LOGIN_DENIED;
   }
 
-  if(neg_ctx->server_name == NULL &&
-      (ret = get_gss_name(conn, proxy, &neg_ctx->server_name)))
-    return ret;
+  if(!neg_ctx->server_name) {
+    /* Generate our SPN */
+    char *spn = Curl_sasl_build_gssapi_spn(
+      proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
+      data->set.str[STRING_SERVICE_NAME],
+      proxy ? conn->proxy.name : conn->host.name);
+    if(!spn)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Populate the SPN structure */
+    spn_token.value = spn;
+    spn_token.length = strlen(spn);
+
+    /* Import the SPN */
+    major_status = gss_import_name(&minor_status, &spn_token,
+                                   GSS_C_NT_HOSTBASED_SERVICE,
+                                   &neg_ctx->server_name);
+    if(GSS_ERROR(major_status)) {
+      Curl_gss_log_error(data, minor_status, "gss_import_name() failed: ");
+
+      free(spn);
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    free(spn);
+  }
 
   header += strlen("Negotiate");
   while(*header && ISSPACE(*header))
@@ -134,10 +94,17 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
 
   len = strlen(header);
   if(len > 0) {
-    error = Curl_base64_decode(header,
-                               (unsigned char **)&input_token.value, &rawlen);
-    if(error || rawlen == 0)
-      return -1;
+    result = Curl_base64_decode(header, (unsigned char **)&input_token.value,
+                                &rawlen);
+    if(result)
+      return result;
+
+    if(!rawlen) {
+      infof(data, "Negotiate handshake failure (empty challenge message)\n");
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
+
     input_token.length = rawlen;
 
     DEBUGASSERT(input_token.value != NULL);
@@ -151,6 +118,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
                                            GSS_C_NO_CHANNEL_BINDINGS,
                                            &input_token,
                                            &output_token,
+                                           TRUE,
                                            NULL);
   Curl_safefree(input_token.value);
 
@@ -158,20 +126,21 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
   if(GSS_ERROR(major_status)) {
     if(output_token.value)
       gss_release_buffer(&discard_st, &output_token);
-    log_gss_error(conn, minor_status, "gss_init_sec_context() failed: ");
-    return -1;
+    Curl_gss_log_error(conn->data, minor_status,
+                       "gss_init_sec_context() failed: ");
+    return CURLE_OUT_OF_MEMORY;
   }
 
   if(!output_token.value || !output_token.length) {
     if(output_token.value)
       gss_release_buffer(&discard_st, &output_token);
-    return -1;
+    return CURLE_OUT_OF_MEMORY;
   }
 
   neg_ctx->output_token = output_token;
-  return 0;
-}
 
+  return CURLE_OK;
+}
 
 CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
 {
@@ -180,18 +149,18 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
   char *encoded = NULL;
   size_t len = 0;
   char *userp;
-  CURLcode error;
+  CURLcode result;
   OM_uint32 discard_st;
 
-  error = Curl_base64_encode(conn->data,
-                             neg_ctx->output_token.value,
-                             neg_ctx->output_token.length,
-                             &encoded, &len);
-  if(error) {
+  result = Curl_base64_encode(conn->data,
+                              neg_ctx->output_token.value,
+                              neg_ctx->output_token.length,
+                              &encoded, &len);
+  if(result) {
     gss_release_buffer(&discard_st, &neg_ctx->output_token);
     neg_ctx->output_token.value = NULL;
     neg_ctx->output_token.length = 0;
-    return error;
+    return result;
   }
 
   if(!encoded || !len) {
@@ -212,7 +181,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
     conn->allocptr.userpwd = userp;
   }
 
-  Curl_safefree(encoded);
+  free(encoded);
 
   return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
 }
@@ -238,6 +207,4 @@ void Curl_cleanup_negotiate(struct SessionHandle *data)
   cleanup(&data->state.proxyneg);
 }
 
-
-#endif
-#endif
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_HTTP && USE_SPNEGO */
diff --git a/Utilities/cmcurl/lib/http_negotiate.h b/Utilities/cmcurl/lib/http_negotiate.h
index f7efe8c..a8eb980 100644
--- a/Utilities/cmcurl/lib/http_negotiate.h
+++ b/Utilities/cmcurl/lib/http_negotiate.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,8 +25,8 @@
 #ifdef USE_SPNEGO
 
 /* this is for Negotiate header input */
-int Curl_input_negotiate(struct connectdata *conn, bool proxy,
-                         const char *header);
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+                              const char *header);
 
 /* this is for creating Negotiate header output */
 CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
diff --git a/Utilities/cmcurl/lib/http_negotiate_sspi.c b/Utilities/cmcurl/lib/http_negotiate_sspi.c
index 61581f1..a50ea96 100644
--- a/Utilities/cmcurl/lib/http_negotiate_sspi.c
+++ b/Utilities/cmcurl/lib/http_negotiate_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -33,30 +33,27 @@
 #include "curl_base64.h"
 #include "curl_sasl.h"
 #include "http_negotiate.h"
-#include "curl_memory.h"
 #include "curl_multibyte.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
-/* returning zero (0) means success, everything else is treated as "failure"
-   with no care exactly what the failure was */
-int Curl_input_negotiate(struct connectdata *conn, bool proxy,
-                         const char *header)
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+                              const char *header)
 {
+  struct SessionHandle *data = conn->data;
   BYTE              *input_token = NULL;
   SecBufferDesc     out_buff_desc;
   SecBuffer         out_sec_buff;
   SecBufferDesc     in_buff_desc;
   SecBuffer         in_sec_buff;
-  unsigned long     context_attributes;
-  TimeStamp         lifetime;
-  int ret;
+  SECURITY_STATUS   status;
+  unsigned long     attrs;
+  TimeStamp         expiry; /* For Windows 9x compatibility of SSPI calls */
   size_t len = 0, input_token_len = 0;
-  CURLcode error;
+  CURLcode result;
 
   /* Point to the username and password */
   const char *userp;
@@ -68,12 +65,12 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
   if(proxy) {
     userp = conn->proxyuser;
     passwdp = conn->proxypasswd;
-    neg_ctx = &conn->data->state.proxyneg;
+    neg_ctx = &data->state.proxyneg;
   }
   else {
     userp = conn->user;
     passwdp = conn->passwd;
-    neg_ctx = &conn->data->state.negotiate;
+    neg_ctx = &data->state.negotiate;
   }
 
   /* Not set means empty */
@@ -87,34 +84,36 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
     /* We finished successfully our part of authentication, but server
      * rejected it (since we're again here). Exit with an error since we
      * can't invent anything better */
-    Curl_cleanup_negotiate(conn->data);
-    return -1;
+    Curl_cleanup_negotiate(data);
+    return CURLE_LOGIN_DENIED;
   }
 
   if(!neg_ctx->server_name) {
     /* Check proxy auth requested but no given proxy name */
     if(proxy && !conn->proxy.name)
-      return -1;
+      return CURLE_BAD_FUNCTION_ARGUMENT;
 
     /* Generate our SPN */
-    neg_ctx->server_name = Curl_sasl_build_spn("HTTP",
-                                                proxy ? conn->proxy.name :
-                                                        conn->host.name);
+    neg_ctx->server_name = Curl_sasl_build_spn(
+      proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
+      data->set.str[STRING_SERVICE_NAME],
+      proxy ? conn->proxy.name : conn->host.name);
     if(!neg_ctx->server_name)
-      return -1;
+      return CURLE_OUT_OF_MEMORY;
   }
 
   if(!neg_ctx->output_token) {
     PSecPkgInfo SecurityPackage;
-    ret = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("Negotiate"),
-                                             &SecurityPackage);
-    if(ret != SEC_E_OK)
-      return -1;
+    status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
+                                                TEXT(SP_NAME_NEGOTIATE),
+                                                &SecurityPackage);
+    if(status != SEC_E_OK)
+      return CURLE_NOT_BUILT_IN;
 
     /* Allocate input and output buffers according to the max token size
        as indicated by the security package */
-    neg_ctx->max_token_length = SecurityPackage->cbMaxToken;
-    neg_ctx->output_token = malloc(neg_ctx->max_token_length);
+    neg_ctx->token_max = SecurityPackage->cbMaxToken;
+    neg_ctx->output_token = malloc(neg_ctx->token_max);
     s_pSecFn->FreeContextBuffer(SecurityPackage);
   }
 
@@ -129,7 +128,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
     if(neg_ctx->context) {
       /* The server rejected our authentication and hasn't suppled any more
          negotiation mechanisms */
-      return -1;
+      return CURLE_LOGIN_DENIED;
     }
 
     /* We have to acquire credentials and allocate memory for the context */
@@ -137,13 +136,13 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
     neg_ctx->context = malloc(sizeof(CtxtHandle));
 
     if(!neg_ctx->credentials || !neg_ctx->context)
-      return -1;
+      return CURLE_OUT_OF_MEMORY;
 
     if(userp && *userp) {
       /* Populate our identity structure */
-      error = Curl_create_sspi_identity(userp, passwdp, &neg_ctx->identity);
-      if(error)
-        return -1;
+      result = Curl_create_sspi_identity(userp, passwdp, &neg_ctx->identity);
+      if(result)
+        return result;
 
       /* Allow proper cleanup of the identity structure */
       neg_ctx->p_identity = &neg_ctx->identity;
@@ -155,19 +154,26 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
     /* Acquire our credientials handle */
     neg_ctx->status =
       s_pSecFn->AcquireCredentialsHandle(NULL,
-                                         (TCHAR *) TEXT("Negotiate"),
+                                         (TCHAR *) TEXT(SP_NAME_NEGOTIATE),
                                          SECPKG_CRED_OUTBOUND, NULL,
                                          neg_ctx->p_identity, NULL, NULL,
-                                         neg_ctx->credentials, &lifetime);
+                                         neg_ctx->credentials, &expiry);
     if(neg_ctx->status != SEC_E_OK)
-      return -1;
+      return CURLE_LOGIN_DENIED;
   }
   else {
-    error = Curl_base64_decode(header,
-                               (unsigned char **)&input_token,
-                               &input_token_len);
-    if(error || !input_token_len)
-      return -1;
+    result = Curl_base64_decode(header,
+                                (unsigned char **)&input_token,
+                                &input_token_len);
+    if(result)
+      return result;
+
+    if(!input_token_len) {
+      infof(data,
+            "Negotiate handshake failure (empty challenge message)\n");
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
   }
 
   /* Setup the "output" security buffer */
@@ -176,7 +182,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
   out_buff_desc.pBuffers  = &out_sec_buff;
   out_sec_buff.BufferType = SECBUFFER_TOKEN;
   out_sec_buff.pvBuffer   = neg_ctx->output_token;
-  out_sec_buff.cbBuffer   = curlx_uztoul(neg_ctx->max_token_length);
+  out_sec_buff.cbBuffer   = curlx_uztoul(neg_ctx->token_max);
 
   /* Setup the "input" security buffer if present */
   if(input_token) {
@@ -200,28 +206,27 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
     0,
     neg_ctx->context,
     &out_buff_desc,
-    &context_attributes,
-    &lifetime);
+    &attrs,
+    &expiry);
 
-  Curl_safefree(input_token);
+  free(input_token);
 
   if(GSS_ERROR(neg_ctx->status))
-    return -1;
+    return CURLE_OUT_OF_MEMORY;
 
   if(neg_ctx->status == SEC_I_COMPLETE_NEEDED ||
      neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE) {
     neg_ctx->status = s_pSecFn->CompleteAuthToken(neg_ctx->context,
                                                   &out_buff_desc);
     if(GSS_ERROR(neg_ctx->status))
-      return -1;
+      return CURLE_RECV_ERROR;
   }
 
   neg_ctx->output_token_length = out_sec_buff.cbBuffer;
 
-  return 0;
+  return CURLE_OK;
 }
 
-
 CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
 {
   struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
@@ -258,25 +263,30 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
 
 static void cleanup(struct negotiatedata *neg_ctx)
 {
+  /* Free our security context */
   if(neg_ctx->context) {
     s_pSecFn->DeleteSecurityContext(neg_ctx->context);
     free(neg_ctx->context);
     neg_ctx->context = NULL;
   }
 
+  /* Free our credentials handle */
   if(neg_ctx->credentials) {
     s_pSecFn->FreeCredentialsHandle(neg_ctx->credentials);
     free(neg_ctx->credentials);
     neg_ctx->credentials = NULL;
   }
 
-  neg_ctx->max_token_length = 0;
-  Curl_safefree(neg_ctx->output_token);
+  /* Free our identity */
+  Curl_sspi_free_identity(neg_ctx->p_identity);
+  neg_ctx->p_identity = NULL;
 
+  /* Free the SPN and output token */
   Curl_safefree(neg_ctx->server_name);
+  Curl_safefree(neg_ctx->output_token);
 
-  Curl_sspi_free_identity(neg_ctx->p_identity);
-  neg_ctx->p_identity = NULL;
+  /* Reset any variables */
+  neg_ctx->token_max = 0;
 }
 
 void Curl_cleanup_negotiate(struct SessionHandle *data)
diff --git a/Utilities/cmcurl/lib/http_proxy.c b/Utilities/cmcurl/lib/http_proxy.c
index 5343eb7..4373d62 100644
--- a/Utilities/cmcurl/lib/http_proxy.c
+++ b/Utilities/cmcurl/lib/http_proxy.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,10 +35,7 @@
 #include "progress.h"
 #include "non-ascii.h"
 #include "connect.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curlx.h"
 
 #include "curl_memory.h"
@@ -71,10 +68,11 @@ CURLcode Curl_proxy_connect(struct connectdata *conn)
     conn->data->req.protop = &http_proxy;
     connkeep(conn, "HTTP proxy CONNECT");
     result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
-                               conn->host.name, conn->remote_port);
+                               conn->host.name, conn->remote_port, FALSE);
     conn->data->req.protop = prot_save;
     if(CURLE_OK != result)
       return result;
+    Curl_safefree(conn->allocptr.proxyuserpwd);
 #else
     return CURLE_NOT_BUILT_IN;
 #endif
@@ -87,12 +85,16 @@ CURLcode Curl_proxy_connect(struct connectdata *conn)
  * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
  * function will issue the necessary commands to get a seamless tunnel through
  * this proxy. After that, the socket can be used just as a normal socket.
+ *
+ * 'blocking' set to TRUE means that this function will do the entire CONNECT
+ * + response in a blocking fashion. Should be avoided!
  */
 
 CURLcode Curl_proxyCONNECT(struct connectdata *conn,
                            int sockindex,
                            const char *hostname,
-                           int remote_port)
+                           int remote_port,
+                           bool blocking)
 {
   int subversion=0;
   struct SessionHandle *data=conn->data;
@@ -123,13 +125,11 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
       infof(data, "Establish HTTP proxy tunnel to %s:%hu\n",
             hostname, remote_port);
 
-      if(data->req.newurl) {
         /* This only happens if we've looped here due to authentication
            reasons, and we don't really use the newly cloned URL here
            then. Just free() it. */
-        free(data->req.newurl);
-        data->req.newurl = NULL;
-      }
+      free(data->req.newurl);
+      data->req.newurl = NULL;
 
       /* initialize a dynamic send-buffer */
       req_buffer = Curl_add_buffer_init();
@@ -139,7 +139,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
 
       host_port = aprintf("%s:%hu", hostname, remote_port);
       if(!host_port) {
-        free(req_buffer);
+        Curl_add_buffer_free(req_buffer);
         return CURLE_OUT_OF_MEMORY;
       }
 
@@ -148,7 +148,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
 
       free(host_port);
 
-      if(CURLE_OK == result) {
+      if(!result) {
         char *host=(char *)"";
         const char *proxyconn="";
         const char *useragent="";
@@ -159,7 +159,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
                   hostname, conn->bits.ipv6_ip?"]":"",
                   remote_port);
         if(!hostheader) {
-          free(req_buffer);
+          Curl_add_buffer_free(req_buffer);
           return CURLE_OUT_OF_MEMORY;
         }
 
@@ -167,7 +167,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
           host = aprintf("Host: %s\r\n", hostheader);
           if(!host) {
             free(hostheader);
-            free(req_buffer);
+            Curl_add_buffer_free(req_buffer);
             return CURLE_OUT_OF_MEMORY;
           }
         }
@@ -197,14 +197,14 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
           free(host);
         free(hostheader);
 
-        if(CURLE_OK == result)
+        if(!result)
           result = Curl_add_custom_headers(conn, TRUE, req_buffer);
 
-        if(CURLE_OK == result)
+        if(!result)
           /* CRLF terminate the request */
           result = Curl_add_bufferf(req_buffer, "\r\n");
 
-        if(CURLE_OK == result) {
+        if(!result) {
           /* Send the connect request to the proxy */
           /* BLOCKING */
           result =
@@ -216,7 +216,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
           failf(data, "Failed sending CONNECT to proxy");
       }
 
-      Curl_safefree(req_buffer);
+      Curl_add_buffer_free(req_buffer);
       if(result)
         return result;
 
@@ -229,12 +229,14 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
       return CURLE_RECV_ERROR;
     }
 
-    if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
-      /* return so we'll be called again polling-style */
-      return CURLE_OK;
-    else {
-      DEBUGF(infof(data,
-                   "Read response immediately from proxy CONNECT\n"));
+    if(!blocking) {
+      if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
+        /* return so we'll be called again polling-style */
+        return CURLE_OK;
+      else {
+        DEBUGF(infof(data,
+               "Read response immediately from proxy CONNECT\n"));
+      }
     }
 
     /* at this point, the tunnel_connecting phase is over. */
@@ -252,7 +254,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
 
       nread=0;
       perline=0;
-      keepon=TRUE;
 
       while((nread<BUFSIZE) && (keepon && !error)) {
 
@@ -286,7 +287,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
               /* proxy auth was requested and there was proxy auth available,
                  then deem this as "mere" proxy disconnect */
               conn->bits.proxy_connect_closed = TRUE;
-              infof(data, "Proxy CONNECT connection closed");
+              infof(data, "Proxy CONNECT connection closed\n");
             }
             else {
               error = SELECT_ERROR;
@@ -468,7 +469,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
 
                     result = Curl_http_input_auth(conn, proxy, auth);
 
-                    Curl_safefree(auth);
+                    free(auth);
 
                     if(result)
                       return result;
@@ -555,11 +556,8 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
       infof(data, "Connect me again please\n");
     }
     else {
-      if(data->req.newurl) {
-        /* this won't be used anymore for the CONNECT so free it now */
-        free(data->req.newurl);
-        data->req.newurl = NULL;
-      }
+      free(data->req.newurl);
+      data->req.newurl = NULL;
       /* failure, close this connection to avoid re-use */
       connclose(conn, "proxy CONNECT failure");
       Curl_closesocket(conn, conn->sock[sockindex]);
diff --git a/Utilities/cmcurl/lib/http_proxy.h b/Utilities/cmcurl/lib/http_proxy.h
index 2b5e9c9..9c4f020 100644
--- a/Utilities/cmcurl/lib/http_proxy.h
+++ b/Utilities/cmcurl/lib/http_proxy.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,7 +26,8 @@
 /* ftp can use this as well */
 CURLcode Curl_proxyCONNECT(struct connectdata *conn,
                            int tunnelsocket,
-                           const char *hostname, int remote_port);
+                           const char *hostname, int remote_port,
+                           bool blocking);
 
 /* Default proxy timeout in milliseconds */
 #define PROXY_TIMEOUT (3600*1000)
@@ -34,7 +35,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
 CURLcode Curl_proxy_connect(struct connectdata *conn);
 
 #else
-#define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN
+#define Curl_proxyCONNECT(x,y,z,w,v) CURLE_NOT_BUILT_IN
 #define Curl_proxy_connect(x) CURLE_OK
 #endif
 
diff --git a/Utilities/cmcurl/lib/idn_win32.c b/Utilities/cmcurl/lib/idn_win32.c
index 464964b..b369723 100644
--- a/Utilities/cmcurl/lib/idn_win32.c
+++ b/Utilities/cmcurl/lib/idn_win32.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,8 +35,31 @@
 #include "memdebug.h"
 
 #ifdef WANT_IDN_PROTOTYPES
-WINBASEAPI int WINAPI IdnToAscii(DWORD, const WCHAR *, int, WCHAR *, int);
-WINBASEAPI int WINAPI IdnToUnicode(DWORD, const WCHAR *, int, WCHAR *, int);
+#  if defined(_SAL_VERSION)
+WINNORMALIZEAPI int WINAPI
+IdnToAscii(_In_                           DWORD    dwFlags,
+           _In_reads_(cchUnicodeChar)     LPCWSTR  lpUnicodeCharStr,
+           _In_                           int      cchUnicodeChar,
+           _Out_writes_opt_(cchASCIIChar) LPWSTR   lpASCIICharStr,
+           _In_                           int      cchASCIIChar);
+WINNORMALIZEAPI int WINAPI
+IdnToUnicode(_In_                             DWORD   dwFlags,
+             _In_reads_(cchASCIIChar)         LPCWSTR lpASCIICharStr,
+             _In_                             int     cchASCIIChar,
+             _Out_writes_opt_(cchUnicodeChar) LPWSTR  lpUnicodeCharStr,
+             _In_                             int     cchUnicodeChar);
+#  else
+WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
+                                 const WCHAR *lpUnicodeCharStr,
+                                 int cchUnicodeChar,
+                                 WCHAR *lpASCIICharStr,
+                                 int cchASCIIChar);
+WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
+                                   const WCHAR *lpASCIICharStr,
+                                   int cchASCIIChar,
+                                   WCHAR *lpUnicodeCharStr,
+                                   int cchUnicodeChar);
+#  endif
 #endif
 
 #define IDN_MAX_LENGTH 255
diff --git a/Utilities/cmcurl/lib/if2ip.c b/Utilities/cmcurl/lib/if2ip.c
index 05ae7d6..6e6f969 100644
--- a/Utilities/cmcurl/lib/if2ip.c
+++ b/Utilities/cmcurl/lib/if2ip.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -53,9 +53,7 @@
 #include "inet_ntop.h"
 #include "strequal.h"
 #include "if2ip.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -63,6 +61,38 @@
 
 /* ------------------------------------------------------------------ */
 
+/* Return the scope of the given address. */
+unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
+{
+#ifndef ENABLE_IPV6
+  (void) sa;
+#else
+  if(sa->sa_family == AF_INET6) {
+    const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *) sa;
+    const unsigned char * b = sa6->sin6_addr.s6_addr;
+    unsigned short w = (unsigned short) ((b[0] << 8) | b[1]);
+
+    switch(w & 0xFFC0) {
+    case 0xFE80:
+      return IPV6_SCOPE_LINKLOCAL;
+    case 0xFEC0:
+      return IPV6_SCOPE_SITELOCAL;
+    case 0x0000:
+      w = b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] |
+          b[10] | b[11] | b[12] | b[13] | b[14];
+      if(w || b[15] != 0x01)
+        break;
+      return IPV6_SCOPE_NODELOCAL;
+    default:
+      break;
+    }
+  }
+#endif
+
+  return IPV6_SCOPE_GLOBAL;
+}
+
+
 #if defined(HAVE_GETIFADDRS)
 
 bool Curl_if_is_interface_name(const char *interf)
@@ -84,41 +114,58 @@ bool Curl_if_is_interface_name(const char *interf)
 }
 
 if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
-                          const char *interf, char *buf, int buf_size)
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size)
 {
   struct ifaddrs *iface, *head;
   if2ip_result_t res = IF2IP_NOT_FOUND;
 
 #ifndef ENABLE_IPV6
   (void) remote_scope;
+
+#ifndef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+  (void) remote_scope_id;
+#endif
+
 #endif
 
   if(getifaddrs(&head) >= 0) {
-    for(iface=head; iface != NULL; iface=iface->ifa_next) {
+    for(iface = head; iface != NULL; iface=iface->ifa_next) {
       if(iface->ifa_addr != NULL) {
         if(iface->ifa_addr->sa_family == af) {
           if(curl_strequal(iface->ifa_name, interf)) {
             void *addr;
             char *ip;
-            char scope[12]="";
+            char scope[12] = "";
             char ipstr[64];
 #ifdef ENABLE_IPV6
             if(af == AF_INET6) {
               unsigned int scopeid = 0;
+              unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
+
+              if(ifscope != remote_scope) {
+                /* We are interested only in interface addresses whose
+                   scope matches the remote address we want to
+                   connect to: global for global, link-local for
+                   link-local, etc... */
+                if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
+                continue;
+              }
+
               addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
 #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
               /* Include the scope of this interface as part of the address */
               scopeid =
                 ((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id;
-#endif
-              if(scopeid != remote_scope) {
-                /* We are interested only in interface addresses whose
-                   scope ID matches the remote address we want to
-                   connect to: global (0) for global, link-local for
-                   link-local, etc... */
-                if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
+
+              /* If given, scope id should match. */
+              if(remote_scope_id && scopeid != remote_scope_id) {
+                if(res == IF2IP_NOT_FOUND)
+                  res = IF2IP_AF_NOT_SUPPORTED;
+
                 continue;
               }
+#endif
               if(scopeid)
                 snprintf(scope, sizeof(scope), "%%%u", scopeid);
             }
@@ -137,8 +184,10 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
         }
       }
     }
+
     freeifaddrs(head);
   }
+
   return res;
 }
 
@@ -149,12 +198,13 @@ bool Curl_if_is_interface_name(const char *interf)
   /* This is here just to support the old interfaces */
   char buf[256];
 
-  return (Curl_if2ip(AF_INET, 0, interf, buf, sizeof(buf)) ==
+  return (Curl_if2ip(AF_INET, 0 /* unused */, 0, interf, buf, sizeof(buf)) ==
           IF2IP_NOT_FOUND) ? FALSE : TRUE;
 }
 
 if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
-                          const char *interf, char *buf, int buf_size)
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size)
 {
   struct ifreq req;
   struct in_addr in;
@@ -163,6 +213,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
   size_t len;
 
   (void)remote_scope;
+  (void)remote_scope_id;
 
   if(!interf || (af != AF_INET))
     return IF2IP_NOT_FOUND;
@@ -205,10 +256,12 @@ bool Curl_if_is_interface_name(const char *interf)
 }
 
 if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
-                          const char *interf, char *buf, int buf_size)
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size)
 {
     (void) af;
     (void) remote_scope;
+    (void) remote_scope_id;
     (void) interf;
     (void) buf;
     (void) buf_size;
diff --git a/Utilities/cmcurl/lib/if2ip.h b/Utilities/cmcurl/lib/if2ip.h
index ac58752..78bb0bd 100644
--- a/Utilities/cmcurl/lib/if2ip.h
+++ b/Utilities/cmcurl/lib/if2ip.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,6 +23,14 @@
  ***************************************************************************/
 #include "curl_setup.h"
 
+/* IPv6 address scopes. */
+#define IPV6_SCOPE_GLOBAL       0       /* Global scope. */
+#define IPV6_SCOPE_LINKLOCAL    1       /* Link-local scope. */
+#define IPV6_SCOPE_SITELOCAL    2       /* Site-local scope (deprecated). */
+#define IPV6_SCOPE_NODELOCAL    3       /* Loopback. */
+
+unsigned int Curl_ipv6_scope(const struct sockaddr *sa);
+
 bool Curl_if_is_interface_name(const char *interf);
 
 typedef enum {
@@ -32,7 +40,8 @@ typedef enum {
 } if2ip_result_t;
 
 if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
-                          const char *interf, char *buf, int buf_size);
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size);
 
 #ifdef __INTERIX
 
diff --git a/Utilities/cmcurl/lib/imap.c b/Utilities/cmcurl/lib/imap.c
index 9fc4728..e6d83f2 100644
--- a/Utilities/cmcurl/lib/imap.c
+++ b/Utilities/cmcurl/lib/imap.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -61,7 +61,6 @@
 #include <curl/curl.h>
 #include "urldata.h"
 #include "sendf.h"
-#include "if2ip.h"
 #include "hostip.h"
 #include "progress.h"
 #include "transfer.h"
@@ -81,9 +80,7 @@
 #include "rawstr.h"
 #include "curl_sasl.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -106,10 +103,12 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...);
 static CURLcode imap_parse_url_options(struct connectdata *conn);
 static CURLcode imap_parse_url_path(struct connectdata *conn);
 static CURLcode imap_parse_custom_request(struct connectdata *conn);
-static CURLcode imap_calc_sasl_details(struct connectdata *conn,
-                                       const char **mech,
-                                       char **initresp, size_t *len,
-                                       imapstate *state1, imapstate *state2);
+static CURLcode imap_perform_authenticate(struct connectdata *conn,
+                                          const char *mech,
+                                          const char *initresp);
+static CURLcode imap_continue_authenticate(struct connectdata *conn,
+                                           const char *resp);
+static void imap_get_message(char *buffer, char** outptr);
 
 /*
  * IMAP protocol handler.
@@ -132,7 +131,7 @@ const struct Curl_handler Curl_handler_imap = {
   ZERO_NULL,                        /* readwrite */
   PORT_IMAP,                        /* defport */
   CURLPROTO_IMAP,                   /* protocol */
-  PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD  /* flags */
+  PROTOPT_CLOSEACTION               /* flags */
 };
 
 #ifdef USE_SSL
@@ -157,8 +156,7 @@ const struct Curl_handler Curl_handler_imaps = {
   ZERO_NULL,                        /* readwrite */
   PORT_IMAPS,                       /* defport */
   CURLPROTO_IMAPS,                  /* protocol */
-  PROTOPT_CLOSEACTION | PROTOPT_SSL |
-  PROTOPT_NEEDSPWD                  /* flags */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
 };
 #endif
 
@@ -214,6 +212,18 @@ static const struct Curl_handler Curl_handler_imaps_proxy = {
 #endif
 #endif
 
+/* SASL parameters for the imap protocol */
+static const struct SASLproto saslimap = {
+  "imap",                     /* The service name */
+  '+',                        /* Code received when continuation is expected */
+  'O',                        /* Code to receive upon authentication success */
+  0,                          /* Maximum initial response length (no max) */
+  imap_perform_authenticate,  /* Send authentication command */
+  imap_continue_authenticate, /* Send authentication continuation */
+  imap_get_message            /* Get SASL response message */
+};
+
+
 #ifdef USE_SSL
 static void imap_to_imaps(struct connectdata *conn)
 {
@@ -354,16 +364,7 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
      (len >= 2 && !memcmp("+ ", line, 2))) {
     switch(imapc->state) {
       /* States which are interested in continuation responses */
-      case IMAP_AUTHENTICATE_PLAIN:
-      case IMAP_AUTHENTICATE_LOGIN:
-      case IMAP_AUTHENTICATE_LOGIN_PASSWD:
-      case IMAP_AUTHENTICATE_CRAMMD5:
-      case IMAP_AUTHENTICATE_DIGESTMD5:
-      case IMAP_AUTHENTICATE_DIGESTMD5_RESP:
-      case IMAP_AUTHENTICATE_NTLM:
-      case IMAP_AUTHENTICATE_NTLM_TYPE2MSG:
-      case IMAP_AUTHENTICATE_XOAUTH2:
-      case IMAP_AUTHENTICATE_FINAL:
+      case IMAP_AUTHENTICATE:
       case IMAP_APPEND:
         *resp = '+';
         break;
@@ -426,20 +427,7 @@ static void state(struct connectdata *conn, imapstate newstate)
     "CAPABILITY",
     "STARTTLS",
     "UPGRADETLS",
-    "AUTHENTICATE_PLAIN",
-    "AUTHENTICATE_LOGIN",
-    "AUTHENTICATE_LOGIN_PASSWD",
-    "AUTHENTICATE_CRAMMD5",
-    "AUTHENTICATE_DIGESTMD5",
-    "AUTHENTICATE_DIGESTMD5_RESP",
-    "AUTHENTICATE_NTLM",
-    "AUTHENTICATE_NTLM_TYPE2MSG",
-    "AUTHENTICATE_GSSAPI",
-    "AUTHENTICATE_GSSAPI_TOKEN",
-    "AUTHENTICATE_GSSAPI_NO_DATA",
-    "AUTHENTICATE_XOAUTH2",
-    "AUTHENTICATE_CANCEL",
-    "AUTHENTICATE_FINAL",
+    "AUTHENTICATE",
     "LOGIN",
     "LIST",
     "SELECT",
@@ -472,9 +460,9 @@ static CURLcode imap_perform_capability(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   struct imap_conn *imapc = &conn->proto.imapc;
 
-  imapc->authmechs = 0;         /* No known authentication mechanisms yet */
-  imapc->authused = 0;          /* Clear the authentication mechanism used */
-  imapc->tls_supported = FALSE; /* Clear the TLS capability */
+  imapc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */
+  imapc->sasl.authused = SASL_AUTH_NONE;  /* Clear the auth. mechanism used */
+  imapc->tls_supported = FALSE;           /* Clear the TLS capability */
 
   /* Send the CAPABILITY command */
   result = imap_sendf(conn, "CAPABILITY");
@@ -559,8 +547,8 @@ static CURLcode imap_perform_login(struct connectdata *conn)
   result = imap_sendf(conn, "LOGIN %s %s", user ? user : "",
                       passwd ? passwd : "");
 
-  Curl_safefree(user);
-  Curl_safefree(passwd);
+  free(user);
+  free(passwd);
 
   if(!result)
     state(conn, IMAP_LOGIN);
@@ -577,24 +565,17 @@ static CURLcode imap_perform_login(struct connectdata *conn)
  */
 static CURLcode imap_perform_authenticate(struct connectdata *conn,
                                           const char *mech,
-                                          const char *initresp,
-                                          imapstate state1, imapstate state2)
+                                          const char *initresp)
 {
   CURLcode result = CURLE_OK;
 
   if(initresp) {
     /* Send the AUTHENTICATE command with the initial response */
     result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
-
-    if(!result)
-      state(conn, state2);
   }
   else {
     /* Send the AUTHENTICATE command */
     result = imap_sendf(conn, "AUTHENTICATE %s", mech);
-
-    if(!result)
-      state(conn, state1);
   }
 
   return result;
@@ -602,6 +583,20 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn,
 
 /***********************************************************************
  *
+ * imap_continue_authenticate()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode imap_continue_authenticate(struct connectdata *conn,
+                                           const char *resp)
+{
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  return Curl_pp_sendf(&imapc->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
  * imap_perform_authentication()
  *
  * Initiates the authentication sequence, with the appropriate SASL
@@ -612,33 +607,22 @@ static CURLcode imap_perform_authentication(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct imap_conn *imapc = &conn->proto.imapc;
-  const char *mech = NULL;
-  char *initresp = NULL;
-  size_t len = 0;
-  imapstate state1 = IMAP_STOP;
-  imapstate state2 = IMAP_STOP;
+  saslprogress progress;
 
-  /* Check we have a username and password to authenticate with and end the
+  /* Check we have enough data to authenticate with and end the
      connect phase if we don't */
-  if(!conn->bits.user_passwd) {
+  if(!Curl_sasl_can_authenticate(&imapc->sasl, conn)) {
     state(conn, IMAP_STOP);
-
     return result;
   }
 
   /* Calculate the SASL login details */
-  result = imap_calc_sasl_details(conn, &mech, &initresp, &len, &state1,
-                                  &state2);
+  result = Curl_sasl_start(&imapc->sasl, conn, imapc->ir_supported, &progress);
 
   if(!result) {
-    if(mech && (imapc->preftype & IMAP_TYPE_SASL)) {
-      /* Perform SASL based authentication */
-      result = imap_perform_authenticate(conn, mech, initresp, state1, state2);
-
-      Curl_safefree(initresp);
-    }
-    else if((!imapc->login_disabled) &&
-            (imapc->preftype & IMAP_TYPE_CLEARTEXT))
+    if(progress == SASL_INPROGRESS)
+      state(conn, IMAP_AUTHENTICATE);
+    else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
       /* Perform clear text authentication */
       result = imap_perform_login(conn);
     else {
@@ -677,7 +661,7 @@ static CURLcode imap_perform_list(struct connectdata *conn)
     /* Send the LIST command */
     result = imap_sendf(conn, "LIST \"%s\" *", mailbox);
 
-    Curl_safefree(mailbox);
+    free(mailbox);
   }
 
   if(!result)
@@ -718,7 +702,7 @@ static CURLcode imap_perform_select(struct connectdata *conn)
   /* Send the SELECT command */
   result = imap_sendf(conn, "SELECT %s", mailbox);
 
-  Curl_safefree(mailbox);
+  free(mailbox);
 
   if(!result)
     state(conn, IMAP_SELECT);
@@ -793,7 +777,7 @@ static CURLcode imap_perform_append(struct connectdata *conn)
   result = imap_sendf(conn, "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}",
                       mailbox, conn->data->state.infilesize);
 
-  Curl_safefree(mailbox);
+  free(mailbox);
 
   if(!result)
     state(conn, IMAP_APPEND);
@@ -915,26 +899,16 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
 
       /* Do we have a SASL based authentication mechanism? */
       else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) {
+        size_t llen;
+        unsigned int mechbit;
+
         line += 5;
         wordlen -= 5;
 
         /* Test the word for a matching authentication mechanism */
-        if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
-          imapc->authmechs |= SASL_MECH_LOGIN;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
-          imapc->authmechs |= SASL_MECH_PLAIN;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
-          imapc->authmechs |= SASL_MECH_CRAM_MD5;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
-          imapc->authmechs |= SASL_MECH_DIGEST_MD5;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
-          imapc->authmechs |= SASL_MECH_GSSAPI;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
-          imapc->authmechs |= SASL_MECH_EXTERNAL;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
-          imapc->authmechs |= SASL_MECH_NTLM;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
-          imapc->authmechs |= SASL_MECH_XOAUTH2;
+        if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+           llen == wordlen)
+          imapc->sasl.authmechs |= mechbit;
       }
 
       line += wordlen;
@@ -987,569 +961,36 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn,
   return result;
 }
 
-/* For AUTHENTICATE PLAIN (without initial response) responses */
-static CURLcode imap_state_auth_plain_resp(struct connectdata *conn,
-                                           int imapcode,
-                                           imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *plainauth = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied. %c", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the authorisation message */
-    result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
-                                            &plainauth, &len);
-    if(!result && plainauth) {
-      /* Send the message */
-      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", plainauth);
-
-      if(!result)
-        state(conn, IMAP_AUTHENTICATE_FINAL);
-    }
-  }
-
-  Curl_safefree(plainauth);
-
-  return result;
-}
-
-/* For AUTHENTICATE LOGIN (without initial response) responses */
-static CURLcode imap_state_auth_login_resp(struct connectdata *conn,
-                                           int imapcode,
-                                           imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *authuser = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the user message */
-    result = Curl_sasl_create_login_message(data, conn->user,
-                                            &authuser, &len);
-    if(!result && authuser) {
-      /* Send the user */
-      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authuser);
-
-      if(!result)
-        state(conn, IMAP_AUTHENTICATE_LOGIN_PASSWD);
-    }
-  }
-
-  Curl_safefree(authuser);
-
-  return result;
-}
-
-/* For AUTHENTICATE LOGIN user entry responses */
-static CURLcode imap_state_auth_login_password_resp(struct connectdata *conn,
-                                                    int imapcode,
-                                                    imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *authpasswd = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the password message */
-    result = Curl_sasl_create_login_message(data, conn->passwd,
-                                            &authpasswd, &len);
-    if(!result && authpasswd) {
-      /* Send the password */
-      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authpasswd);
-
-      if(!result)
-        state(conn, IMAP_AUTHENTICATE_FINAL);
-    }
-  }
-
-  Curl_safefree(authpasswd);
-
-  return result;
-}
-
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-/* For AUTHENTICATE CRAM-MD5 responses */
-static CURLcode imap_state_auth_cram_resp(struct connectdata *conn,
-                                          int imapcode,
-                                          imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *chlg = NULL;
-  char *chlg64 = NULL;
-  char *rplyb64 = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    return CURLE_LOGIN_DENIED;
-  }
-
-  /* Get the challenge message */
-  imap_get_message(data->state.buffer, &chlg64);
-
-  /* Decode the challenge message */
-  result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
-  if(result) {
-    /* Send the cancellation */
-    result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
-
-    if(!result)
-      state(conn, IMAP_AUTHENTICATE_CANCEL);
-  }
-  else {
-    /* Create the response message */
-    result = Curl_sasl_create_cram_md5_message(data, chlg, conn->user,
-                                               conn->passwd, &rplyb64, &len);
-    if(!result && rplyb64) {
-      /* Send the response */
-      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
-
-      if(!result)
-        state(conn, IMAP_AUTHENTICATE_FINAL);
-    }
-  }
-
-  Curl_safefree(chlg);
-  Curl_safefree(rplyb64);
-
-  return result;
-}
-
-/* For AUTHENTICATE DIGEST-MD5 challenge responses */
-static CURLcode imap_state_auth_digest_resp(struct connectdata *conn,
-                                            int imapcode,
-                                            imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *chlg64 = NULL;
-  char *rplyb64 = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    return CURLE_LOGIN_DENIED;
-  }
-
-  /* Get the challenge message */
-  imap_get_message(data->state.buffer, &chlg64);
-
-  /* Create the response message */
-  result = Curl_sasl_create_digest_md5_message(data, chlg64,
-                                               conn->user, conn->passwd,
-                                               "imap", &rplyb64, &len);
-  if(result) {
-    if(result == CURLE_BAD_CONTENT_ENCODING) {
-      /* Send the cancellation */
-      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
-
-      if(!result)
-        state(conn, IMAP_AUTHENTICATE_CANCEL);
-    }
-  }
-  else {
-    /* Send the response */
-    result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
-
-    if(!result)
-      state(conn, IMAP_AUTHENTICATE_DIGESTMD5_RESP);
-  }
-
-  Curl_safefree(rplyb64);
-
-  return result;
-}
-
-/* For AUTHENTICATE DIGEST-MD5 challenge-response responses */
-static CURLcode imap_state_auth_digest_resp_resp(struct connectdata *conn,
-                                                 int imapcode,
-                                                 imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Authentication failed: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Send an empty response */
-    result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "");
-
-    if(!result)
-      state(conn, IMAP_AUTHENTICATE_FINAL);
-  }
-
-  return result;
-}
-#endif
-
-#ifdef USE_NTLM
-/* For AUTHENTICATE NTLM (without initial response) responses */
-static CURLcode imap_state_auth_ntlm_resp(struct connectdata *conn,
-                                          int imapcode,
-                                          imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *type1msg = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the type-1 message */
-    result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
-                                                 &conn->ntlm,
-                                                 &type1msg, &len);
-    if(!result && type1msg) {
-      /* Send the message */
-      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type1msg);
-
-      if(!result)
-        state(conn, IMAP_AUTHENTICATE_NTLM_TYPE2MSG);
-    }
-  }
-
-  Curl_safefree(type1msg);
-
-  return result;
-}
-
-/* For NTLM type-2 responses (sent in reponse to our type-1 message) */
-static CURLcode imap_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
-                                                   int imapcode,
-                                                   imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *type2msg = NULL;
-  char *type3msg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Get the challenge message */
-    imap_get_message(data->state.buffer, &type2msg);
-
-    /* Decode the type-2 message */
-    result = Curl_sasl_decode_ntlm_type2_message(data, type2msg, &conn->ntlm);
-    if(result) {
-      /* Send the cancellation */
-      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
-
-      if(!result)
-        state(conn, IMAP_AUTHENTICATE_CANCEL);
-    }
-    else {
-      /* Create the type-3 message */
-      result = Curl_sasl_create_ntlm_type3_message(data, conn->user,
-                                                   conn->passwd, &conn->ntlm,
-                                                   &type3msg, &len);
-      if(!result && type3msg) {
-        /* Send the message */
-        result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type3msg);
-
-        if(!result)
-          state(conn, IMAP_AUTHENTICATE_FINAL);
-      }
-    }
-  }
-
-  Curl_safefree(type3msg);
-
-  return result;
-}
-#endif
-
-#if defined(USE_WINDOWS_SSPI)
-/* For AUTHENTICATE GSSAPI (without initial response) responses */
-static CURLcode imap_state_auth_gssapi_resp(struct connectdata *conn,
-                                            int imapcode,
-                                            imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct imap_conn *imapc = &conn->proto.imapc;
-  size_t len = 0;
-  char *respmsg = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the initial response message */
-    result = Curl_sasl_create_gssapi_user_message(data, conn->user,
-                                                  conn->passwd, "imap",
-                                                  imapc->mutual_auth,
-                                                  NULL, &conn->krb5,
-                                                  &respmsg, &len);
-    if(!result && respmsg) {
-      /* Send the message */
-      result = Curl_pp_sendf(&imapc->pp, "%s", respmsg);
-
-      if(!result)
-        state(conn, IMAP_AUTHENTICATE_GSSAPI_TOKEN);
-    }
-  }
-
-  Curl_safefree(respmsg);
-
-  return result;
-}
-
-/* For AUTHENTICATE GSSAPI user token responses */
-static CURLcode imap_state_auth_gssapi_token_resp(struct connectdata *conn,
-                                                  int imapcode,
-                                                  imapstate instate)
+/* For SASL authentication responses */
+static CURLcode imap_state_auth_resp(struct connectdata *conn,
+                                     int imapcode,
+                                     imapstate instate)
 {
   CURLcode result = CURLE_OK;
   struct SessionHandle *data = conn->data;
   struct imap_conn *imapc = &conn->proto.imapc;
-  char *chlgmsg = NULL;
-  char *respmsg = NULL;
-  size_t len = 0;
+  saslprogress progress;
 
   (void)instate; /* no use for this yet */
 
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Get the challenge message */
-    imap_get_message(data->state.buffer, &chlgmsg);
-
-    if(imapc->mutual_auth)
-      /* Decode the user token challenge and create the optional response
-         message */
-      result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
-                                                    imapc->mutual_auth,
-                                                    chlgmsg, &conn->krb5,
-                                                    &respmsg, &len);
-    else
-      /* Decode the security challenge and create the response message */
-      result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
-                                                        &conn->krb5,
-                                                        &respmsg, &len);
-
-    if(result) {
-      if(result == CURLE_BAD_CONTENT_ENCODING) {
-        /* Send the cancellation */
-        result = Curl_pp_sendf(&imapc->pp, "%s", "*");
-
-        if(!result)
-          state(conn, IMAP_AUTHENTICATE_CANCEL);
-      }
-    }
-    else {
-      /* Send the response */
-      if(respmsg)
-        result = Curl_pp_sendf(&imapc->pp, "%s", respmsg);
-      else
-        result = Curl_pp_sendf(&imapc->pp, "%s", "");
-
-      if(!result)
-        state(conn, (imapc->mutual_auth ? IMAP_AUTHENTICATE_GSSAPI_NO_DATA :
-                                          IMAP_AUTHENTICATE_FINAL));
-    }
-  }
-
-  Curl_safefree(respmsg);
-
-  return result;
-}
-
-/* For AUTHENTICATE GSSAPI no data responses */
-static CURLcode imap_state_auth_gssapi_no_data_resp(struct connectdata *conn,
-                                                    int imapcode,
-                                                    imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *chlgmsg = NULL;
-  char *respmsg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Get the challenge message */
-    imap_get_message(data->state.buffer, &chlgmsg);
-
-    /* Decode the security challenge and create the response message */
-    result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
-                                                      &conn->krb5,
-                                                      &respmsg, &len);
-    if(result) {
-      if(result == CURLE_BAD_CONTENT_ENCODING) {
-        /* Send the cancellation */
-        result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
-
-        if(!result)
-          state(conn, IMAP_AUTHENTICATE_CANCEL);
-      }
-    }
-    else {
-      /* Send the response */
-      if(respmsg) {
-        result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", respmsg);
-
-        if(!result)
-          state(conn, IMAP_AUTHENTICATE_FINAL);
+  result = Curl_sasl_continue(&imapc->sasl, conn, imapcode, &progress);
+  if(!result)
+    switch(progress) {
+    case SASL_DONE:
+      state(conn, IMAP_STOP);  /* Authenticated */
+      break;
+    case SASL_IDLE:            /* No mechanism left after cancellation */
+      if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
+        /* Perform clear text authentication */
+        result = imap_perform_login(conn);
+      else {
+        failf(data, "Authentication cancelled");
+        result = CURLE_LOGIN_DENIED;
       }
+      break;
+    default:
+      break;
     }
-  }
-
-  Curl_safefree(respmsg);
-
-  return result;
-}
-#endif
-
-/* For AUTHENTICATE XOAUTH2 (without initial response) responses */
-static CURLcode imap_state_auth_xoauth2_resp(struct connectdata *conn,
-                                             int imapcode,
-                                             imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *xoauth = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != '+') {
-    failf(data, "Access denied: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the authorisation message */
-    result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
-                                              conn->xoauth2_bearer,
-                                              &xoauth, &len);
-    if(!result && xoauth) {
-      /* Send the message */
-      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", xoauth);
-
-      if(!result)
-        state(conn, IMAP_AUTHENTICATE_FINAL);
-    }
-  }
-
-  Curl_safefree(xoauth);
-
-  return result;
-}
-
-/* For AUTHENTICATE cancellation responses */
-static CURLcode imap_state_auth_cancel_resp(struct connectdata *conn,
-                                            int imapcode,
-                                            imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct imap_conn *imapc = &conn->proto.imapc;
-  const char *mech = NULL;
-  char *initresp = NULL;
-  size_t len = 0;
-  imapstate state1 = IMAP_STOP;
-  imapstate state2 = IMAP_STOP;
-
-  (void)imapcode;
-  (void)instate; /* no use for this yet */
-
-  /* Remove the offending mechanism from the supported list */
-  imapc->authmechs ^= imapc->authused;
-
-  /* Calculate alternative SASL login details */
-  result = imap_calc_sasl_details(conn, &mech, &initresp, &len, &state1,
-                                  &state2);
-
-  if(!result) {
-    /* Do we have any mechanisms left or can we fallback to clear text? */
-    if(mech) {
-      /* Retry SASL based authentication */
-      result = imap_perform_authenticate(conn, mech, initresp, state1, state2);
-
-      Curl_safefree(initresp);
-    }
-    else if((!imapc->login_disabled) &&
-            (imapc->preftype & IMAP_TYPE_CLEARTEXT))
-      /* Perform clear text authentication */
-      result = imap_perform_login(conn);
-    else {
-      failf(data, "Authentication cancelled");
-
-      result = CURLE_LOGIN_DENIED;
-    }
-  }
-
-  return result;
-}
-
-/* For final responses in the AUTHENTICATE sequence */
-static CURLcode imap_state_auth_final_resp(struct connectdata *conn,
-                                           int imapcode,
-                                           imapstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-
-  (void)instate; /* no use for this yet */
-
-  if(imapcode != 'O') {
-    failf(data, "Authentication failed: %d", imapcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else
-    /* End of connect phase */
-    state(conn, IMAP_STOP);
 
   return result;
 }
@@ -1873,69 +1314,8 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
       result = imap_state_starttls_resp(conn, imapcode, imapc->state);
       break;
 
-    case IMAP_AUTHENTICATE_PLAIN:
-      result = imap_state_auth_plain_resp(conn, imapcode, imapc->state);
-      break;
-
-    case IMAP_AUTHENTICATE_LOGIN:
-      result = imap_state_auth_login_resp(conn, imapcode, imapc->state);
-      break;
-
-    case IMAP_AUTHENTICATE_LOGIN_PASSWD:
-      result = imap_state_auth_login_password_resp(conn, imapcode,
-                                                   imapc->state);
-      break;
-
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-    case IMAP_AUTHENTICATE_CRAMMD5:
-      result = imap_state_auth_cram_resp(conn, imapcode, imapc->state);
-      break;
-
-    case IMAP_AUTHENTICATE_DIGESTMD5:
-      result = imap_state_auth_digest_resp(conn, imapcode, imapc->state);
-      break;
-
-    case IMAP_AUTHENTICATE_DIGESTMD5_RESP:
-      result = imap_state_auth_digest_resp_resp(conn, imapcode, imapc->state);
-      break;
-#endif
-
-#ifdef USE_NTLM
-    case IMAP_AUTHENTICATE_NTLM:
-      result = imap_state_auth_ntlm_resp(conn, imapcode, imapc->state);
-      break;
-
-    case IMAP_AUTHENTICATE_NTLM_TYPE2MSG:
-      result = imap_state_auth_ntlm_type2msg_resp(conn, imapcode,
-                                                  imapc->state);
-      break;
-#endif
-
-#if defined(USE_WINDOWS_SSPI)
-    case IMAP_AUTHENTICATE_GSSAPI:
-      result = imap_state_auth_gssapi_resp(conn, imapcode, imapc->state);
-      break;
-
-    case IMAP_AUTHENTICATE_GSSAPI_TOKEN:
-      result = imap_state_auth_gssapi_token_resp(conn, imapcode, imapc->state);
-      break;
-
-    case IMAP_AUTHENTICATE_GSSAPI_NO_DATA:
-      result = imap_state_auth_gssapi_no_data_resp(conn, imapcode,
-                                                   imapc->state);
-      break;
-#endif
-
-    case IMAP_AUTHENTICATE_XOAUTH2:
-      result = imap_state_auth_xoauth2_resp(conn, imapcode, imapc->state);
-      break;
-
-    case IMAP_AUTHENTICATE_CANCEL:
-      result = imap_state_auth_cancel_resp(conn, imapcode, imapc->state);
-      break;
-
-    case IMAP_AUTHENTICATE_FINAL:
-      result = imap_state_auth_final_resp(conn, imapcode, imapc->state);
+    case IMAP_AUTHENTICATE:
+      result = imap_state_auth_resp(conn, imapcode, imapc->state);
       break;
 
     case IMAP_LOGIN:
@@ -2062,7 +1442,7 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
 
   /* Set the default preferred authentication type and mechanism */
   imapc->preftype = IMAP_TYPE_ANY;
-  imapc->prefmech = SASL_AUTH_ANY;
+  Curl_sasl_init(&imapc->sasl, &saslimap);
 
   /* Initialise the pingpong layer */
   Curl_pp_init(pp);
@@ -2275,7 +1655,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
   Curl_pp_disconnect(&imapc->pp);
 
   /* Cleanup the SASL module */
-  Curl_sasl_cleanup(conn, imapc->authused);
+  Curl_sasl_cleanup(conn, imapc->sasl.authused);
 
   /* Cleanup our connection based variables */
   Curl_safefree(imapc->mailbox);
@@ -2420,7 +1800,7 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
   result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
   va_end(ap);
 
-  Curl_safefree(taggedfmt);
+  free(taggedfmt);
 
   return result;
 }
@@ -2448,7 +1828,7 @@ static char *imap_atom(const char *str)
   if(!str)
     return NULL;
 
-  /* Count any unescapped characters */
+  /* Count any unescaped characters */
   p1 = str;
   while(*p1) {
     if(*p1 == '\\')
@@ -2461,7 +1841,7 @@ static char *imap_atom(const char *str)
     p1++;
   }
 
-  /* Does the input contain any unescapped characters? */
+  /* Does the input contain any unescaped characters? */
   if(!backsp_count && !quote_count && !space_exists)
     return strdup(str);
 
@@ -2549,69 +1929,42 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct imap_conn *imapc = &conn->proto.imapc;
-  const char *options = conn->options;
-  const char *ptr = options;
-  bool reset = TRUE;
+  const char *ptr = conn->options;
+
+  imapc->sasl.resetprefs = TRUE;
 
-  while(ptr && *ptr) {
+  while(!result && ptr && *ptr) {
     const char *key = ptr;
+    const char *value;
 
     while(*ptr && *ptr != '=')
         ptr++;
 
-    if(strnequal(key, "AUTH", 4)) {
-      size_t len = 0;
-      const char *value = ++ptr;
+    value = ptr + 1;
 
-      if(reset) {
-        reset = FALSE;
-        imapc->preftype = IMAP_TYPE_NONE;
-        imapc->prefmech = SASL_AUTH_NONE;
-      }
-
-      while(*ptr && *ptr != ';') {
-        ptr++;
-        len++;
-      }
-
-      if(strnequal(value, "*", len)) {
-        imapc->preftype = IMAP_TYPE_ANY;
-        imapc->prefmech = SASL_AUTH_ANY;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_LOGIN, len)) {
-        imapc->preftype = IMAP_TYPE_SASL;
-        imapc->prefmech |= SASL_MECH_LOGIN;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_PLAIN, len)) {
-        imapc->preftype = IMAP_TYPE_SASL;
-        imapc->prefmech |= SASL_MECH_PLAIN;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_CRAM_MD5, len)) {
-        imapc->preftype = IMAP_TYPE_SASL;
-        imapc->prefmech |= SASL_MECH_CRAM_MD5;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_DIGEST_MD5, len)) {
-        imapc->preftype = IMAP_TYPE_SASL;
-        imapc->prefmech |= SASL_MECH_DIGEST_MD5;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_GSSAPI, len)) {
-        imapc->preftype = IMAP_TYPE_SASL;
-        imapc->prefmech |= SASL_MECH_GSSAPI;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_NTLM, len)) {
-        imapc->preftype = IMAP_TYPE_SASL;
-        imapc->prefmech |= SASL_MECH_NTLM;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_XOAUTH2, len)) {
-        imapc->preftype = IMAP_TYPE_SASL;
-        imapc->prefmech |= SASL_MECH_XOAUTH2;
-      }
+    while(*ptr && *ptr != ';')
+      ptr++;
 
-      if(*ptr == ';')
-        ptr++;
-    }
+    if(strnequal(key, "AUTH=", 5))
+      result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
+                                               value, ptr - value);
     else
       result = CURLE_URL_MALFORMAT;
+
+    if(*ptr == ';')
+      ptr++;
+  }
+
+  switch(imapc->sasl.prefmech) {
+  case SASL_AUTH_NONE:
+    imapc->preftype = IMAP_TYPE_NONE;
+    break;
+  case SASL_AUTH_DEFAULT:
+    imapc->preftype = IMAP_TYPE_ANY;
+    break;
+  default:
+    imapc->preftype = IMAP_TYPE_SASL;
+    break;
   }
 
   return result;
@@ -2678,7 +2031,7 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
     /* Decode the value parameter */
     result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen, TRUE);
     if(result) {
-      Curl_safefree(name);
+      free(name);
       return result;
     }
 
@@ -2717,14 +2070,14 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
       value = NULL;
     }
     else {
-      Curl_safefree(name);
-      Curl_safefree(value);
+      free(name);
+      free(value);
 
       return CURLE_URL_MALFORMAT;
     }
 
-    Curl_safefree(name);
-    Curl_safefree(value);
+    free(name);
+    free(value);
   }
 
   /* Does the URL contain a query parameter? Only valid when we have a mailbox
@@ -2786,108 +2139,4 @@ static CURLcode imap_parse_custom_request(struct connectdata *conn)
   return result;
 }
 
-/***********************************************************************
- *
- * imap_calc_sasl_details()
- *
- * Calculate the required login details for SASL authentication.
- */
-static CURLcode imap_calc_sasl_details(struct connectdata *conn,
-                                       const char **mech,
-                                       char **initresp, size_t *len,
-                                       imapstate *state1, imapstate *state2)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct imap_conn *imapc = &conn->proto.imapc;
-
-  /* Calculate the supported authentication mechanism, by decreasing order of
-     security, as well as the initial response where appropriate */
-#if defined(USE_WINDOWS_SSPI)
-    if((imapc->authmechs & SASL_MECH_GSSAPI) &&
-       (imapc->prefmech & SASL_MECH_GSSAPI)) {
-    imapc->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
-
-    *mech = SASL_MECH_STRING_GSSAPI;
-    *state1 = IMAP_AUTHENTICATE_GSSAPI;
-    *state2 = IMAP_AUTHENTICATE_GSSAPI_TOKEN;
-    imapc->authused = SASL_MECH_GSSAPI;
-
-    if(imapc->ir_supported || data->set.sasl_ir)
-      result = Curl_sasl_create_gssapi_user_message(data, conn->user,
-                                                    conn->passwd, "imap",
-                                                    imapc->mutual_auth,
-                                                    NULL, &conn->krb5,
-                                                    initresp, len);
-  }
-  else
-#endif
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-  if((imapc->authmechs & SASL_MECH_DIGEST_MD5) &&
-     (imapc->prefmech & SASL_MECH_DIGEST_MD5)) {
-    *mech = SASL_MECH_STRING_DIGEST_MD5;
-    *state1 = IMAP_AUTHENTICATE_DIGESTMD5;
-    imapc->authused = SASL_MECH_DIGEST_MD5;
-  }
-  else if((imapc->authmechs & SASL_MECH_CRAM_MD5) &&
-          (imapc->prefmech & SASL_MECH_CRAM_MD5)) {
-    *mech = SASL_MECH_STRING_CRAM_MD5;
-    *state1 = IMAP_AUTHENTICATE_CRAMMD5;
-    imapc->authused = SASL_MECH_CRAM_MD5;
-  }
-  else
-#endif
-#ifdef USE_NTLM
-    if((imapc->authmechs & SASL_MECH_NTLM) &&
-       (imapc->prefmech & SASL_MECH_NTLM)) {
-    *mech = SASL_MECH_STRING_NTLM;
-    *state1 = IMAP_AUTHENTICATE_NTLM;
-    *state2 = IMAP_AUTHENTICATE_NTLM_TYPE2MSG;
-    imapc->authused = SASL_MECH_NTLM;
-
-    if(imapc->ir_supported || data->set.sasl_ir)
-      result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
-                                                   &conn->ntlm,
-                                                   initresp, len);
-  }
-  else
-#endif
-  if(((imapc->authmechs & SASL_MECH_XOAUTH2) &&
-      (imapc->prefmech & SASL_MECH_XOAUTH2) &&
-      (imapc->prefmech != SASL_AUTH_ANY)) || conn->xoauth2_bearer) {
-    *mech = SASL_MECH_STRING_XOAUTH2;
-    *state1 = IMAP_AUTHENTICATE_XOAUTH2;
-    *state2 = IMAP_AUTHENTICATE_FINAL;
-    imapc->authused = SASL_MECH_XOAUTH2;
-
-    if(imapc->ir_supported || data->set.sasl_ir)
-      result = Curl_sasl_create_xoauth2_message(data, conn->user,
-                                                conn->xoauth2_bearer,
-                                                initresp, len);
-  }
-  else if((imapc->authmechs & SASL_MECH_LOGIN) &&
-          (imapc->prefmech & SASL_MECH_LOGIN)) {
-    *mech = SASL_MECH_STRING_LOGIN;
-    *state1 = IMAP_AUTHENTICATE_LOGIN;
-    *state2 = IMAP_AUTHENTICATE_LOGIN_PASSWD;
-    imapc->authused = SASL_MECH_LOGIN;
-
-    if(imapc->ir_supported || data->set.sasl_ir)
-      result = Curl_sasl_create_login_message(data, conn->user, initresp, len);
-  }
-  else if((imapc->authmechs & SASL_MECH_PLAIN) &&
-          (imapc->prefmech & SASL_MECH_PLAIN)) {
-    *mech = SASL_MECH_STRING_PLAIN;
-    *state1 = IMAP_AUTHENTICATE_PLAIN;
-    *state2 = IMAP_AUTHENTICATE_FINAL;
-    imapc->authused = SASL_MECH_PLAIN;
-
-    if(imapc->ir_supported || data->set.sasl_ir)
-      result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
-                                              initresp, len);
-  }
-
-  return result;
-}
-
 #endif /* CURL_DISABLE_IMAP */
diff --git a/Utilities/cmcurl/lib/imap.h b/Utilities/cmcurl/lib/imap.h
index 768fc4b..3189daa 100644
--- a/Utilities/cmcurl/lib/imap.h
+++ b/Utilities/cmcurl/lib/imap.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,6 +23,7 @@
  ***************************************************************************/
 
 #include "pingpong.h"
+#include "curl_sasl.h"
 
 /****************************************************************************
  * IMAP unique setup
@@ -35,20 +36,7 @@ typedef enum {
   IMAP_STARTTLS,
   IMAP_UPGRADETLS,   /* asynchronously upgrade the connection to SSL/TLS
                        (multi mode only) */
-  IMAP_AUTHENTICATE_PLAIN,
-  IMAP_AUTHENTICATE_LOGIN,
-  IMAP_AUTHENTICATE_LOGIN_PASSWD,
-  IMAP_AUTHENTICATE_CRAMMD5,
-  IMAP_AUTHENTICATE_DIGESTMD5,
-  IMAP_AUTHENTICATE_DIGESTMD5_RESP,
-  IMAP_AUTHENTICATE_NTLM,
-  IMAP_AUTHENTICATE_NTLM_TYPE2MSG,
-  IMAP_AUTHENTICATE_GSSAPI,
-  IMAP_AUTHENTICATE_GSSAPI_TOKEN,
-  IMAP_AUTHENTICATE_GSSAPI_NO_DATA,
-  IMAP_AUTHENTICATE_XOAUTH2,
-  IMAP_AUTHENTICATE_CANCEL,
-  IMAP_AUTHENTICATE_FINAL,
+  IMAP_AUTHENTICATE,
   IMAP_LOGIN,
   IMAP_LIST,
   IMAP_SELECT,
@@ -83,16 +71,13 @@ struct imap_conn {
   struct pingpong pp;
   imapstate state;            /* Always use imap.c:state() to change state! */
   bool ssldone;               /* Is connect() over SSL done? */
-  unsigned int authmechs;     /* Accepted authentication mechanisms */
+  struct SASL sasl;           /* SASL-related parameters */
   unsigned int preftype;      /* Preferred authentication type */
-  unsigned int prefmech;      /* Preferred authentication mechanism */
-  unsigned int authused;      /* Auth mechanism used for the connection */
   int cmdid;                  /* Last used command ID */
   char resptag[5];            /* Response tag to wait for */
   bool tls_supported;         /* StartTLS capability supported by server */
   bool login_disabled;        /* LOGIN command disabled by server */
   bool ir_supported;          /* Initial response supported by server */
-  bool mutual_auth;           /* Mutual authentication enabled (GSSAPI only) */
   char *mailbox;              /* The last selected mailbox */
   char *mailbox_uidvalidity;  /* UIDVALIDITY parsed from select response */
 };
diff --git a/Utilities/cmcurl/lib/inet_ntop.c b/Utilities/cmcurl/lib/inet_ntop.c
index c327150..da9a3ab 100644
--- a/Utilities/cmcurl/lib/inet_ntop.c
+++ b/Utilities/cmcurl/lib/inet_ntop.c
@@ -32,8 +32,7 @@
 #include <arpa/inet.h>
 #endif
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #include "inet_ntop.h"
 
diff --git a/Utilities/cmcurl/lib/inet_ntop.h b/Utilities/cmcurl/lib/inet_ntop.h
index db28ed8..cc4bdbb 100644
--- a/Utilities/cmcurl/lib/inet_ntop.h
+++ b/Utilities/cmcurl/lib/inet_ntop.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,7 +31,7 @@ char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size);
 #include <arpa/inet.h>
 #endif
 #define Curl_inet_ntop(af,addr,buf,size) \
-        inet_ntop(af,addr,buf,(curl_socklen_t)size)
+        inet_ntop(af, addr, buf, (curl_socklen_t)size)
 #endif
 
 #endif /* HEADER_CURL_INET_NTOP_H */
diff --git a/Utilities/cmcurl/lib/krb5.c b/Utilities/cmcurl/lib/krb5.c
index 7e82a68..ad7dd67 100644
--- a/Utilities/cmcurl/lib/krb5.c
+++ b/Utilities/cmcurl/lib/krb5.c
@@ -1,8 +1,8 @@
 /* GSSAPI/krb5 support for FTP - loosely based on old krb4.c
  *
- * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2013 Kungliga Tekniska H�gskolan
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska H�gskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
- * Copyright (c) 2004 - 2012 Daniel Stenberg
+ * Copyright (c) 2004 - 2015 Daniel Stenberg
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,13 +34,7 @@
 
 #include "curl_setup.h"
 
-#ifndef CURL_DISABLE_FTP
-#ifdef HAVE_GSSAPI
-
-#ifdef HAVE_OLD_GSSMIT
-#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
-#define NCOMPAT 1
-#endif
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_FTP)
 
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
@@ -52,13 +46,11 @@
 #include "curl_gssapi.h"
 #include "sendf.h"
 #include "curl_sec.h"
-#include "curl_memory.h"
 #include "warnless.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #define LOCAL_ADDR (&conn->local_addr)
@@ -121,8 +113,7 @@ krb5_overhead(void *app_data, int level, int len)
 }
 
 static int
-krb5_encode(void *app_data, const void *from, int length, int level, void **to,
-            struct connectdata *conn UNUSED_PARAM)
+krb5_encode(void *app_data, const void *from, int length, int level, void **to)
 {
   gss_ctx_id_t *context = app_data;
   gss_buffer_desc dec, enc;
@@ -130,9 +121,6 @@ krb5_encode(void *app_data, const void *from, int length, int level, void **to,
   int state;
   int len;
 
-  /* shut gcc up */
-  conn = NULL;
-
   /* NOTE that the cast is safe, neither of the krb5, gnu gss and heimdal
    * libraries modify the input buffer in gss_seal()
    */
@@ -240,6 +228,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
                                       &chan,
                                       gssresp,
                                       &output_buffer,
+                                      TRUE,
                                       NULL);
 
       if(gssresp) {
@@ -257,7 +246,8 @@ krb5_auth(void *app_data, struct connectdata *conn)
         result = Curl_base64_encode(data, (char *)output_buffer.value,
                                     output_buffer.length, &p, &base64_sz);
         if(result) {
-          Curl_infof(data,"base64-encoding: %s\n", curl_easy_strerror(result));
+          Curl_infof(data, "base64-encoding: %s\n",
+                     curl_easy_strerror(result));
           ret = AUTH_CONTINUE;
           break;
         }
@@ -289,7 +279,8 @@ krb5_auth(void *app_data, struct connectdata *conn)
                                       (unsigned char **)&_gssresp.value,
                                       &_gssresp.length);
           if(result) {
-            Curl_failf(data,"base64-decoding: %s", curl_easy_strerror(result));
+            Curl_failf(data, "base64-decoding: %s",
+                       curl_easy_strerror(result));
             ret = AUTH_CONTINUE;
             break;
           }
@@ -338,5 +329,4 @@ struct Curl_sec_client_mech Curl_krb5_client_mech = {
     krb5_decode
 };
 
-#endif /* HAVE_GSSAPI */
-#endif /* CURL_DISABLE_FTP */
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_FTP */
diff --git a/Utilities/cmcurl/lib/ldap.c b/Utilities/cmcurl/lib/ldap.c
index ae48448..4d91282 100644
--- a/Utilities/cmcurl/lib/ldap.c
+++ b/Utilities/cmcurl/lib/ldap.c
@@ -5,7 +5,7 @@
  *                | (__| |_| |  _ <| |___
  *                 \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,7 +35,7 @@
  * OpenLDAP library versions, USE_OPENLDAP shall not be defined.
  */
 
-#ifdef CURL_LDAP_WIN            /* Use Windows LDAP implementation. */
+#ifdef USE_WIN32_LDAP           /* Use Windows LDAP implementation. */
 # include <winldap.h>
 # ifndef LDAP_VENDOR_NAME
 #  error Your Platform SDK is NOT sufficient for LDAP support! \
@@ -54,6 +54,15 @@
 # endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */
 #endif
 
+/* These are macros in both <wincrypt.h> (in above <winldap.h>) and typedefs
+ * in BoringSSL's <openssl/x509.h>
+ */
+#ifdef HAVE_BORINGSSL
+# undef X509_NAME
+# undef X509_CERT_PAIR
+# undef X509_EXTENSIONS
+#endif
+
 #include "urldata.h"
 #include <curl/curl.h>
 #include "sendf.h"
@@ -63,14 +72,14 @@
 #include "strequal.h"
 #include "strtok.h"
 #include "curl_ldap.h"
-#include "curl_memory.h"
+#include "curl_multibyte.h"
 #include "curl_base64.h"
 #include "rawstr.h"
 #include "connect.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #ifndef HAVE_LDAP_URL_PARSE
@@ -80,10 +89,19 @@
 typedef struct {
   char   *lud_host;
   int     lud_port;
+#if defined(USE_WIN32_LDAP)
+  TCHAR  *lud_dn;
+  TCHAR **lud_attrs;
+#else
   char   *lud_dn;
   char  **lud_attrs;
+#endif
   int     lud_scope;
+#if defined(USE_WIN32_LDAP)
+  TCHAR  *lud_filter;
+#else
   char   *lud_filter;
+#endif
   char  **lud_exts;
   size_t    lud_attrs_dups; /* how many were dup'ed, this field is not in the
                                "real" struct so can only be used in code
@@ -168,11 +186,11 @@ const struct Curl_handler Curl_handler_ldaps = {
 
 static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
 {
-  CURLcode status = CURLE_OK;
+  CURLcode result = CURLE_OK;
   int rc = 0;
   LDAP *server = NULL;
   LDAPURLDesc *ludp = NULL;
-  LDAPMessage *result = NULL;
+  LDAPMessage *ldapmsg = NULL;
   LDAPMessage *entryIterator;
   int num = 0;
   struct SessionHandle *data=conn->data;
@@ -182,7 +200,16 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
   size_t val_b64_sz = 0;
   curl_off_t dlsize = 0;
 #ifdef LDAP_OPT_NETWORK_TIMEOUT
-  struct timeval ldap_timeout = {10,0}; /* 10 sec connection/search timeout */
+  struct timeval ldap_timeout = {10, 0}; /* 10 sec connection/search timeout */
+#endif
+#if defined(USE_WIN32_LDAP)
+  TCHAR *host = NULL;
+  TCHAR *user = NULL;
+  TCHAR *passwd = NULL;
+#else
+  char *host = NULL;
+  char *user = NULL;
+  char *passwd = NULL;
 #endif
 
   *done = TRUE; /* unconditionally */
@@ -197,7 +224,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
 #endif
   if(rc != 0) {
     failf(data, "LDAP local: %s", ldap_err2string(rc));
-    status = CURLE_LDAP_INVALID_URL;
+    result = CURLE_LDAP_INVALID_URL;
     goto quit;
   }
 
@@ -207,6 +234,32 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
   infof(data, "LDAP local: trying to establish %s connection\n",
           ldap_ssl ? "encrypted" : "cleartext");
 
+#if defined(USE_WIN32_LDAP)
+  host = Curl_convert_UTF8_to_tchar(conn->host.name);
+  if(!host) {
+    result = CURLE_OUT_OF_MEMORY;
+
+    goto quit;
+  }
+
+  if(conn->bits.user_passwd) {
+    user = Curl_convert_UTF8_to_tchar(conn->user);
+    passwd = Curl_convert_UTF8_to_tchar(conn->passwd);
+    if(!user || !passwd) {
+      result = CURLE_OUT_OF_MEMORY;
+
+      goto quit;
+    }
+  }
+#else
+  host = conn->host.name;
+
+  if(conn->bits.user_passwd) {
+    user = conn->user;
+    passwd = conn->passwd;
+  }
+#endif
+
 #ifdef LDAP_OPT_NETWORK_TIMEOUT
   ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout);
 #endif
@@ -214,9 +267,9 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
 
   if(ldap_ssl) {
 #ifdef HAVE_LDAP_SSL
-#ifdef CURL_LDAP_WIN
+#ifdef USE_WIN32_LDAP
     /* Win32 LDAP SDK doesn't support insecure mode without CA! */
-    server = ldap_sslinit(conn->host.name, (int)conn->port, 1);
+    server = ldap_sslinit(host, (int)conn->port, 1);
     ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
 #else
     int ldap_option;
@@ -225,7 +278,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
     rc = ldapssl_client_init(NULL, NULL);
     if(rc != LDAP_SUCCESS) {
       failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc));
-      status = CURLE_SSL_CERTPROBLEM;
+      result = CURLE_SSL_CERTPROBLEM;
       goto quit;
     }
     if(data->set.ssl.verifypeer) {
@@ -237,7 +290,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
       if(!ldap_ca) {
         failf(data, "LDAP local: ERROR %s CA cert not set!",
               (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"));
-        status = CURLE_SSL_CERTPROBLEM;
+        result = CURLE_SSL_CERTPROBLEM;
         goto quit;
       }
       infof(data, "LDAP local: using %s CA cert '%s'\n",
@@ -248,7 +301,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
         failf(data, "LDAP local: ERROR setting %s CA cert: %s",
                 (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
                 ldap_err2string(rc));
-        status = CURLE_SSL_CERTPROBLEM;
+        result = CURLE_SSL_CERTPROBLEM;
         goto quit;
       }
       ldap_option = LDAPSSL_VERIFY_SERVER;
@@ -259,14 +312,14 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
     if(rc != LDAP_SUCCESS) {
       failf(data, "LDAP local: ERROR setting cert verify mode: %s",
               ldap_err2string(rc));
-      status = CURLE_SSL_CERTPROBLEM;
+      result = CURLE_SSL_CERTPROBLEM;
       goto quit;
     }
-    server = ldapssl_init(conn->host.name, (int)conn->port, 1);
+    server = ldapssl_init(host, (int)conn->port, 1);
     if(server == NULL) {
       failf(data, "LDAP local: Cannot connect to %s:%ld",
-              conn->host.name, conn->port);
-      status = CURLE_COULDNT_CONNECT;
+            conn->host.dispname, conn->port);
+      result = CURLE_COULDNT_CONNECT;
       goto quit;
     }
 #elif defined(LDAP_OPT_X_TLS)
@@ -275,12 +328,12 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
       if((data->set.str[STRING_CERT_TYPE]) &&
          (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
         failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
-        status = CURLE_SSL_CERTPROBLEM;
+        result = CURLE_SSL_CERTPROBLEM;
         goto quit;
       }
       if(!ldap_ca) {
         failf(data, "LDAP local: ERROR PEM CA cert not set!");
-        status = CURLE_SSL_CERTPROBLEM;
+        result = CURLE_SSL_CERTPROBLEM;
         goto quit;
       }
       infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca);
@@ -288,7 +341,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
       if(rc != LDAP_SUCCESS) {
         failf(data, "LDAP local: ERROR setting PEM CA cert: %s",
                 ldap_err2string(rc));
-        status = CURLE_SSL_CERTPROBLEM;
+        result = CURLE_SSL_CERTPROBLEM;
         goto quit;
       }
       ldap_option = LDAP_OPT_X_TLS_DEMAND;
@@ -300,14 +353,14 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
     if(rc != LDAP_SUCCESS) {
       failf(data, "LDAP local: ERROR setting cert verify mode: %s",
               ldap_err2string(rc));
-      status = CURLE_SSL_CERTPROBLEM;
+      result = CURLE_SSL_CERTPROBLEM;
       goto quit;
     }
-    server = ldap_init(conn->host.name, (int)conn->port);
+    server = ldap_init(host, (int)conn->port);
     if(server == NULL) {
       failf(data, "LDAP local: Cannot connect to %s:%ld",
-              conn->host.name, conn->port);
-      status = CURLE_COULDNT_CONNECT;
+            conn->host.dispname, conn->port);
+      result = CURLE_COULDNT_CONNECT;
       goto quit;
     }
     ldap_option = LDAP_OPT_X_TLS_HARD;
@@ -315,7 +368,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
     if(rc != LDAP_SUCCESS) {
       failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s",
               ldap_err2string(rc));
-      status = CURLE_SSL_CERTPROBLEM;
+      result = CURLE_SSL_CERTPROBLEM;
       goto quit;
     }
 /*
@@ -323,7 +376,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
     if(rc != LDAP_SUCCESS) {
       failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s",
               ldap_err2string(rc));
-      status = CURLE_SSL_CERTPROBLEM;
+      result = CURLE_SSL_CERTPROBLEM;
       goto quit;
     }
 */
@@ -332,126 +385,278 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
        should check in first place if we can support LDAP SSL/TLS */
     failf(data, "LDAP local: SSL/TLS not supported with this version "
             "of the OpenLDAP toolkit\n");
-    status = CURLE_SSL_CERTPROBLEM;
+    result = CURLE_SSL_CERTPROBLEM;
     goto quit;
 #endif
 #endif
 #endif /* CURL_LDAP_USE_SSL */
   }
   else {
-    server = ldap_init(conn->host.name, (int)conn->port);
+    server = ldap_init(host, (int)conn->port);
     if(server == NULL) {
       failf(data, "LDAP local: Cannot connect to %s:%ld",
-              conn->host.name, conn->port);
-      status = CURLE_COULDNT_CONNECT;
+            conn->host.dispname, conn->port);
+      result = CURLE_COULDNT_CONNECT;
       goto quit;
     }
   }
-#ifdef CURL_LDAP_WIN
+#ifdef USE_WIN32_LDAP
   ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
 #endif
 
-  rc = ldap_simple_bind_s(server,
-                          conn->bits.user_passwd ? conn->user : NULL,
-                          conn->bits.user_passwd ? conn->passwd : NULL);
+  rc = ldap_simple_bind_s(server, user, passwd);
   if(!ldap_ssl && rc != 0) {
     ldap_proto = LDAP_VERSION2;
     ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
-    rc = ldap_simple_bind_s(server,
-                            conn->bits.user_passwd ? conn->user : NULL,
-                            conn->bits.user_passwd ? conn->passwd : NULL);
+    rc = ldap_simple_bind_s(server, user, passwd);
   }
   if(rc != 0) {
     failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
-    status = CURLE_LDAP_CANNOT_BIND;
+    result = CURLE_LDAP_CANNOT_BIND;
     goto quit;
   }
 
   rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
-                     ludp->lud_filter, ludp->lud_attrs, 0, &result);
+                     ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg);
 
   if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
     failf(data, "LDAP remote: %s", ldap_err2string(rc));
-    status = CURLE_LDAP_SEARCH_FAILED;
+    result = CURLE_LDAP_SEARCH_FAILED;
     goto quit;
   }
 
-  for(num = 0, entryIterator = ldap_first_entry(server, result);
+  for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg);
       entryIterator;
       entryIterator = ldap_next_entry(server, entryIterator), num++) {
     BerElement *ber = NULL;
+#if defined(USE_WIN32_LDAP)
+    TCHAR *attribute;
+#else
     char  *attribute;       /*! suspicious that this isn't 'const' */
-    char  *dn = ldap_get_dn(server, entryIterator);
+#endif
     int i;
 
-    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
-    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)dn, 0);
-    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+    /* Get the DN and write it to the client */
+    {
+      char *name;
+      size_t name_len;
+#if defined(USE_WIN32_LDAP)
+      TCHAR *dn = ldap_get_dn(server, entryIterator);
+      name = Curl_convert_tchar_to_UTF8(dn);
+      if(!name) {
+        ldap_memfree(dn);
+
+        result = CURLE_OUT_OF_MEMORY;
+
+        goto quit;
+      }
+#else
+      char *dn = name = ldap_get_dn(server, entryIterator);
+#endif
+      name_len = strlen(name);
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+      if(result) {
+#if defined(USE_WIN32_LDAP)
+        Curl_unicodefree(name);
+#endif
+        ldap_memfree(dn);
+
+        goto quit;
+      }
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name,
+                                 name_len);
+      if(result) {
+#if defined(USE_WIN32_LDAP)
+        Curl_unicodefree(name);
+#endif
+        ldap_memfree(dn);
+
+        goto quit;
+      }
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+      if(result) {
+#if defined(USE_WIN32_LDAP)
+        Curl_unicodefree(name);
+#endif
+        ldap_memfree(dn);
+
+        goto quit;
+      }
 
-    dlsize += strlen(dn)+5;
+      dlsize += name_len + 5;
 
+#if defined(USE_WIN32_LDAP)
+      Curl_unicodefree(name);
+#endif
+      ldap_memfree(dn);
+    }
+
+    /* Get the attributes and write them to the client */
     for(attribute = ldap_first_attribute(server, entryIterator, &ber);
         attribute;
         attribute = ldap_next_attribute(server, entryIterator, ber)) {
-      BerValue **vals = ldap_get_values_len(server, entryIterator, attribute);
+      BerValue **vals;
+      size_t attr_len;
+#if defined(USE_WIN32_LDAP)
+      char *attr = Curl_convert_tchar_to_UTF8(attribute);
+      if(!attr) {
+        if(ber)
+          ber_free(ber, 0);
+
+        result = CURLE_OUT_OF_MEMORY;
+
+        goto quit;
+    }
+#else
+      char *attr = attribute;
+#endif
+      attr_len = strlen(attr);
 
+      vals = ldap_get_values_len(server, entryIterator, attribute);
       if(vals != NULL) {
         for(i = 0; (vals[i] != NULL); i++) {
-          Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
-          Curl_client_write(conn, CLIENTWRITE_BODY, (char *) attribute, 0);
-          Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
-          dlsize += strlen(attribute)+3;
-
-          if((strlen(attribute) > 7) &&
-              (strcmp(";binary",
-                      (char *)attribute +
-                      (strlen((char *)attribute) - 7)) == 0)) {
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     (char *) attr, attr_len);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          dlsize += attr_len + 3;
+
+          if((attr_len > 7) &&
+             (strcmp(";binary", (char *) attr + (attr_len - 7)) == 0)) {
             /* Binary attribute, encode to base64. */
-            CURLcode error = Curl_base64_encode(data,
-                                                vals[i]->bv_val,
-                                                vals[i]->bv_len,
-                                                &val_b64,
-                                                &val_b64_sz);
-            if(error) {
+            result = Curl_base64_encode(data,
+                                        vals[i]->bv_val,
+                                        vals[i]->bv_len,
+                                        &val_b64,
+                                        &val_b64_sz);
+            if(result) {
               ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+              Curl_unicodefree(attr);
+#endif
               ldap_memfree(attribute);
-              ldap_memfree(dn);
               if(ber)
                 ber_free(ber, 0);
-              status = error;
+
               goto quit;
             }
+
             if(val_b64_sz > 0) {
-              Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);
+              result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+                                         val_b64_sz);
               free(val_b64);
+              if(result) {
+                ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+                Curl_unicodefree(attr);
+#endif
+                ldap_memfree(attribute);
+                if(ber)
+                  ber_free(ber, 0);
+
+                goto quit;
+              }
+
               dlsize += val_b64_sz;
             }
           }
           else {
-            Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
-                              vals[i]->bv_len);
+            result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
+                                       vals[i]->bv_len);
+            if(result) {
+              ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+              Curl_unicodefree(attr);
+#endif
+              ldap_memfree(attribute);
+              if(ber)
+                ber_free(ber, 0);
+
+              goto quit;
+            }
+
             dlsize += vals[i]->bv_len;
           }
-          Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
           dlsize++;
         }
 
         /* Free memory used to store values */
         ldap_value_free_len(vals);
       }
-      Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+
+      /* Free the attribute as we are done with it */
+#if defined(USE_WIN32_LDAP)
+      Curl_unicodefree(attr);
+#endif
+      ldap_memfree(attribute);
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+      if(result)
+        goto quit;
       dlsize++;
       Curl_pgrsSetDownloadCounter(data, dlsize);
-      ldap_memfree(attribute);
     }
-    ldap_memfree(dn);
+
     if(ber)
        ber_free(ber, 0);
   }
 
 quit:
-  if(result) {
-    ldap_msgfree(result);
+  if(ldapmsg) {
+    ldap_msgfree(ldapmsg);
     LDAP_TRACE (("Received %d entries\n", num));
   }
   if(rc == LDAP_SIZELIMIT_EXCEEDED)
@@ -465,11 +670,17 @@ quit:
     ldapssl_client_deinit();
 #endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
 
+#if defined(USE_WIN32_LDAP)
+  Curl_unicodefree(passwd);
+  Curl_unicodefree(user);
+  Curl_unicodefree(host);
+#endif
+
   /* no data to transfer */
   Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
   connclose(conn, "LDAP connection always disable re-use");
 
-  return status;
+  return result;
 }
 
 #ifdef DEBUG_LDAP
@@ -513,57 +724,34 @@ static int str2scope (const char *p)
 
 /*
  * Split 'str' into strings separated by commas.
- * Note: res[] points into 'str'.
+ * Note: out[] points into 'str'.
  */
-static char **split_str (char *str)
+static bool split_str(char *str, char ***out, size_t *count)
 {
-  char **res, *lasts, *s;
-  int  i;
-
-  for(i = 2, s = strchr(str,','); s; i++)
-    s = strchr(++s,',');
+  char **res;
+  char *lasts;
+  char *s;
+  size_t  i;
+  size_t items = 1;
+
+  s = strchr(str, ',');
+  while(s) {
+    items++;
+    s = strchr(++s, ',');
+  }
 
-  res = calloc(i, sizeof(char*));
+  res = calloc(items, sizeof(char *));
   if(!res)
-    return NULL;
+    return FALSE;
 
-  for(i = 0, s = strtok_r(str, ",", &lasts); s;
+  for(i = 0, s = strtok_r(str, ",", &lasts); s && i < items;
       s = strtok_r(NULL, ",", &lasts), i++)
     res[i] = s;
-  return res;
-}
-
-/*
- * Unescape the LDAP-URL components
- */
-static bool unescape_elements (void *data, LDAPURLDesc *ludp)
-{
-  int i;
-
-  if(ludp->lud_filter) {
-    ludp->lud_filter = curl_easy_unescape(data, ludp->lud_filter, 0, NULL);
-    if(!ludp->lud_filter)
-       return FALSE;
-  }
-
-  for(i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) {
-    ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i],
-                                            0, NULL);
-    if(!ludp->lud_attrs[i])
-      return FALSE;
-    ludp->lud_attrs_dups++;
-  }
 
-  if(ludp->lud_dn) {
-    char *dn = ludp->lud_dn;
-    char *new_dn = curl_easy_unescape(data, dn, 0, NULL);
+  *out = res;
+  *count = items;
 
-    free(dn);
-    ludp->lud_dn = new_dn;
-    if(!new_dn)
-       return (FALSE);
-  }
-  return (TRUE);
+  return TRUE;
 }
 
 /*
@@ -582,8 +770,11 @@ static bool unescape_elements (void *data, LDAPURLDesc *ludp)
  */
 static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
 {
-  char *p, *q;
-  int i;
+  int rc = LDAP_SUCCESS;
+  char *path;
+  char *p;
+  char *q;
+  size_t i;
 
   if(!conn->data ||
       !conn->data->state.path ||
@@ -595,74 +786,190 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
   ludp->lud_port  = conn->remote_port;
   ludp->lud_host  = conn->host.name;
 
-  /* parse DN (Distinguished Name).
-   */
-  ludp->lud_dn = strdup(conn->data->state.path+1);
-  if(!ludp->lud_dn)
+  /* Duplicate the path */
+  p = path = strdup(conn->data->state.path + 1);
+  if(!path)
     return LDAP_NO_MEMORY;
 
-  p = strchr(ludp->lud_dn, '?');
-  LDAP_TRACE (("DN '%.*s'\n", p ? (size_t)(p-ludp->lud_dn) :
-               strlen(ludp->lud_dn), ludp->lud_dn));
+  /* Parse the DN (Distinguished Name) */
+  q = strchr(p, '?');
+  if(q)
+    *q++ = '\0';
+
+  if(*p) {
+    char *dn = p;
+    char *unescaped;
 
-  if(!p)
-    goto success;
+    LDAP_TRACE (("DN '%s'\n", dn));
 
-  *p++ = '\0';
+    /* Unescape the DN */
+    unescaped = curl_easy_unescape(conn->data, dn, 0, NULL);
+    if(!unescaped) {
+      rc = LDAP_NO_MEMORY;
 
-  /* parse attributes. skip "??".
-   */
+      goto quit;
+    }
+
+#if defined(USE_WIN32_LDAP)
+    /* Convert the unescaped string to a tchar */
+    ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped);
+
+    /* Free the unescaped string as we are done with it */
+    Curl_unicodefree(unescaped);
+
+    if(!ludp->lud_dn) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+#else
+    ludp->lud_dn = unescaped;
+#endif
+  }
+
+  p = q;
+  if(!p)
+    goto quit;
+
+  /* Parse the attributes. skip "??" */
   q = strchr(p, '?');
   if(q)
     *q++ = '\0';
 
-  if(*p && *p != '?') {
-    ludp->lud_attrs = split_str(p);
-    if(!ludp->lud_attrs)
-      return LDAP_NO_MEMORY;
+  if(*p) {
+    char **attributes;
+    size_t count = 0;
+
+    /* Split the string into an array of attributes */
+    if(!split_str(p, &attributes, &count)) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+    /* Allocate our array (+1 for the NULL entry) */
+#if defined(USE_WIN32_LDAP)
+    ludp->lud_attrs = calloc(count + 1, sizeof(TCHAR *));
+#else
+    ludp->lud_attrs = calloc(count + 1, sizeof(char *));
+#endif
+    if(!ludp->lud_attrs) {
+      free(attributes);
+
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+    for(i = 0; i < count; i++) {
+      char *unescaped;
+
+      LDAP_TRACE (("attr[%d] '%s'\n", i, attributes[i]));
+
+      /* Unescape the attribute */
+      unescaped = curl_easy_unescape(conn->data, attributes[i], 0, NULL);
+      if(!unescaped) {
+        free(attributes);
+
+        rc = LDAP_NO_MEMORY;
+
+        goto quit;
+      }
+
+#if defined(USE_WIN32_LDAP)
+      /* Convert the unescaped string to a tchar */
+      ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescaped);
+
+      /* Free the unescaped string as we are done with it */
+      Curl_unicodefree(unescaped);
+
+      if(!ludp->lud_attrs[i]) {
+        free(attributes);
 
-    for(i = 0; ludp->lud_attrs[i]; i++)
-      LDAP_TRACE (("attr[%d] '%s'\n", i, ludp->lud_attrs[i]));
+        rc = LDAP_NO_MEMORY;
+
+        goto quit;
+      }
+#else
+      ludp->lud_attrs[i] = unescaped;
+#endif
+
+      ludp->lud_attrs_dups++;
+    }
+
+    free(attributes);
   }
 
   p = q;
   if(!p)
-    goto success;
+    goto quit;
 
-  /* parse scope. skip "??"
-   */
+  /* Parse the scope. skip "??" */
   q = strchr(p, '?');
   if(q)
     *q++ = '\0';
 
-  if(*p && *p != '?') {
+  if(*p) {
     ludp->lud_scope = str2scope(p);
     if(ludp->lud_scope == -1) {
-      return LDAP_INVALID_SYNTAX;
+      rc = LDAP_INVALID_SYNTAX;
+
+      goto quit;
     }
     LDAP_TRACE (("scope %d\n", ludp->lud_scope));
   }
 
   p = q;
   if(!p)
-    goto success;
+    goto quit;
 
-  /* parse filter
-   */
+  /* Parse the filter */
   q = strchr(p, '?');
   if(q)
     *q++ = '\0';
-  if(!*p) {
-    return LDAP_INVALID_SYNTAX;
+
+  if(*p) {
+    char *filter = p;
+    char *unescaped;
+
+    LDAP_TRACE (("filter '%s'\n", filter));
+
+    /* Unescape the filter */
+    unescaped = curl_easy_unescape(conn->data, filter, 0, NULL);
+    if(!unescaped) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+#if defined(USE_WIN32_LDAP)
+    /* Convert the unescaped string to a tchar */
+    ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped);
+
+    /* Free the unescaped string as we are done with it */
+    Curl_unicodefree(unescaped);
+
+    if(!ludp->lud_filter) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+#else
+    ludp->lud_filter = unescaped;
+#endif
   }
 
-  ludp->lud_filter = p;
-  LDAP_TRACE (("filter '%s'\n", ludp->lud_filter));
+  p = q;
+  if(p && !*p) {
+    rc = LDAP_INVALID_SYNTAX;
 
-  success:
-  if(!unescape_elements(conn->data, ludp))
-    return LDAP_NO_MEMORY;
-  return LDAP_SUCCESS;
+    goto quit;
+  }
+
+quit:
+  free(path);
+
+  return rc;
 }
 
 static int _ldap_url_parse (const struct connectdata *conn,
@@ -691,11 +998,8 @@ static void _ldap_free_urldesc (LDAPURLDesc *ludp)
   if(!ludp)
     return;
 
-  if(ludp->lud_dn)
-    free(ludp->lud_dn);
-
-  if(ludp->lud_filter)
-    free(ludp->lud_filter);
+  free(ludp->lud_dn);
+  free(ludp->lud_filter);
 
   if(ludp->lud_attrs) {
     for(i = 0; i < ludp->lud_attrs_dups; i++)
diff --git a/Utilities/cmcurl/lib/md4.c b/Utilities/cmcurl/lib/md4.c
index 6930e02..60f73a2 100644
--- a/Utilities/cmcurl/lib/md4.c
+++ b/Utilities/cmcurl/lib/md4.c
@@ -1,282 +1,304 @@
-/*-
-   Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
-
-   License to copy and use this software is granted provided that it
-   is identified as the "RSA Data Security, Inc. MD4 Message-Digest
-   Algorithm" in all material mentioning or referencing this software
-   or this function.
-
-   License is also granted to make and use derivative works provided
-   that such works are identified as "derived from the RSA Data
-   Security, Inc. MD4 Message-Digest Algorithm" in all material
-   mentioning or referencing the derived work.
-
-   RSA Data Security, Inc. makes no representations concerning either
-   the merchantability of this software or the suitability of this
-   software for any particular purpose. It is provided "as is"
-   without express or implied warranty of any kind.
-
-   These notices must be retained in any copies of any part of this
-   documentation and/or software.
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD4 Message-Digest Algorithm (RFC 1320).
+ *
+ * Homepage:
+ http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001.  No copyright is
+ * claimed, and the software is hereby placed in the public domain.  In case
+ * this attempt to disclaim copyright and place the software in the public
+ * domain is deemed null and void, then the software is Copyright (c) 2001
+ * Alexander Peslyak and it is hereby released to the general public under the
+ * following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's.  No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible.  Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
  */
 
 #include "curl_setup.h"
 
-/* NSS crypto library does not provide the MD4 hash algorithm, so that we have
- * a local implementation of it */
-#ifdef USE_NSS
+/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so
+ * that we have a local implementation of it */
+#if defined(USE_NSS) || defined(USE_OS400CRYPTO)
 
 #include "curl_md4.h"
 #include "warnless.h"
 
-typedef unsigned int UINT4;
+#ifndef HAVE_OPENSSL
 
-typedef struct MD4Context {
-  UINT4 state[4];               /* state (ABCD) */
-  UINT4 count[2];               /* number of bits, modulo 2^64 (lsb first) */
-  unsigned char buffer[64];     /* input buffer */
+#include <string.h>
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD4_u32plus;
+
+typedef struct {
+  MD4_u32plus lo, hi;
+  MD4_u32plus a, b, c, d;
+  unsigned char buffer[64];
+  MD4_u32plus block[16];
 } MD4_CTX;
 
-/* Constants for MD4Transform routine.
- */
-#define S11 3
-#define S12 7
-#define S13 11
-#define S14 19
-#define S21 3
-#define S22 5
-#define S23 9
-#define S24 13
-#define S31 3
-#define S32 9
-#define S33 11
-#define S34 15
-
-static void MD4Transform(UINT4 [4], const unsigned char [64]);
-static void Encode(unsigned char *, UINT4 *, unsigned int);
-static void Decode(UINT4 *, const unsigned char *, unsigned int);
-
-static unsigned char PADDING[64] = {
-  0x80, 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, 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, 0
-};
-
-/* F, G and H are basic MD4 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
+static void MD4_Init(MD4_CTX *ctx);
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
 
-/* ROTATE_LEFT rotates x left n bits.
+/*
+ * The basic MD4 functions.
+ *
+ * F and G are optimized compared to their RFC 1320 definitions, with the
+ * optimization for F borrowed from Colin Plumb's MD5 implementation.
  */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
-/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s) { \
-    (a) += F ((b), (c), (d)) + (x); \
-    (a) = ROTATE_LEFT ((a), (s)); \
-  }
-#define GG(a, b, c, d, x, s) { \
-    (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
-    (a) = ROTATE_LEFT ((a), (s)); \
-  }
-#define HH(a, b, c, d, x, s) { \
-    (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
-    (a) = ROTATE_LEFT ((a), (s)); \
-  }
+#define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z)                      (((x) & ((y) | (z))) | ((y) & (z)))
+#define H(x, y, z)                      ((x) ^ (y) ^ (z))
 
-/* MD4 initialization. Begins an MD4 operation, writing a new context.
+/*
+ * The MD4 transformation for all three rounds.
  */
-static void MD4Init(MD4_CTX *context)
+#define STEP(f, a, b, c, d, x, s) \
+        (a) += f((b), (c), (d)) + (x); \
+        (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization.  Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+        (*(MD4_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+        SET(n)
+#else
+#define SET(n) \
+        (ctx->block[(n)] = \
+        (MD4_u32plus)ptr[(n) * 4] | \
+        ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
+        ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
+        ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+        (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters.  There are no alignment requirements.
+ */
+static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
 {
-  context->count[0] = context->count[1] = 0;
-
-  /* Load magic initialization constants.
-   */
-  context->state[0] = 0x67452301;
-  context->state[1] = 0xefcdab89;
-  context->state[2] = 0x98badcfe;
-  context->state[3] = 0x10325476;
+  const unsigned char *ptr;
+  MD4_u32plus a, b, c, d;
+  MD4_u32plus saved_a, saved_b, saved_c, saved_d;
+
+  ptr = (const unsigned char *)data;
+
+  a = ctx->a;
+  b = ctx->b;
+  c = ctx->c;
+  d = ctx->d;
+
+  do {
+    saved_a = a;
+    saved_b = b;
+    saved_c = c;
+    saved_d = d;
+
+/* Round 1 */
+    STEP(F, a, b, c, d, SET(0), 3)
+      STEP(F, d, a, b, c, SET(1), 7)
+      STEP(F, c, d, a, b, SET(2), 11)
+      STEP(F, b, c, d, a, SET(3), 19)
+      STEP(F, a, b, c, d, SET(4), 3)
+      STEP(F, d, a, b, c, SET(5), 7)
+      STEP(F, c, d, a, b, SET(6), 11)
+      STEP(F, b, c, d, a, SET(7), 19)
+      STEP(F, a, b, c, d, SET(8), 3)
+      STEP(F, d, a, b, c, SET(9), 7)
+      STEP(F, c, d, a, b, SET(10), 11)
+      STEP(F, b, c, d, a, SET(11), 19)
+      STEP(F, a, b, c, d, SET(12), 3)
+      STEP(F, d, a, b, c, SET(13), 7)
+      STEP(F, c, d, a, b, SET(14), 11)
+      STEP(F, b, c, d, a, SET(15), 19)
+
+/* Round 2 */
+      STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
+      STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
+      STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
+      STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
+
+/* Round 3 */
+      STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
+      STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
+      STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
+      STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
+
+      a += saved_a;
+    b += saved_b;
+    c += saved_c;
+    d += saved_d;
+
+    ptr += 64;
+  } while(size -= 64);
+
+  ctx->a = a;
+  ctx->b = b;
+  ctx->c = c;
+  ctx->d = d;
+
+  return ptr;
 }
 
-/* MD4 block update operation. Continues an MD4 message-digest
-     operation, processing another message block, and updating the
-     context.
- */
-static void MD4Update(MD4_CTX *context, const unsigned char *input,
-                      unsigned int inputLen)
+static void MD4_Init(MD4_CTX *ctx)
 {
-  unsigned int i, bufindex, partLen;
-
-  /* Compute number of bytes mod 64 */
-  bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F);
-  /* Update number of bits */
-  if((context->count[0] += ((UINT4)inputLen << 3))
-     < ((UINT4)inputLen << 3))
-    context->count[1]++;
-  context->count[1] += ((UINT4)inputLen >> 29);
-
-  partLen = 64 - bufindex;
-  /* Transform as many times as possible.
-   */
-  if(inputLen >= partLen) {
-    memcpy(&context->buffer[bufindex], input, partLen);
-    MD4Transform (context->state, context->buffer);
-
-    for(i = partLen; i + 63 < inputLen; i += 64)
-      MD4Transform (context->state, &input[i]);
-
-    bufindex = 0;
-  }
-  else
-    i = 0;
+  ctx->a = 0x67452301;
+  ctx->b = 0xefcdab89;
+  ctx->c = 0x98badcfe;
+  ctx->d = 0x10325476;
 
-  /* Buffer remaining input */
-  memcpy(&context->buffer[bufindex], &input[i], inputLen-i);
+  ctx->lo = 0;
+  ctx->hi = 0;
 }
 
-/* MD4 padding. */
-static void MD4Pad(MD4_CTX *context)
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
 {
-  unsigned char bits[8];
-  unsigned int bufindex, padLen;
+  MD4_u32plus saved_lo;
+  unsigned long used, available;
 
-  /* Save number of bits */
-  Encode (bits, context->count, 8);
+  saved_lo = ctx->lo;
+  if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+    ctx->hi++;
+  ctx->hi += (MD4_u32plus)size >> 29;
 
-  /* Pad out to 56 mod 64.
-   */
-  bufindex = (unsigned int)((context->count[0] >> 3) & 0x3f);
-  padLen = (bufindex < 56) ? (56 - bufindex) : (120 - bufindex);
-  MD4Update (context, PADDING, padLen);
+  used = saved_lo & 0x3f;
 
-  /* Append length (before padding) */
-  MD4Update (context, bits, 8);
-}
+  if(used) {
+    available = 64 - used;
 
-/* MD4 finalization. Ends an MD4 message-digest operation, writing the
-     the message digest and zeroizing the context.
- */
-static void MD4Final (unsigned char digest[16], MD4_CTX *context)
-{
-  /* Do padding */
-  MD4Pad (context);
+    if(size < available) {
+      memcpy(&ctx->buffer[used], data, size);
+      return;
+    }
 
-  /* Store state in digest */
-  Encode (digest, context->state, 16);
+    memcpy(&ctx->buffer[used], data, available);
+    data = (const unsigned char *)data + available;
+    size -= available;
+    body(ctx, ctx->buffer, 64);
+  }
 
-  /* Zeroize sensitive information.
-   */
-  memset(context, 0, sizeof(*context));
-}
+  if(size >= 64) {
+    data = body(ctx, data, size & ~(unsigned long)0x3f);
+    size &= 0x3f;
+  }
 
-/* MD4 basic transformation. Transforms state based on block.
- */
-static void MD4Transform (UINT4 state[4], const unsigned char block[64])
-{
-  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
-  Decode (x, block, 64);
-
-  /* Round 1 */
-  FF (a, b, c, d, x[ 0], S11); /* 1 */
-  FF (d, a, b, c, x[ 1], S12); /* 2 */
-  FF (c, d, a, b, x[ 2], S13); /* 3 */
-  FF (b, c, d, a, x[ 3], S14); /* 4 */
-  FF (a, b, c, d, x[ 4], S11); /* 5 */
-  FF (d, a, b, c, x[ 5], S12); /* 6 */
-  FF (c, d, a, b, x[ 6], S13); /* 7 */
-  FF (b, c, d, a, x[ 7], S14); /* 8 */
-  FF (a, b, c, d, x[ 8], S11); /* 9 */
-  FF (d, a, b, c, x[ 9], S12); /* 10 */
-  FF (c, d, a, b, x[10], S13); /* 11 */
-  FF (b, c, d, a, x[11], S14); /* 12 */
-  FF (a, b, c, d, x[12], S11); /* 13 */
-  FF (d, a, b, c, x[13], S12); /* 14 */
-  FF (c, d, a, b, x[14], S13); /* 15 */
-  FF (b, c, d, a, x[15], S14); /* 16 */
-
-  /* Round 2 */
-  GG (a, b, c, d, x[ 0], S21); /* 17 */
-  GG (d, a, b, c, x[ 4], S22); /* 18 */
-  GG (c, d, a, b, x[ 8], S23); /* 19 */
-  GG (b, c, d, a, x[12], S24); /* 20 */
-  GG (a, b, c, d, x[ 1], S21); /* 21 */
-  GG (d, a, b, c, x[ 5], S22); /* 22 */
-  GG (c, d, a, b, x[ 9], S23); /* 23 */
-  GG (b, c, d, a, x[13], S24); /* 24 */
-  GG (a, b, c, d, x[ 2], S21); /* 25 */
-  GG (d, a, b, c, x[ 6], S22); /* 26 */
-  GG (c, d, a, b, x[10], S23); /* 27 */
-  GG (b, c, d, a, x[14], S24); /* 28 */
-  GG (a, b, c, d, x[ 3], S21); /* 29 */
-  GG (d, a, b, c, x[ 7], S22); /* 30 */
-  GG (c, d, a, b, x[11], S23); /* 31 */
-  GG (b, c, d, a, x[15], S24); /* 32 */
-
-  /* Round 3 */
-  HH (a, b, c, d, x[ 0], S31); /* 33 */
-  HH (d, a, b, c, x[ 8], S32); /* 34 */
-  HH (c, d, a, b, x[ 4], S33); /* 35 */
-  HH (b, c, d, a, x[12], S34); /* 36 */
-  HH (a, b, c, d, x[ 2], S31); /* 37 */
-  HH (d, a, b, c, x[10], S32); /* 38 */
-  HH (c, d, a, b, x[ 6], S33); /* 39 */
-  HH (b, c, d, a, x[14], S34); /* 40 */
-  HH (a, b, c, d, x[ 1], S31); /* 41 */
-  HH (d, a, b, c, x[ 9], S32); /* 42 */
-  HH (c, d, a, b, x[ 5], S33); /* 43 */
-  HH (b, c, d, a, x[13], S34); /* 44 */
-  HH (a, b, c, d, x[ 3], S31); /* 45 */
-  HH (d, a, b, c, x[11], S32); /* 46 */
-  HH (c, d, a, b, x[ 7], S33); /* 47 */
-  HH (b, c, d, a, x[15], S34); /* 48 */
-
-  state[0] += a;
-  state[1] += b;
-  state[2] += c;
-  state[3] += d;
-
-  /* Zeroize sensitive information.
-   */
-  memset(x, 0, sizeof(x));
+  memcpy(ctx->buffer, data, size);
 }
 
-/* Encodes input (UINT4) into output (unsigned char). Assumes len is
-     a multiple of 4.
- */
-static void Encode(unsigned char *output, UINT4 *input, unsigned int len)
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
 {
-  unsigned int i, j;
+  unsigned long used, available;
 
-  for(i = 0, j = 0; j < len; i++, j += 4) {
-    output[j] = (unsigned char)(input[i] & 0xff);
-    output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
-    output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
-    output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
-  }
-}
+  used = ctx->lo & 0x3f;
 
-/* Decodes input (unsigned char) into output (UINT4). Assumes len is
-     a multiple of 4.
- */
-static void Decode (UINT4 *output, const unsigned char *input,
-                    unsigned int len)
-{
-  unsigned int i, j;
+  ctx->buffer[used++] = 0x80;
+
+  available = 64 - used;
 
-  for(i = 0, j = 0; j < len; i++, j += 4)
-    output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
-      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+  if(available < 8) {
+    memset(&ctx->buffer[used], 0, available);
+    body(ctx, ctx->buffer, 64);
+    used = 0;
+    available = 64;
+  }
+
+  memset(&ctx->buffer[used], 0, available - 8);
+
+  ctx->lo <<= 3;
+  ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
+  ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
+  ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
+  ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
+  ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
+  ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
+  ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
+  ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
+
+  body(ctx, ctx->buffer, 64);
+
+  result[0] = curlx_ultouc((ctx->a)&0xff);
+  result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
+  result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
+  result[3] = curlx_ultouc(ctx->a >> 24);
+  result[4] = curlx_ultouc((ctx->b)&0xff);
+  result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
+  result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
+  result[7] = curlx_ultouc(ctx->b >> 24);
+  result[8] = curlx_ultouc((ctx->c)&0xff);
+  result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
+  result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
+  result[11] = curlx_ultouc(ctx->c >> 24);
+  result[12] = curlx_ultouc((ctx->d)&0xff);
+  result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
+  result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
+  result[15] = curlx_ultouc(ctx->d >> 24);
+
+  memset(ctx, 0, sizeof(*ctx));
 }
 
+#endif
+
 void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
 {
   MD4_CTX ctx;
-  MD4Init(&ctx);
-  MD4Update(&ctx, input, curlx_uztoui(len));
-  MD4Final(output, &ctx);
+  MD4_Init(&ctx);
+  MD4_Update(&ctx, input, curlx_uztoui(len));
+  MD4_Final(output, &ctx);
 }
-#endif /* USE_NSS */
+#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */
diff --git a/Utilities/cmcurl/lib/md5.c b/Utilities/cmcurl/lib/md5.c
index af39fd4..b604c10 100644
--- a/Utilities/cmcurl/lib/md5.c
+++ b/Utilities/cmcurl/lib/md5.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,11 +28,10 @@
 #include "curl_hmac.h"
 #include "warnless.h"
 
-#include "curl_memory.h"
-
 #if defined(USE_GNUTLS_NETTLE)
 
 #include <nettle/md5.h>
+#include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -58,6 +57,7 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
 #elif defined(USE_GNUTLS)
 
 #include <gcrypt.h>
+#include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -81,14 +81,12 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
   gcry_md_close(*ctx);
 }
 
-#elif defined(USE_SSLEAY)
+#elif defined(USE_OPENSSL)
 /* When OpenSSL is available we use the MD5-function from OpenSSL */
-
-#  ifdef USE_OPENSSL
-#    include <openssl/md5.h>
-#  else
-#    include <md5.h>
-#  endif
+#include <openssl/md5.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
 
 #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
               (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
@@ -103,6 +101,9 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
    reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
 #  include <CommonCrypto/CommonDigest.h>
 #  define MD5_CTX CC_MD5_CTX
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
 
 static void MD5_Init(MD5_CTX *ctx)
 {
@@ -124,6 +125,9 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
 #elif defined(_WIN32)
 
 #include <wincrypt.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
 
 typedef struct {
   HCRYPTPROV hCryptProv;
@@ -157,314 +161,326 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
     CryptReleaseContext(ctx->hCryptProv, 0);
 }
 
+#elif defined(USE_AXTLS)
+#include <axTLS/config.h>
+#include <axTLS/os_int.h>
+#include <axTLS/crypto.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
 #else
 /* When no other crypto library is available we use this code segment */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001.  No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's.  No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible.  Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
  */
 
-/* UINT4 defines a four byte word */
-typedef unsigned int UINT4;
+#include <string.h>
 
-/* MD5 context. */
-struct md5_ctx {
-  UINT4 state[4];                                   /* state (ABCD) */
-  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
-  unsigned char buffer[64];                         /* input buffer */
-};
-
-typedef struct md5_ctx MD5_CTX;
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
 
-static void MD5_Init(struct md5_ctx *);
-static void MD5_Update(struct md5_ctx *, const unsigned char *, unsigned int);
-static void MD5_Final(unsigned char [16], struct md5_ctx *);
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD5_u32plus;
 
-/* Constants for MD5Transform routine.
- */
+typedef struct {
+  MD5_u32plus lo, hi;
+  MD5_u32plus a, b, c, d;
+  unsigned char buffer[64];
+  MD5_u32plus block[16];
+} MD5_CTX;
 
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-
-static void MD5Transform(UINT4 [4], const unsigned char [64]);
-static void Encode(unsigned char *, UINT4 *, unsigned int);
-static void Decode(UINT4 *, const unsigned char *, unsigned int);
-
-static const unsigned char PADDING[64] = {
-  0x80, 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, 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, 0
-};
+static void MD5_Init(MD5_CTX *ctx);
+static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
+static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
 
-/* F, G, H and I are basic MD5 functions.
+/*
+ * The basic MD5 functions.
+ *
+ * F and G are optimized compared to their RFC 1321 definitions for
+ * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
+ * implementation.
  */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits.
+#define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z)                      ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z)                      (((x) ^ (y)) ^ (z))
+#define H2(x, y, z)                     ((x) ^ ((y) ^ (z)))
+#define I(x, y, z)                      ((y) ^ ((x) | ~(z)))
+
+/*
+ * The MD5 transformation for all four rounds.
  */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-Rotation is separate from addition to prevent recomputation.
+#define STEP(f, a, b, c, d, x, t, s) \
+        (a) += f((b), (c), (d)) + (x) + (t); \
+        (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+        (a) += (b);
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization.  Nothing will break if it
+ * doesn't work.
  */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
-  }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
-  }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
-  }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
-  }
-
-/* MD5 initialization. Begins an MD5 operation, writing a new context.
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+        (*(MD5_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+        SET(n)
+#else
+#define SET(n) \
+        (ctx->block[(n)] = \
+        (MD5_u32plus)ptr[(n) * 4] | \
+        ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+        ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+        ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+        (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters.  There are no alignment requirements.
  */
-static void MD5_Init(struct md5_ctx *context)
+static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
 {
-  context->count[0] = context->count[1] = 0;
-  /* Load magic initialization constants. */
-  context->state[0] = 0x67452301;
-  context->state[1] = 0xefcdab89;
-  context->state[2] = 0x98badcfe;
-  context->state[3] = 0x10325476;
+  const unsigned char *ptr;
+  MD5_u32plus a, b, c, d;
+  MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+  ptr = (const unsigned char *)data;
+
+  a = ctx->a;
+  b = ctx->b;
+  c = ctx->c;
+  d = ctx->d;
+
+  do {
+    saved_a = a;
+    saved_b = b;
+    saved_c = c;
+    saved_d = d;
+
+/* Round 1 */
+    STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+      STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+      STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+      STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+      STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+      STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+      STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+      STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+      STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+      STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+      STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+      STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+      STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+      STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+      STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+      STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+/* Round 2 */
+      STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+      STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+      STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+      STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+      STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+      STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+      STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+      STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+      STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+      STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+      STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+      STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+      STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+      STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+      STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+      STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+/* Round 3 */
+      STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+      STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
+      STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+      STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
+      STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+      STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+      STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+      STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
+      STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+      STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
+      STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+      STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
+      STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+      STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
+      STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+      STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+/* Round 4 */
+      STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+      STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+      STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+      STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+      STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+      STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+      STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+      STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+      STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+      STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+      STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+      STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+      STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+      STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+      STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+      STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+      a += saved_a;
+    b += saved_b;
+    c += saved_c;
+    d += saved_d;
+
+    ptr += 64;
+  } while(size -= 64);
+
+  ctx->a = a;
+  ctx->b = b;
+  ctx->c = c;
+  ctx->d = d;
+
+  return ptr;
 }
 
-/* MD5 block update operation. Continues an MD5 message-digest
-  operation, processing another message block, and updating the
-  context.
- */
-static void MD5_Update (struct md5_ctx *context,    /* context */
-                        const unsigned char *input, /* input block */
-                        unsigned int inputLen)      /* length of input block */
+static void MD5_Init(MD5_CTX *ctx)
 {
-  unsigned int i, bufindex, partLen;
+  ctx->a = 0x67452301;
+  ctx->b = 0xefcdab89;
+  ctx->c = 0x98badcfe;
+  ctx->d = 0x10325476;
 
-  /* Compute number of bytes mod 64 */
-  bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F);
+  ctx->lo = 0;
+  ctx->hi = 0;
+}
 
-  /* Update number of bits */
-  if((context->count[0] += ((UINT4)inputLen << 3))
-      < ((UINT4)inputLen << 3))
-    context->count[1]++;
-  context->count[1] += ((UINT4)inputLen >> 29);
+static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
+{
+  MD5_u32plus saved_lo;
+  unsigned long used, available;
+
+  saved_lo = ctx->lo;
+  if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+    ctx->hi++;
+  ctx->hi += (MD5_u32plus)size >> 29;
 
-  partLen = 64 - bufindex;
+  used = saved_lo & 0x3f;
 
-  /* Transform as many times as possible. */
-  if(inputLen >= partLen) {
-    memcpy(&context->buffer[bufindex], input, partLen);
-    MD5Transform(context->state, context->buffer);
+  if(used) {
+    available = 64 - used;
 
-    for(i = partLen; i + 63 < inputLen; i += 64)
-      MD5Transform(context->state, &input[i]);
+    if(size < available) {
+      memcpy(&ctx->buffer[used], data, size);
+      return;
+    }
+
+    memcpy(&ctx->buffer[used], data, available);
+    data = (const unsigned char *)data + available;
+    size -= available;
+    body(ctx, ctx->buffer, 64);
+  }
 
-    bufindex = 0;
+  if(size >= 64) {
+    data = body(ctx, data, size & ~(unsigned long)0x3f);
+    size &= 0x3f;
   }
-  else
-    i = 0;
 
-  /* Buffer remaining input */
-  memcpy(&context->buffer[bufindex], &input[i], inputLen-i);
+  memcpy(ctx->buffer, data, size);
 }
 
-/* MD5 finalization. Ends an MD5 message-digest operation, writing the
-   the message digest and zeroizing the context.
-*/
-static void MD5_Final(unsigned char digest[16], /* message digest */
-                      struct md5_ctx *context) /* context */
+static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
 {
-  unsigned char bits[8];
-  unsigned int count, padLen;
+  unsigned long used, available;
 
-  /* Save number of bits */
-  Encode (bits, context->count, 8);
+  used = ctx->lo & 0x3f;
 
-  /* Pad out to 56 mod 64. */
-  count = (unsigned int)((context->count[0] >> 3) & 0x3f);
-  padLen = (count < 56) ? (56 - count) : (120 - count);
-  MD5_Update (context, PADDING, padLen);
+  ctx->buffer[used++] = 0x80;
 
-  /* Append length (before padding) */
-  MD5_Update (context, bits, 8);
+  available = 64 - used;
 
-  /* Store state in digest */
-  Encode (digest, context->state, 16);
-
-  /* Zeroize sensitive information. */
-  memset ((void *)context, 0, sizeof (*context));
-}
-
-/* MD5 basic transformation. Transforms state based on block. */
-static void MD5Transform(UINT4 state[4],
-                         const unsigned char block[64])
-{
-  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
-  Decode (x, block, 64);
-
-  /* Round 1 */
-  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
-  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
-  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
-  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
-  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
-  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
-  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
-  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
-  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
-  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
-  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
-  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
-  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
-  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
-  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
-  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
-  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
-  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
-  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
-  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
-  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
-  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
-  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
-  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
-  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
-  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
-  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
-  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
-  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
-  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
-  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
-  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
-  /* Round 3 */
-  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
-  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
-  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
-  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
-  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
-  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
-  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
-  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
-  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
-  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
-  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
-  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
-  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
-  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
-  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
-  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
-  /* Round 4 */
-  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
-  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
-  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
-  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
-  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
-  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
-  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
-  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
-  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
-  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
-  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
-  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
-  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
-  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
-  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
-  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
-  state[0] += a;
-  state[1] += b;
-  state[2] += c;
-  state[3] += d;
-
-  /* Zeroize sensitive information. */
-  memset((void *)x, 0, sizeof (x));
-}
-
-/* Encodes input (UINT4) into output (unsigned char). Assumes len is
-  a multiple of 4.
- */
-static void Encode (unsigned char *output,
-                    UINT4 *input,
-                    unsigned int len)
-{
-  unsigned int i, j;
-
-  for(i = 0, j = 0; j < len; i++, j += 4) {
-    output[j] = (unsigned char)(input[i] & 0xff);
-    output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
-    output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
-    output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+  if(available < 8) {
+    memset(&ctx->buffer[used], 0, available);
+    body(ctx, ctx->buffer, 64);
+    used = 0;
+    available = 64;
   }
-}
-
-/* Decodes input (unsigned char) into output (UINT4). Assumes len is
-   a multiple of 4.
-*/
-static void Decode (UINT4 *output,
-                    const unsigned char *input,
-                    unsigned int len)
-{
-  unsigned int i, j;
 
-  for(i = 0, j = 0; j < len; i++, j += 4)
-    output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
-      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+  memset(&ctx->buffer[used], 0, available - 8);
+
+  ctx->lo <<= 3;
+  ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
+  ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
+  ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
+  ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24);
+  ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
+  ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
+  ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
+  ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
+
+  body(ctx, ctx->buffer, 64);
+
+  result[0] = curlx_ultouc((ctx->a)&0xff);
+  result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
+  result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
+  result[3] = curlx_ultouc(ctx->a >> 24);
+  result[4] = curlx_ultouc((ctx->b)&0xff);
+  result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
+  result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
+  result[7] = curlx_ultouc(ctx->b >> 24);
+  result[8] = curlx_ultouc((ctx->c)&0xff);
+  result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
+  result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
+  result[11] = curlx_ultouc(ctx->c >> 24);
+  result[12] = curlx_ultouc((ctx->d)&0xff);
+  result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
+  result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
+  result[15] = curlx_ultouc(ctx->d >> 24);
+
+  memset(ctx, 0, sizeof(*ctx));
 }
 
 #endif /* CRYPTO LIBS */
 
-/* The last #include file should be: */
-#include "memdebug.h"
-
 const HMAC_params Curl_HMAC_MD5[] = {
   {
     (HMAC_hinit_func) MD5_Init,           /* Hash initialization function. */
@@ -486,6 +502,9 @@ const MD5_params Curl_DIGEST_MD5[] = {
   }
 };
 
+/*
+ * @unittest: 1601
+ */
 void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
                 const unsigned char *input)
 {
diff --git a/Utilities/cmcurl/lib/memdebug.c b/Utilities/cmcurl/lib/memdebug.c
index 4afa620..dd8889b 100644
--- a/Utilities/cmcurl/lib/memdebug.c
+++ b/Utilities/cmcurl/lib/memdebug.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,8 +26,7 @@
 
 #include <curl/curl.h>
 
-#define _MPRINTF_REPLACE
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 #include "urldata.h"
 
 #define MEMDEBUG_NODEFINES /* don't redefine the standard functions */
@@ -113,7 +112,7 @@ void curl_memdebug(const char *logname)
 {
   if(!logfile) {
     if(logname && *logname)
-      logfile = fopen(logname, "w");
+      logfile = fopen(logname, FOPEN_WRITETEXT);
     else
       logfile = stderr;
 #ifdef MEMDEBUG_LOG_SYNC
@@ -343,10 +342,10 @@ curl_socket_t curl_socket(int domain, int type, int protocol,
                           int line, const char *source)
 {
   const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
-                    "FD %s:%d socket() = %d\n" :
-                    (sizeof(curl_socket_t) == sizeof(long)) ?
-                    "FD %s:%d socket() = %ld\n" :
-                    "FD %s:%d socket() = %zd\n" ;
+    "FD %s:%d socket() = %d\n" :
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d socket() = %ld\n" :
+    "FD %s:%d socket() = %zd\n";
 
   curl_socket_t sockfd = socket(domain, type, protocol);
 
@@ -362,10 +361,10 @@ int curl_socketpair(int domain, int type, int protocol,
                     int line, const char *source)
 {
   const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
-                    "FD %s:%d socketpair() = %d %d\n" :
-                    (sizeof(curl_socket_t) == sizeof(long)) ?
-                    "FD %s:%d socketpair() = %ld %ld\n" :
-                    "FD %s:%d socketpair() = %zd %zd\n" ;
+    "FD %s:%d socketpair() = %d %d\n" :
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d socketpair() = %ld %ld\n" :
+    "FD %s:%d socketpair() = %zd %zd\n";
 
   int res = socketpair(domain, type, protocol, socket_vector);
 
@@ -380,10 +379,10 @@ curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
                           int line, const char *source)
 {
   const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
-                    "FD %s:%d accept() = %d\n" :
-                    (sizeof(curl_socket_t) == sizeof(long)) ?
-                    "FD %s:%d accept() = %ld\n" :
-                    "FD %s:%d accept() = %zd\n" ;
+    "FD %s:%d accept() = %d\n" :
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d accept() = %ld\n" :
+    "FD %s:%d accept() = %zd\n";
 
   struct sockaddr *addr = (struct sockaddr *)saddr;
   curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen;
@@ -400,10 +399,10 @@ curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
 void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source)
 {
   const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
-                    "FD %s:%d sclose(%d)\n" :
-                    (sizeof(curl_socket_t) == sizeof(long)) ?
-                    "FD %s:%d sclose(%ld)\n" :
-                    "FD %s:%d sclose(%zd)\n" ;
+    "FD %s:%d sclose(%d)\n":
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d sclose(%ld)\n":
+    "FD %s:%d sclose(%zd)\n";
 
   if(source)
     curl_memlog(fmt, source, line, sockfd);
diff --git a/Utilities/cmcurl/lib/memdebug.h b/Utilities/cmcurl/lib/memdebug.h
index bd565c8..cfac1e0 100644
--- a/Utilities/cmcurl/lib/memdebug.h
+++ b/Utilities/cmcurl/lib/memdebug.h
@@ -8,7 +8,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -104,13 +104,13 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
 #endif
 
 #define socket(domain,type,protocol)\
- curl_socket(domain,type,protocol,__LINE__,__FILE__)
+ curl_socket(domain, type, protocol, __LINE__, __FILE__)
 #undef accept /* for those with accept as a macro */
 #define accept(sock,addr,len)\
- curl_accept(sock,addr,len,__LINE__,__FILE__)
+ curl_accept(sock, addr, len, __LINE__, __FILE__)
 #ifdef HAVE_SOCKETPAIR
 #define socketpair(domain,type,protocol,socket_vector)\
- curl_socketpair(domain,type,protocol,socket_vector,__LINE__,__FILE__)
+ curl_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__)
 #endif
 
 #ifdef HAVE_GETADDRINFO
@@ -119,25 +119,25 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
    our macro as for other platforms. Instead, we redefine the new name they
    define getaddrinfo to become! */
 #define ogetaddrinfo(host,serv,hint,res) \
-  curl_dogetaddrinfo(host,serv,hint,res,__LINE__,__FILE__)
+  curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
 #else
 #undef getaddrinfo
 #define getaddrinfo(host,serv,hint,res) \
-  curl_dogetaddrinfo(host,serv,hint,res,__LINE__,__FILE__)
+  curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
 #endif
 #endif /* HAVE_GETADDRINFO */
 
 #ifdef HAVE_GETNAMEINFO
 #undef getnameinfo
 #define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
-  curl_dogetnameinfo(sa,salen,host,hostlen,serv,servlen,flags, __LINE__, \
-  __FILE__)
+  curl_dogetnameinfo(sa, salen, host, hostlen, serv, servlen, flags, \
+                     __LINE__, __FILE__)
 #endif /* HAVE_GETNAMEINFO */
 
 #ifdef HAVE_FREEADDRINFO
 #undef freeaddrinfo
 #define freeaddrinfo(data) \
-  curl_dofreeaddrinfo(data,__LINE__,__FILE__)
+  curl_dofreeaddrinfo(data, __LINE__, __FILE__)
 #endif /* HAVE_FREEADDRINFO */
 
 /* sclose is probably already defined, redefine it! */
@@ -171,6 +171,6 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
  */
 
 #define Curl_safefree(ptr) \
-  do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE
+  do { free((ptr)); (ptr) = NULL;} WHILE_FALSE
 
 #endif /* HEADER_CURL_MEMDEBUG_H */
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
index a1dc2c8..0052087 100644
--- a/Utilities/cmcurl/lib/multi.c
+++ b/Utilities/cmcurl/lib/multi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -39,14 +39,10 @@
 #include "warnless.h"
 #include "speedcheck.h"
 #include "conncache.h"
-#include "bundles.h"
 #include "multihandle.h"
 #include "pipeline.h"
 #include "sigpipe.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -66,15 +62,11 @@
 
 #define GOOD_MULTI_HANDLE(x) \
   ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
-#define GOOD_EASY_HANDLE(x) \
-  ((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
 
 static void singlesocket(struct Curl_multi *multi,
                          struct SessionHandle *data);
 static int update_timer(struct Curl_multi *multi);
 
-static bool isHandleAtHead(struct SessionHandle *handle,
-                           struct curl_llist *pipeline);
 static CURLMcode add_next_timeout(struct timeval now,
                                   struct Curl_multi *multi,
                                   struct SessionHandle *d);
@@ -89,6 +81,7 @@ static const char * const statename[]={
   "WAITRESOLVE",
   "WAITCONNECT",
   "WAITPROXYCONNECT",
+  "SENDPROTOCONNECT",
   "PROTOCONNECT",
   "WAITDO",
   "DO",
@@ -113,20 +106,23 @@ static void mstate(struct SessionHandle *data, CURLMstate state
 #endif
 )
 {
-#ifdef DEBUGBUILD
-  long connection_id = -5000;
-#endif
   CURLMstate oldstate = data->mstate;
 
+#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) lineno;
+#endif
+
   if(oldstate == state)
     /* don't bother when the new state is the same as the old state */
     return;
 
   data->mstate = state;
 
-#ifdef DEBUGBUILD
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
   if(data->mstate >= CURLM_STATE_CONNECT_PEND &&
      data->mstate < CURLM_STATE_COMPLETED) {
+    long connection_id = -5000;
+
     if(data->easy_conn)
       connection_id = data->easy_conn->connection_id;
 
@@ -136,6 +132,7 @@ static void mstate(struct SessionHandle *data, CURLMstate state
           (void *)data, lineno, connection_id);
   }
 #endif
+
   if(state == CURLM_STATE_COMPLETED)
     /* changing to COMPLETED means there's one less easy handle 'alive' */
     data->multi->num_alive--;
@@ -153,7 +150,6 @@ static void mstate(struct SessionHandle *data, CURLMstate state
 
 struct Curl_sh_entry {
   struct SessionHandle *easy;
-  time_t timestamp;
   int action;  /* what action READ/WRITE this socket waits for */
   curl_socket_t socket; /* mainly to ease debugging */
   void *socketp; /* settable by users with curl_multi_assign() */
@@ -180,11 +176,12 @@ static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
   check = calloc(1, sizeof(struct Curl_sh_entry));
   if(!check)
     return NULL; /* major failure */
+
   check->easy = data;
   check->socket = s;
 
   /* make/add new hash entry */
-  if(NULL == Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
+  if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
     free(check);
     return NULL; /* major failure */
   }
@@ -214,8 +211,7 @@ static void sh_freeentry(void *freethis)
 {
   struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
 
-  if(p)
-    free(p);
+  free(p);
 }
 
 static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
@@ -251,10 +247,10 @@ static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
  * per call."
  *
  */
-static struct curl_hash *sh_init(int hashsize)
+static int sh_init(struct curl_hash *hash, int hashsize)
 {
-  return Curl_hash_alloc(hashsize, hash_fd, fd_key_compare,
-                         sh_freeentry);
+  return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
+                        sh_freeentry);
 }
 
 /*
@@ -293,16 +289,13 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
 
   multi->type = CURL_MULTI_HANDLE;
 
-  multi->hostcache = Curl_mk_dnscache();
-  if(!multi->hostcache)
+  if(Curl_mk_dnscache(&multi->hostcache))
     goto error;
 
-  multi->sockhash = sh_init(hashsize);
-  if(!multi->sockhash)
+  if(sh_init(&multi->sockhash, hashsize))
     goto error;
 
-  multi->conn_cache = Curl_conncache_init(chashsize);
-  if(!multi->conn_cache)
+  if(Curl_conncache_init(&multi->conn_cache, chashsize))
     goto error;
 
   multi->msglist = Curl_llist_alloc(multi_freeamsg);
@@ -319,7 +312,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
     goto error;
 
   multi->closure_handle->multi = multi;
-  multi->closure_handle->state.conn_cache = multi->conn_cache;
+  multi->closure_handle->state.conn_cache = &multi->conn_cache;
 
   multi->max_pipeline_length = 5;
 
@@ -329,12 +322,9 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
 
   error:
 
-  Curl_hash_destroy(multi->sockhash);
-  multi->sockhash = NULL;
-  Curl_hash_destroy(multi->hostcache);
-  multi->hostcache = NULL;
-  Curl_conncache_destroy(multi->conn_cache);
-  multi->conn_cache = NULL;
+  Curl_hash_destroy(&multi->sockhash);
+  Curl_hash_destroy(&multi->hostcache);
+  Curl_conncache_destroy(&multi->conn_cache);
   Curl_close(multi->closure_handle);
   multi->closure_handle = NULL;
   Curl_llist_destroy(multi->msglist, NULL);
@@ -403,14 +393,12 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
      easy handle's one is currently not set. */
   else if(!data->dns.hostcache ||
      (data->dns.hostcachetype == HCACHE_NONE)) {
-    data->dns.hostcache = multi->hostcache;
+    data->dns.hostcache = &multi->hostcache;
     data->dns.hostcachetype = HCACHE_MULTI;
   }
 
   /* Point to the multi's connection cache */
-  data->state.conn_cache = multi->conn_cache;
-
-  data->state.infilesize = data->set.filesize;
+  data->state.conn_cache = &multi->conn_cache;
 
   /* This adds the new entry at the 'end' of the doubly-linked circular
      list of SessionHandle structs to try and maintain a FIFO queue so
@@ -426,8 +414,7 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
     multi->easylp = data; /* the new last node */
   }
   else {
-    /* first node, make both prev and next be NULL! */
-    data->next = NULL;
+    /* first node, make prev NULL! */
     data->prev = NULL;
     multi->easylp = multi->easyp = data; /* both first and last */
   }
@@ -487,6 +474,9 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
   struct SessionHandle *easy = curl_handle;
   struct SessionHandle *data = easy;
+  bool premature;
+  bool easy_owns_conn;
+  struct curl_llist_element *e;
 
   /* First, make some basic checks that the CURLM handle is a good handle */
   if(!GOOD_MULTI_HANDLE(multi))
@@ -500,131 +490,127 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
   if(!data->multi)
     return CURLM_OK; /* it is already removed so let's say it is fine! */
 
-  if(easy) {
-    bool premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
-    bool easy_owns_conn = (data->easy_conn &&
-                           (data->easy_conn->data == easy)) ?
-                           TRUE : FALSE;
+  premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
+  easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ?
+    TRUE : FALSE;
 
-    /* If the 'state' is not INIT or COMPLETED, we might need to do something
-       nice to put the easy_handle in a good known state when this returns. */
-    if(premature)
-      /* this handle is "alive" so we need to count down the total number of
-         alive connections when this is removed */
-      multi->num_alive--;
+  /* If the 'state' is not INIT or COMPLETED, we might need to do something
+     nice to put the easy_handle in a good known state when this returns. */
+  if(premature) {
+    /* this handle is "alive" so we need to count down the total number of
+       alive connections when this is removed */
+    multi->num_alive--;
 
-    if(data->easy_conn &&
-       (data->easy_conn->send_pipe->size +
-        data->easy_conn->recv_pipe->size > 1) &&
-       data->mstate > CURLM_STATE_WAITDO &&
-       data->mstate < CURLM_STATE_COMPLETED) {
-      /* If the handle is in a pipeline and has started sending off its
-         request but not received its response yet, we need to close
-         connection. */
-      connclose(data->easy_conn, "Removed with partial response");
-      /* Set connection owner so that Curl_done() closes it.
-         We can sefely do this here since connection is killed. */
-      data->easy_conn->data = easy;
-    }
+    /* When this handle gets removed, other handles may be able to get the
+       connection */
+    Curl_multi_process_pending_handles(multi);
+  }
 
-    /* The timer must be shut down before data->multi is set to NULL,
-       else the timenode will remain in the splay tree after
-       curl_easy_cleanup is called. */
-    Curl_expire(data, 0);
+  if(data->easy_conn &&
+     data->mstate > CURLM_STATE_DO &&
+     data->mstate < CURLM_STATE_COMPLETED) {
+    /* If the handle is in a pipeline and has started sending off its
+       request but not received its response yet, we need to close
+       connection. */
+    connclose(data->easy_conn, "Removed with partial response");
+    /* Set connection owner so that Curl_done() closes it.
+       We can safely do this here since connection is killed. */
+    data->easy_conn->data = easy;
+    easy_owns_conn = TRUE;
+  }
 
-    /* destroy the timeout list that is held in the easy handle */
-    if(data->state.timeoutlist) {
-      Curl_llist_destroy(data->state.timeoutlist, NULL);
-      data->state.timeoutlist = NULL;
-    }
+  /* The timer must be shut down before data->multi is set to NULL,
+     else the timenode will remain in the splay tree after
+     curl_easy_cleanup is called. */
+  Curl_expire(data, 0);
 
-    if(data->dns.hostcachetype == HCACHE_MULTI) {
-      /* stop using the multi handle's DNS cache */
-      data->dns.hostcache = NULL;
-      data->dns.hostcachetype = HCACHE_NONE;
-    }
+  /* destroy the timeout list that is held in the easy handle */
+  if(data->state.timeoutlist) {
+    Curl_llist_destroy(data->state.timeoutlist, NULL);
+    data->state.timeoutlist = NULL;
+  }
 
-    if(data->easy_conn) {
+  if(data->dns.hostcachetype == HCACHE_MULTI) {
+    /* stop using the multi handle's DNS cache */
+    data->dns.hostcache = NULL;
+    data->dns.hostcachetype = HCACHE_NONE;
+  }
 
-      /* we must call Curl_done() here (if we still "own it") so that we don't
-         leave a half-baked one around */
-      if(easy_owns_conn) {
+  if(data->easy_conn) {
 
-        /* Curl_done() clears the conn->data field to lose the association
-           between the easy handle and the connection
+    /* we must call Curl_done() here (if we still "own it") so that we don't
+       leave a half-baked one around */
+    if(easy_owns_conn) {
 
-           Note that this ignores the return code simply because there's
-           nothing really useful to do with it anyway! */
-        (void)Curl_done(&data->easy_conn, data->result, premature);
-      }
-      else
-        /* Clear connection pipelines, if Curl_done above was not called */
-        Curl_getoff_all_pipelines(data, data->easy_conn);
+      /* Curl_done() clears the conn->data field to lose the association
+         between the easy handle and the connection
+
+         Note that this ignores the return code simply because there's
+         nothing really useful to do with it anyway! */
+      (void)Curl_done(&data->easy_conn, data->result, premature);
     }
+    else
+      /* Clear connection pipelines, if Curl_done above was not called */
+      Curl_getoff_all_pipelines(data, data->easy_conn);
+  }
 
-    Curl_wildcard_dtor(&data->wildcard);
+  Curl_wildcard_dtor(&data->wildcard);
 
-    /* as this was using a shared connection cache we clear the pointer
-       to that since we're not part of that multi handle anymore */
-    data->state.conn_cache = NULL;
+  /* as this was using a shared connection cache we clear the pointer to that
+     since we're not part of that multi handle anymore */
+  data->state.conn_cache = NULL;
 
-    /* change state without using multistate(), only to make singlesocket() do
-       what we want */
-    data->mstate = CURLM_STATE_COMPLETED;
-    singlesocket(multi, easy); /* to let the application know what sockets
-                                  that vanish with this handle */
+  /* change state without using multistate(), only to make singlesocket() do
+     what we want */
+  data->mstate = CURLM_STATE_COMPLETED;
+  singlesocket(multi, easy); /* to let the application know what sockets that
+                                vanish with this handle */
 
-    /* Remove the association between the connection and the handle */
-    if(data->easy_conn) {
-      data->easy_conn->data = NULL;
-      data->easy_conn = NULL;
-    }
+  /* Remove the association between the connection and the handle */
+  if(data->easy_conn) {
+    data->easy_conn->data = NULL;
+    data->easy_conn = NULL;
+  }
 
-    data->multi = NULL; /* clear the association to this multi handle */
+  data->multi = NULL; /* clear the association to this multi handle */
 
-    {
-      /* make sure there's no pending message in the queue sent from this easy
-         handle */
-      struct curl_llist_element *e;
+  /* make sure there's no pending message in the queue sent from this easy
+     handle */
 
-      for(e = multi->msglist->head; e; e = e->next) {
-        struct Curl_message *msg = e->ptr;
+  for(e = multi->msglist->head; e; e = e->next) {
+    struct Curl_message *msg = e->ptr;
 
-        if(msg->extmsg.easy_handle == easy) {
-          Curl_llist_remove(multi->msglist, e, NULL);
-          /* there can only be one from this specific handle */
-          break;
-        }
-      }
+    if(msg->extmsg.easy_handle == easy) {
+      Curl_llist_remove(multi->msglist, e, NULL);
+      /* there can only be one from this specific handle */
+      break;
     }
+  }
 
-    /* make the previous node point to our next */
-    if(data->prev)
-      data->prev->next = data->next;
-    else
-      multi->easyp = data->next; /* point to first node */
-
-    /* make our next point to our previous node */
-    if(data->next)
-      data->next->prev = data->prev;
-    else
-      multi->easylp = data->prev; /* point to last node */
+  /* make the previous node point to our next */
+  if(data->prev)
+    data->prev->next = data->next;
+  else
+    multi->easyp = data->next; /* point to first node */
 
-    /* NOTE NOTE NOTE
-       We do not touch the easy handle here! */
+  /* make our next point to our previous node */
+  if(data->next)
+    data->next->prev = data->prev;
+  else
+    multi->easylp = data->prev; /* point to last node */
 
-    multi->num_easy--; /* one less to care about now */
+  /* NOTE NOTE NOTE
+     We do not touch the easy handle here! */
+  multi->num_easy--; /* one less to care about now */
 
-    update_timer(multi);
-    return CURLM_OK;
-  }
-  else
-    return CURLM_BAD_EASY_HANDLE; /* twasn't found */
+  update_timer(multi);
+  return CURLM_OK;
 }
 
-bool Curl_multi_pipeline_enabled(const struct Curl_multi *multi)
+/* Return TRUE if the application asked for a certain set of pipelining */
+bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
 {
-  return (multi && multi->pipelining_enabled) ? TRUE : FALSE;
+  return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
 }
 
 void Curl_multi_handlePipeBreak(struct SessionHandle *data)
@@ -650,14 +636,24 @@ static int waitconnect_getsock(struct connectdata *conn,
     }
   }
 
+  return rc;
+}
+
+static int waitproxyconnect_getsock(struct connectdata *conn,
+                                    curl_socket_t *sock,
+                                    int numsocks)
+{
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  sock[0] = conn->sock[FIRSTSOCKET];
+
   /* when we've sent a CONNECT to a proxy, we should rather wait for the
      socket to become readable to be able to get the response headers */
-  if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) {
-    sock[0] = conn->sock[FIRSTSOCKET];
-    rc = GETSOCK_READSOCK(0);
-  }
+  if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
+    return GETSOCK_READSOCK(0);
 
-  return rc;
+  return GETSOCK_WRITESOCK(0);
 }
 
 static int domore_getsock(struct connectdata *conn,
@@ -710,6 +706,7 @@ static int multi_getsock(struct SessionHandle *data,
     return Curl_resolver_getsock(data->easy_conn, socks, numsocks);
 
   case CURLM_STATE_PROTOCONNECT:
+  case CURLM_STATE_SENDPROTOCONNECT:
     return Curl_protocol_getsock(data->easy_conn, socks, numsocks);
 
   case CURLM_STATE_DO:
@@ -717,6 +714,8 @@ static int multi_getsock(struct SessionHandle *data,
     return Curl_doing_getsock(data->easy_conn, socks, numsocks);
 
   case CURLM_STATE_WAITPROXYCONNECT:
+    return waitproxyconnect_getsock(data->easy_conn, socks, numsocks);
+
   case CURLM_STATE_WAITCONNECT:
     return waitconnect_getsock(data->easy_conn, socks, numsocks);
 
@@ -917,12 +916,62 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
   else
     i = 0;
 
-  Curl_safefree(ufds);
+  free(ufds);
   if(ret)
     *ret = i;
   return CURLM_OK;
 }
 
+/*
+ * Curl_multi_connchanged() is called to tell that there is a connection in
+ * this multi handle that has changed state (pipelining become possible, the
+ * number of allowed streams changed or similar), and a subsequent use of this
+ * multi handle should move CONNECT_PEND handles back to CONNECT to have them
+ * retry.
+ */
+void Curl_multi_connchanged(struct Curl_multi *multi)
+{
+  multi->recheckstate = TRUE;
+}
+
+/*
+ * multi_ischanged() is called
+ *
+ * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
+ * => CONNECT action.
+ *
+ * Set 'clear' to TRUE to have it also clear the state variable.
+ */
+static bool multi_ischanged(struct Curl_multi *multi, bool clear)
+{
+  bool retval = multi->recheckstate;
+  if(clear)
+    multi->recheckstate = FALSE;
+  return retval;
+}
+
+CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
+                                 struct SessionHandle *data,
+                                 struct connectdata *conn)
+{
+  CURLMcode rc;
+
+  rc = curl_multi_add_handle(multi, data);
+  if(!rc) {
+    struct SingleRequest *k = &data->req;
+
+    /* pass in NULL for 'conn' here since we don't want to init the
+       connection, only this transfer */
+    Curl_init_do(data, NULL);
+
+    /* take this handle to the perform state right away */
+    multistate(data, CURLM_STATE_PERFORM);
+    data->easy_conn = conn;
+    k->keepon |= KEEP_RECV; /* setup to receive! */
+  }
+  return rc;
+}
+
 static CURLMcode multi_runsingle(struct Curl_multi *multi,
                                  struct timeval now,
                                  struct SessionHandle *data)
@@ -933,7 +982,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
   bool protocol_connect = FALSE;
   bool dophase_done = FALSE;
   bool done = FALSE;
-  CURLMcode result = CURLM_OK;
+  CURLMcode rc;
+  CURLcode result = CURLE_OK;
   struct SingleRequest *k;
   long timeout_ms;
   int control;
@@ -942,26 +992,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
     return CURLM_BAD_EASY_HANDLE;
 
   do {
-    /* this is a single-iteration do-while loop just to allow a
-       break to skip to the end of it */
     bool disconnect_conn = FALSE;
+    rc = CURLM_OK;
 
     /* Handle the case when the pipe breaks, i.e., the connection
        we're using gets cleaned up and we're left with nothing. */
     if(data->state.pipe_broke) {
-      infof(data, "Pipe broke: handle 0x%p, url = %s\n",
+      infof(data, "Pipe broke: handle %p, url = %s\n",
             (void *)data, data->state.path);
 
       if(data->mstate < CURLM_STATE_COMPLETED) {
         /* Head back to the CONNECT state */
         multistate(data, CURLM_STATE_CONNECT);
-        result = CURLM_CALL_MULTI_PERFORM;
-        data->result = CURLE_OK;
+        rc = CURLM_CALL_MULTI_PERFORM;
+        result = CURLE_OK;
       }
 
       data->state.pipe_broke = FALSE;
       data->easy_conn = NULL;
-      break;
+      continue;
     }
 
     if(!data->easy_conn &&
@@ -974,6 +1023,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       return CURLM_INTERNAL_ERROR;
     }
 
+    if(multi_ischanged(multi, TRUE)) {
+      DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
+      Curl_multi_process_pending_handles(multi);
+    }
+
     if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT &&
        data->mstate < CURLM_STATE_COMPLETED)
       /* Make sure we set the connection's current owner */
@@ -1014,26 +1068,28 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
           }
         }
 
-        /* Force the connection closed because the server could continue to
-           send us stuff at any time. (The disconnect_conn logic used below
-           doesn't work at this point). */
-        connclose(data->easy_conn, "Disconnected with pending data");
-        data->result = CURLE_OPERATION_TIMEDOUT;
-        multistate(data, CURLM_STATE_COMPLETED);
-        break;
+        /* Force connection closed if the connection has indeed been used */
+        if(data->mstate > CURLM_STATE_DO) {
+          connclose(data->easy_conn, "Disconnected with pending data");
+          disconnect_conn = TRUE;
+        }
+        result = CURLE_OPERATION_TIMEDOUT;
+        (void)Curl_done(&data->easy_conn, result, TRUE);
+        /* Skip the statemachine and go directly to error handling section. */
+        goto statemachine_end;
       }
     }
 
     switch(data->mstate) {
     case CURLM_STATE_INIT:
       /* init this transfer. */
-      data->result=Curl_pretransfer(data);
+      result=Curl_pretransfer(data);
 
-      if(CURLE_OK == data->result) {
+      if(!result) {
         /* after init, go CONNECT */
         multistate(data, CURLM_STATE_CONNECT);
         Curl_pgrsTime(data, TIMER_STARTOP);
-        result = CURLM_CALL_MULTI_PERFORM;
+        rc = CURLM_CALL_MULTI_PERFORM;
       }
       break;
 
@@ -1045,25 +1101,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
     case CURLM_STATE_CONNECT:
       /* Connect. We want to get a connection identifier filled in. */
       Curl_pgrsTime(data, TIMER_STARTSINGLE);
-      data->result = Curl_connect(data, &data->easy_conn,
-                                  &async, &protocol_connect);
-      if(CURLE_NO_CONNECTION_AVAILABLE == data->result) {
+      result = Curl_connect(data, &data->easy_conn,
+                            &async, &protocol_connect);
+      if(CURLE_NO_CONNECTION_AVAILABLE == result) {
         /* There was no connection available. We will go to the pending
            state and wait for an available connection. */
         multistate(data, CURLM_STATE_CONNECT_PEND);
 
         /* add this handle to the list of connect-pending handles */
         if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
-          data->result = CURLE_OUT_OF_MEMORY;
+          result = CURLE_OUT_OF_MEMORY;
         else
-          data->result = CURLE_OK;
+          result = CURLE_OK;
         break;
       }
 
-      if(CURLE_OK == data->result) {
+      if(!result) {
         /* Add this handle to the send or pend pipeline */
-        data->result = Curl_add_handle_to_pipeline(data, data->easy_conn);
-        if(CURLE_OK != data->result)
+        result = Curl_add_handle_to_pipeline(data, data->easy_conn);
+        if(result)
           disconnect_conn = TRUE;
         else {
           if(async)
@@ -1073,10 +1129,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
             /* after the connect has been sent off, go WAITCONNECT unless the
                protocol connect is already done and we can go directly to
                WAITDO or DO! */
-            result = CURLM_CALL_MULTI_PERFORM;
+            rc = CURLM_CALL_MULTI_PERFORM;
 
             if(protocol_connect)
-              multistate(data, multi->pipelining_enabled?
+              multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
                          CURLM_STATE_WAITDO:CURLM_STATE_DO);
             else {
 #ifndef CURL_DISABLE_HTTP
@@ -1096,31 +1152,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
     {
       struct Curl_dns_entry *dns = NULL;
       struct connectdata *conn = data->easy_conn;
-      int stale;
 
       /* check if we have the name resolved by now */
-      if(data->share)
-        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
-
-      dns = Curl_fetch_addr(conn, conn->host.name, (int)conn->port, &stale);
+      dns = Curl_fetch_addr(conn, conn->host.name, (int)conn->port);
 
       if(dns) {
-        dns->inuse++; /* we use it! */
 #ifdef CURLRES_ASYNCH
         conn->async.dns = dns;
         conn->async.done = TRUE;
 #endif
-        data->result = CURLRESOLV_RESOLVED;
+        result = CURLE_OK;
         infof(data, "Hostname was found in DNS cache\n");
       }
-      if(stale)
-        infof(data, "Hostname in DNS cache was stale, zapped\n");
-
-      if(data->share)
-        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
 
       if(!dns)
-        data->result = Curl_resolver_is_resolved(data->easy_conn, &dns);
+        result = Curl_resolver_is_resolved(data->easy_conn, &dns);
 
       /* Update sockets here, because the socket(s) may have been
          closed and the application thus needs to be told, even if it
@@ -1133,18 +1179,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       if(dns) {
         /* Perform the next step in the connection phase, and then move on
            to the WAITCONNECT state */
-        data->result = Curl_async_resolved(data->easy_conn,
-                                           &protocol_connect);
+        result = Curl_async_resolved(data->easy_conn, &protocol_connect);
 
-        if(CURLE_OK != data->result)
+        if(result)
           /* if Curl_async_resolved() returns failure, the connection struct
              is already freed and gone */
           data->easy_conn = NULL;           /* no more connection */
         else {
           /* call again please so that we get the next socket setup */
-          result = CURLM_CALL_MULTI_PERFORM;
+          rc = CURLM_CALL_MULTI_PERFORM;
           if(protocol_connect)
-            multistate(data, multi->pipelining_enabled?
+            multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
                        CURLM_STATE_WAITDO:CURLM_STATE_DO);
           else {
 #ifndef CURL_DISABLE_HTTP
@@ -1157,7 +1202,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         }
       }
 
-      if(CURLE_OK != data->result) {
+      if(result) {
         /* failure detected */
         disconnect_conn = TRUE;
         break;
@@ -1168,109 +1213,82 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
 #ifndef CURL_DISABLE_HTTP
     case CURLM_STATE_WAITPROXYCONNECT:
       /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
-      data->result = Curl_http_connect(data->easy_conn, &protocol_connect);
+      result = Curl_http_connect(data->easy_conn, &protocol_connect);
 
+      rc = CURLM_CALL_MULTI_PERFORM;
       if(data->easy_conn->bits.proxy_connect_closed) {
         /* connect back to proxy again */
-        data->result = CURLE_OK;
-        result = CURLM_CALL_MULTI_PERFORM;
+        result = CURLE_OK;
+        Curl_done(&data->easy_conn, CURLE_OK, FALSE);
         multistate(data, CURLM_STATE_CONNECT);
       }
-      else if(CURLE_OK == data->result) {
+      else if(!result) {
         if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE)
-          multistate(data, CURLM_STATE_WAITCONNECT);
+          /* initiate protocol connect phase */
+          multistate(data, CURLM_STATE_SENDPROTOCONNECT);
       }
       break;
 #endif
 
     case CURLM_STATE_WAITCONNECT:
-      /* awaiting a completion of an asynch connect */
-      data->result = Curl_is_connected(data->easy_conn,
-                                       FIRSTSOCKET,
-                                       &connected);
-      if(connected) {
-
-        if(!data->result)
-          /* if everything is still fine we do the protocol-specific connect
-             setup */
-          data->result = Curl_protocol_connect(data->easy_conn,
-                                               &protocol_connect);
-      }
-
-      if(data->easy_conn->bits.proxy_connect_closed) {
-        /* connect back to proxy again since it was closed in a proxy CONNECT
-           setup */
-        data->result = CURLE_OK;
-        result = CURLM_CALL_MULTI_PERFORM;
-        multistate(data, CURLM_STATE_CONNECT);
-        break;
+      /* awaiting a completion of an asynch TCP connect */
+      result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
+      if(connected && !result) {
+        rc = CURLM_CALL_MULTI_PERFORM;
+        multistate(data, data->easy_conn->bits.tunnel_proxy?
+                   CURLM_STATE_WAITPROXYCONNECT:
+                   CURLM_STATE_SENDPROTOCONNECT);
       }
-      else if(CURLE_OK != data->result) {
+      else if(result) {
         /* failure detected */
         /* Just break, the cleaning up is handled all in one place */
         disconnect_conn = TRUE;
         break;
       }
+      break;
 
-      if(connected) {
-        if(!protocol_connect) {
-          /* We have a TCP connection, but 'protocol_connect' may be false
-             and then we continue to 'STATE_PROTOCONNECT'. If protocol
-             connect is TRUE, we move on to STATE_DO.
-             BUT if we are using a proxy we must change to WAITPROXYCONNECT
-          */
-#ifndef CURL_DISABLE_HTTP
-          if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
-            multistate(data, CURLM_STATE_WAITPROXYCONNECT);
-          else
-#endif
-            multistate(data, CURLM_STATE_PROTOCONNECT);
-
-        }
-        else
-          /* after the connect has completed, go WAITDO or DO */
-          multistate(data, multi->pipelining_enabled?
-                     CURLM_STATE_WAITDO:CURLM_STATE_DO);
-
-        result = CURLM_CALL_MULTI_PERFORM;
+    case CURLM_STATE_SENDPROTOCONNECT:
+      result = Curl_protocol_connect(data->easy_conn, &protocol_connect);
+      if(!protocol_connect)
+        /* switch to waiting state */
+        multistate(data, CURLM_STATE_PROTOCONNECT);
+      else if(!result) {
+        /* protocol connect has completed, go WAITDO or DO */
+        multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+                   CURLM_STATE_WAITDO:CURLM_STATE_DO);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      else if(result) {
+        /* failure detected */
+        Curl_posttransfer(data);
+        Curl_done(&data->easy_conn, result, TRUE);
+        disconnect_conn = TRUE;
       }
       break;
 
     case CURLM_STATE_PROTOCONNECT:
       /* protocol-specific connect phase */
-      data->result = Curl_protocol_connecting(data->easy_conn,
-                                              &protocol_connect);
-      if((data->result == CURLE_OK) && protocol_connect) {
+      result = Curl_protocol_connecting(data->easy_conn, &protocol_connect);
+      if(!result && protocol_connect) {
         /* after the connect has completed, go WAITDO or DO */
-        multistate(data, multi->pipelining_enabled?
+        multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
                    CURLM_STATE_WAITDO:CURLM_STATE_DO);
-        result = CURLM_CALL_MULTI_PERFORM;
+        rc = CURLM_CALL_MULTI_PERFORM;
       }
-      else if(data->result) {
+      else if(result) {
         /* failure detected */
         Curl_posttransfer(data);
-        Curl_done(&data->easy_conn, data->result, TRUE);
+        Curl_done(&data->easy_conn, result, TRUE);
         disconnect_conn = TRUE;
       }
       break;
 
     case CURLM_STATE_WAITDO:
       /* Wait for our turn to DO when we're pipelining requests */
-#ifdef DEBUGBUILD
-      infof(data, "WAITDO: Conn %ld send pipe %zu inuse %s athead %s\n",
-            data->easy_conn->connection_id,
-            data->easy_conn->send_pipe->size,
-            data->easy_conn->writechannel_inuse?"TRUE":"FALSE",
-            isHandleAtHead(data,
-                           data->easy_conn->send_pipe)?"TRUE":"FALSE");
-#endif
-      if(!data->easy_conn->writechannel_inuse &&
-         isHandleAtHead(data,
-                        data->easy_conn->send_pipe)) {
-        /* Grab the channel */
-        data->easy_conn->writechannel_inuse = TRUE;
+      if(Curl_pipeline_checkget_write(data, data->easy_conn)) {
+        /* Grabbed the channel */
         multistate(data, CURLM_STATE_DO);
-        result = CURLM_CALL_MULTI_PERFORM;
+        rc = CURLM_CALL_MULTI_PERFORM;
       }
       break;
 
@@ -1279,16 +1297,16 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         /* keep connection open for application to use the socket */
         connkeep(data->easy_conn, "CONNECT_ONLY");
         multistate(data, CURLM_STATE_DONE);
-        data->result = CURLE_OK;
-        result = CURLM_CALL_MULTI_PERFORM;
+        result = CURLE_OK;
+        rc = CURLM_CALL_MULTI_PERFORM;
       }
       else {
         /* Perform the protocol's DO action */
-        data->result = Curl_do(&data->easy_conn, &dophase_done);
+        result = Curl_do(&data->easy_conn, &dophase_done);
 
         /* When Curl_do() returns failure, data->easy_conn might be NULL! */
 
-        if(CURLE_OK == data->result) {
+        if(!result) {
           if(!dophase_done) {
             /* some steps needed for wildcard matching */
             if(data->set.wildcardmatch) {
@@ -1297,14 +1315,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
                 /* skip some states if it is important */
                 Curl_done(&data->easy_conn, CURLE_OK, FALSE);
                 multistate(data, CURLM_STATE_DONE);
-                result = CURLM_CALL_MULTI_PERFORM;
+                rc = CURLM_CALL_MULTI_PERFORM;
                 break;
               }
             }
             /* DO was not completed in one function call, we must continue
                DOING... */
             multistate(data, CURLM_STATE_DOING);
-            result = CURLM_OK;
+            rc = CURLM_OK;
           }
 
           /* after DO, go DO_DONE... or DO_MORE */
@@ -1312,15 +1330,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
             /* we're supposed to do more, but we need to sit down, relax
                and wait a little while first */
             multistate(data, CURLM_STATE_DO_MORE);
-            result = CURLM_OK;
+            rc = CURLM_OK;
           }
           else {
             /* we're done with the DO, now DO_DONE */
             multistate(data, CURLM_STATE_DO_DONE);
-            result = CURLM_CALL_MULTI_PERFORM;
+            rc = CURLM_CALL_MULTI_PERFORM;
           }
         }
-        else if((CURLE_SEND_ERROR == data->result) &&
+        else if((CURLE_SEND_ERROR == result) &&
                 data->easy_conn->bits.reuse) {
           /*
            * In this situation, a connection that we were trying to use
@@ -1335,48 +1353,49 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
           drc = Curl_retry_request(data->easy_conn, &newurl);
           if(drc) {
             /* a failure here pretty much implies an out of memory */
-            data->result = drc;
+            result = drc;
             disconnect_conn = TRUE;
           }
           else
             retry = (newurl)?TRUE:FALSE;
 
           Curl_posttransfer(data);
-          drc = Curl_done(&data->easy_conn, data->result, FALSE);
+          drc = Curl_done(&data->easy_conn, result, FALSE);
 
           /* When set to retry the connection, we must to go back to
            * the CONNECT state */
           if(retry) {
-            if((drc == CURLE_OK) || (drc == CURLE_SEND_ERROR)) {
+            if(!drc || (drc == CURLE_SEND_ERROR)) {
               follow = FOLLOW_RETRY;
               drc = Curl_follow(data, newurl, follow);
-              if(drc == CURLE_OK) {
+              if(!drc) {
                 multistate(data, CURLM_STATE_CONNECT);
-                result = CURLM_CALL_MULTI_PERFORM;
-                data->result = CURLE_OK;
+                rc = CURLM_CALL_MULTI_PERFORM;
+                result = CURLE_OK;
               }
               else {
                 /* Follow failed */
-                data->result = drc;
+                result = drc;
                 free(newurl);
               }
             }
             else {
               /* done didn't return OK or SEND_ERROR */
-              data->result = drc;
+              result = drc;
               free(newurl);
             }
           }
           else {
             /* Have error handler disconnect conn if we can't retry */
             disconnect_conn = TRUE;
+            free(newurl);
           }
         }
         else {
           /* failure detected */
           Curl_posttransfer(data);
           if(data->easy_conn)
-            Curl_done(&data->easy_conn, data->result, FALSE);
+            Curl_done(&data->easy_conn, result, FALSE);
           disconnect_conn = TRUE;
         }
       }
@@ -1384,21 +1403,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
 
     case CURLM_STATE_DOING:
       /* we continue DOING until the DO phase is complete */
-      data->result = Curl_protocol_doing(data->easy_conn,
-                                         &dophase_done);
-      if(CURLE_OK == data->result) {
+      result = Curl_protocol_doing(data->easy_conn,
+                                   &dophase_done);
+      if(!result) {
         if(dophase_done) {
           /* after DO, go DO_DONE or DO_MORE */
           multistate(data, data->easy_conn->bits.do_more?
                      CURLM_STATE_DO_MORE:
                      CURLM_STATE_DO_DONE);
-          result = CURLM_CALL_MULTI_PERFORM;
+          rc = CURLM_CALL_MULTI_PERFORM;
         } /* dophase_done */
       }
       else {
         /* failure detected */
         Curl_posttransfer(data);
-        Curl_done(&data->easy_conn, data->result, FALSE);
+        Curl_done(&data->easy_conn, result, FALSE);
         disconnect_conn = TRUE;
       }
       break;
@@ -1407,27 +1426,27 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       /*
        * When we are connected, DO MORE and then go DO_DONE
        */
-      data->result = Curl_do_more(data->easy_conn, &control);
+      result = Curl_do_more(data->easy_conn, &control);
 
       /* No need to remove this handle from the send pipeline here since that
          is done in Curl_done() */
-      if(CURLE_OK == data->result) {
+      if(!result) {
         if(control) {
           /* if positive, advance to DO_DONE
              if negative, go back to DOING */
           multistate(data, control==1?
                      CURLM_STATE_DO_DONE:
                      CURLM_STATE_DOING);
-          result = CURLM_CALL_MULTI_PERFORM;
+          rc = CURLM_CALL_MULTI_PERFORM;
         }
         else
           /* stay in DO_MORE */
-          result = CURLM_OK;
+          rc = CURLM_OK;
       }
       else {
         /* failure detected */
         Curl_posttransfer(data);
-        Curl_done(&data->easy_conn, data->result, FALSE);
+        Curl_done(&data->easy_conn, result, FALSE);
         disconnect_conn = TRUE;
       }
       break;
@@ -1445,37 +1464,24 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         multistate(data, CURLM_STATE_WAITPERFORM);
       else
         multistate(data, CURLM_STATE_DONE);
-      result = CURLM_CALL_MULTI_PERFORM;
+      rc = CURLM_CALL_MULTI_PERFORM;
       break;
 
     case CURLM_STATE_WAITPERFORM:
       /* Wait for our turn to PERFORM */
-      if(!data->easy_conn->readchannel_inuse &&
-         isHandleAtHead(data,
-                        data->easy_conn->recv_pipe)) {
-        /* Grab the channel */
-        data->easy_conn->readchannel_inuse = TRUE;
+      if(Curl_pipeline_checkget_read(data, data->easy_conn)) {
+        /* Grabbed the channel */
         multistate(data, CURLM_STATE_PERFORM);
-        result = CURLM_CALL_MULTI_PERFORM;
+        rc = CURLM_CALL_MULTI_PERFORM;
       }
-#ifdef DEBUGBUILD
-      else {
-        infof(data, "WAITPERFORM: Conn %ld recv pipe %zu inuse %s athead %s\n",
-              data->easy_conn->connection_id,
-              data->easy_conn->recv_pipe->size,
-              data->easy_conn->readchannel_inuse?"TRUE":"FALSE",
-              isHandleAtHead(data,
-                             data->easy_conn->recv_pipe)?"TRUE":"FALSE");
-      }
-#endif
       break;
 
     case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
       /* if both rates are within spec, resume transfer */
       if(Curl_pgrsUpdate(data->easy_conn))
-        data->result = CURLE_ABORTED_BY_CALLBACK;
+        result = CURLE_ABORTED_BY_CALLBACK;
       else
-        data->result = Curl_speedcheck(data, now);
+        result = Curl_speedcheck(data, now);
 
       if(( (data->set.max_send_speed == 0) ||
            (data->progress.ulspeed < data->set.max_send_speed ))  &&
@@ -1485,7 +1491,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       break;
 
     case CURLM_STATE_PERFORM:
-      {
+    {
       char *newurl = NULL;
       bool retry = FALSE;
 
@@ -1512,7 +1518,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
 
         multistate(data, CURLM_STATE_TOOFAST);
 
-         /* Calculate download rate-limitation timeout. */
+        /* Calculate download rate-limitation timeout. */
         buffersize = (int)(data->set.buffer_size ?
                            data->set.buffer_size : BUFSIZE);
         timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
@@ -1522,21 +1528,19 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       }
 
       /* read/write data if it is ready to do so */
-      data->result = Curl_readwrite(data->easy_conn, &done);
+      result = Curl_readwrite(data->easy_conn, data, &done);
 
       k = &data->req;
 
-      if(!(k->keepon & KEEP_RECV)) {
+      if(!(k->keepon & KEEP_RECV))
         /* We're done receiving */
-        data->easy_conn->readchannel_inuse = FALSE;
-      }
+        Curl_pipeline_leave_read(data->easy_conn);
 
-      if(!(k->keepon & KEEP_SEND)) {
+      if(!(k->keepon & KEEP_SEND))
         /* We're done sending */
-        data->easy_conn->writechannel_inuse = FALSE;
-      }
+        Curl_pipeline_leave_write(data->easy_conn);
 
-      if(done || (data->result == CURLE_RECV_ERROR)) {
+      if(done || (result == CURLE_RECV_ERROR)) {
         /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
          * condition and the server closed the re-used connection exactly when
          * we wanted to use it, so figure out if that is indeed the case.
@@ -1548,12 +1552,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         if(retry) {
           /* if we are to retry, set the result to OK and consider the
              request as done */
-          data->result = CURLE_OK;
+          result = CURLE_OK;
           done = TRUE;
         }
       }
 
-      if(data->result) {
+      if(result) {
         /*
          * The transfer phase returned error, we mark the connection to get
          * closed to prevent being re-used. This is because we can't possibly
@@ -1566,7 +1570,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
           connclose(data->easy_conn, "Transfer returned error");
 
         Curl_posttransfer(data);
-        Curl_done(&data->easy_conn, data->result, FALSE);
+        Curl_done(&data->easy_conn, result, FALSE);
       }
       else if(done) {
         followtype follow=FOLLOW_NONE;
@@ -1590,18 +1594,19 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
           if(!retry) {
             /* if the URL is a follow-location and not just a retried request
                then figure out the URL here */
+            free(newurl);
             newurl = data->req.newurl;
             data->req.newurl = NULL;
             follow = FOLLOW_REDIR;
           }
           else
             follow = FOLLOW_RETRY;
-          data->result = Curl_done(&data->easy_conn, CURLE_OK, FALSE);
-          if(CURLE_OK == data->result) {
-            data->result = Curl_follow(data, newurl, follow);
-            if(CURLE_OK == data->result) {
+          result = Curl_done(&data->easy_conn, CURLE_OK, FALSE);
+          if(!result) {
+            result = Curl_follow(data, newurl, follow);
+            if(!result) {
               multistate(data, CURLM_STATE_CONNECT);
-              result = CURLM_CALL_MULTI_PERFORM;
+              rc = CURLM_CALL_MULTI_PERFORM;
               newurl = NULL; /* handed over the memory ownership to
                                 Curl_follow(), make sure we don't free() it
                                 here */
@@ -1614,30 +1619,28 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
           /* but first check to see if we got a location info even though we're
              not following redirects */
           if(data->req.location) {
-            if(newurl)
-              free(newurl);
+            free(newurl);
             newurl = data->req.location;
             data->req.location = NULL;
-            data->result = Curl_follow(data, newurl, FOLLOW_FAKE);
-            if(CURLE_OK == data->result)
+            result = Curl_follow(data, newurl, FOLLOW_FAKE);
+            if(!result)
               newurl = NULL; /* allocation was handed over Curl_follow() */
             else
               disconnect_conn = TRUE;
           }
 
           multistate(data, CURLM_STATE_DONE);
-          result = CURLM_CALL_MULTI_PERFORM;
+          rc = CURLM_CALL_MULTI_PERFORM;
         }
       }
 
-      if(newurl)
-        free(newurl);
+      free(newurl);
       break;
-      }
+    }
 
     case CURLM_STATE_DONE:
       /* this state is highly transient, so run another loop after this */
-      result = CURLM_CALL_MULTI_PERFORM;
+      rc = CURLM_CALL_MULTI_PERFORM;
 
       if(data->easy_conn) {
         CURLcode res;
@@ -1648,11 +1651,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         Curl_multi_process_pending_handles(multi);
 
         /* post-transfer command */
-        res = Curl_done(&data->easy_conn, data->result, FALSE);
+        res = Curl_done(&data->easy_conn, result, FALSE);
 
         /* allow a previously set error code take precedence */
-        if(!data->result)
-          data->result = res;
+        if(!result)
+          result = res;
 
         /*
          * If there are other handles on the pipeline, Curl_done won't set
@@ -1692,14 +1695,16 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       break;
 
     case CURLM_STATE_MSGSENT:
+      data->result = result;
       return CURLM_OK; /* do nothing */
 
     default:
       return CURLM_INTERNAL_ERROR;
     }
+    statemachine_end:
 
     if(data->mstate < CURLM_STATE_COMPLETED) {
-      if(CURLE_OK != data->result) {
+      if(result) {
         /*
          * If an error was returned, and we aren't in completed state now,
          * then we go to completed and consider this transfer aborted.
@@ -1710,20 +1715,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
 
         data->state.pipe_broke = FALSE;
 
+        /* Check if we can move pending requests to send pipe */
+        Curl_multi_process_pending_handles(multi);
+
         if(data->easy_conn) {
           /* if this has a connection, unsubscribe from the pipelines */
-          data->easy_conn->writechannel_inuse = FALSE;
-          data->easy_conn->readchannel_inuse = FALSE;
-          Curl_removeHandleFromPipeline(data,
-                                        data->easy_conn->send_pipe);
-          Curl_removeHandleFromPipeline(data,
-                                        data->easy_conn->recv_pipe);
-          /* Check if we can move pending requests to send pipe */
-          Curl_multi_process_pending_handles(multi);
+          Curl_pipeline_leave_write(data->easy_conn);
+          Curl_pipeline_leave_read(data->easy_conn);
+          Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
+          Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
 
           if(disconnect_conn) {
+            /* Don't attempt to send data over a connection that timed out */
+            bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
             /* disconnect properly */
-            Curl_disconnect(data->easy_conn, /* dead_connection */ FALSE);
+            Curl_disconnect(data->easy_conn, dead_connection);
 
             /* This is where we make sure that the easy_conn pointer is reset.
                We don't have to do this in every case block above where a
@@ -1742,31 +1748,34 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
         /* aborted due to progress callback return code must close the
            connection */
-        data->result = CURLE_ABORTED_BY_CALLBACK;
+        result = CURLE_ABORTED_BY_CALLBACK;
         connclose(data->easy_conn, "Aborted by callback");
 
         /* if not yet in DONE state, go there, otherwise COMPLETED */
         multistate(data, (data->mstate < CURLM_STATE_DONE)?
                    CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
-        result = CURLM_CALL_MULTI_PERFORM;
+        rc = CURLM_CALL_MULTI_PERFORM;
       }
     }
-  } WHILE_FALSE; /* just to break out from! */
 
-  if(CURLM_STATE_COMPLETED == data->mstate) {
-    /* now fill in the Curl_message with this info */
-    msg = &data->msg;
+    if(CURLM_STATE_COMPLETED == data->mstate) {
+      /* now fill in the Curl_message with this info */
+      msg = &data->msg;
 
-    msg->extmsg.msg = CURLMSG_DONE;
-    msg->extmsg.easy_handle = data;
-    msg->extmsg.data.result = data->result;
+      msg->extmsg.msg = CURLMSG_DONE;
+      msg->extmsg.easy_handle = data;
+      msg->extmsg.data.result = result;
 
-    result = multi_addmsg(multi, msg);
+      rc = multi_addmsg(multi, msg);
 
-    multistate(data, CURLM_STATE_MSGSENT);
-  }
+      multistate(data, CURLM_STATE_MSGSENT);
+    }
+  } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
 
-  return result;
+  data->result = result;
+
+
+  return rc;
 }
 
 
@@ -1796,9 +1805,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
     }
 
     sigpipe_ignore(data, &pipe_st);
-    do
-      result = multi_runsingle(multi, now, data);
-    while(CURLM_CALL_MULTI_PERFORM == result);
+    result = multi_runsingle(multi, now, data);
     sigpipe_restore(&pipe_st);
 
     if(data->set.wildcardmatch) {
@@ -1843,7 +1850,7 @@ static void close_all_connections(struct Curl_multi *multi)
 {
   struct connectdata *conn;
 
-  conn = Curl_conncache_find_first_connection(multi->conn_cache);
+  conn = Curl_conncache_find_first_connection(&multi->conn_cache);
   while(conn) {
     SIGPIPE_VARIABLE(pipe_st);
     conn->data = multi->closure_handle;
@@ -1853,7 +1860,7 @@ static void close_all_connections(struct Curl_multi *multi)
     (void)Curl_disconnect(conn, FALSE);
     sigpipe_restore(&pipe_st);
 
-    conn = Curl_conncache_find_first_connection(multi->conn_cache);
+    conn = Curl_conncache_find_first_connection(&multi->conn_cache);
   }
 }
 
@@ -1876,15 +1883,15 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
       sigpipe_ignore(multi->closure_handle, &pipe_st);
       restore_pipe = TRUE;
 
-      multi->closure_handle->dns.hostcache = multi->hostcache;
+      multi->closure_handle->dns.hostcache = &multi->hostcache;
       Curl_hostcache_clean(multi->closure_handle,
                            multi->closure_handle->dns.hostcache);
 
       Curl_close(multi->closure_handle);
     }
 
-    Curl_hash_destroy(multi->sockhash);
-    Curl_conncache_destroy(multi->conn_cache);
+    Curl_hash_destroy(&multi->sockhash);
+    Curl_conncache_destroy(&multi->conn_cache);
     Curl_llist_destroy(multi->msglist, NULL);
     Curl_llist_destroy(multi->pending, NULL);
 
@@ -1906,7 +1913,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
       data = nextdata;
     }
 
-    Curl_hash_destroy(multi->hostcache);
+    Curl_hash_destroy(&multi->hostcache);
 
     /* Free the blacklists by setting them to NULL */
     Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
@@ -1995,7 +2002,7 @@ static void singlesocket(struct Curl_multi *multi,
     s = socks[i];
 
     /* get it from the hash */
-    entry = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
+    entry = Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
 
     if(curraction & GETSOCK_READSOCK(i))
       action |= CURL_POLL_IN;
@@ -2010,7 +2017,7 @@ static void singlesocket(struct Curl_multi *multi,
     }
     else {
       /* this is a socket we didn't have before, add it! */
-      entry = sh_addentry(multi->sockhash, s, data);
+      entry = sh_addentry(&multi->sockhash, s, data);
       if(!entry)
         /* fatal */
         return;
@@ -2046,7 +2053,7 @@ static void singlesocket(struct Curl_multi *multi,
       /* this socket has been removed. Tell the app to remove it */
       remove_sock_from_hash = TRUE;
 
-      entry = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
+      entry = Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
       if(entry) {
         /* check if the socket to be removed serves a connection which has
            other easy-s in a pipeline. In this case the socket should not be
@@ -2061,7 +2068,7 @@ static void singlesocket(struct Curl_multi *multi,
                for the recv_pipe, or the first (in case this particular easy
                isn't already) */
             if(entry->easy == data) {
-              if(isHandleAtHead(data, easy_conn->recv_pipe))
+              if(Curl_recvpipe_head(data, easy_conn))
                 entry->easy = easy_conn->recv_pipe->head->next->ptr;
               else
                 entry->easy = easy_conn->recv_pipe->head->ptr;
@@ -2075,7 +2082,7 @@ static void singlesocket(struct Curl_multi *multi,
                for the send_pipe, or the first (in case this particular easy
                isn't already) */
             if(entry->easy == data) {
-              if(isHandleAtHead(data, easy_conn->send_pipe))
+              if(Curl_sendpipe_head(data, easy_conn))
                 entry->easy = easy_conn->send_pipe->head->next->ptr;
               else
                 entry->easy = easy_conn->send_pipe->head->ptr;
@@ -2101,7 +2108,7 @@ static void singlesocket(struct Curl_multi *multi,
                            CURL_POLL_REMOVE,
                            multi->socket_userp,
                            entry->socketp);
-        sh_delentry(multi->sockhash, s);
+        sh_delentry(&multi->sockhash, s);
       }
 
     }
@@ -2115,7 +2122,7 @@ static void singlesocket(struct Curl_multi *multi,
  * Curl_multi_closed()
  *
  * Used by the connect code to tell the multi_socket code that one of the
- * sockets we were using have just been closed.  This function will then
+ * sockets we were using is about to be closed.  This function will then
  * remove it from the sockethash for this handle to make the multi_socket API
  * behave properly, especially for the case when libcurl will create another
  * socket again and it gets the same file descriptor number.
@@ -2128,7 +2135,7 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
     /* this is set if this connection is part of a handle that is added to
        a multi handle, and only then this is necessary */
     struct Curl_sh_entry *entry =
-      Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
+      Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
 
     if(entry) {
       if(multi->socket_cb)
@@ -2137,7 +2144,7 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
                          entry->socketp);
 
       /* now remove it from the socket hash */
-      sh_delentry(multi->sockhash, s);
+      sh_delentry(&multi->sockhash, s);
     }
   }
 }
@@ -2230,7 +2237,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
   else if(s != CURL_SOCKET_TIMEOUT) {
 
     struct Curl_sh_entry *entry =
-      Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
+      Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
 
     if(!entry)
       /* Unmatched socket, we can't act on it but we ignore this fact.  In
@@ -2268,9 +2275,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
         data->easy_conn->cselect_bits = ev_bitmask;
 
       sigpipe_ignore(data, &pipe_st);
-      do
-        result = multi_runsingle(multi, now, data);
-      while(CURLM_CALL_MULTI_PERFORM == result);
+      result = multi_runsingle(multi, now, data);
       sigpipe_restore(&pipe_st);
 
       if(data->easy_conn &&
@@ -2312,9 +2317,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
       SIGPIPE_VARIABLE(pipe_st);
 
       sigpipe_ignore(data, &pipe_st);
-      do
-        result = multi_runsingle(multi, now, data);
-      while(CURLM_CALL_MULTI_PERFORM == result);
+      result = multi_runsingle(multi, now, data);
       sigpipe_restore(&pipe_st);
 
       if(CURLM_OK >= result)
@@ -2358,8 +2361,14 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle,
   case CURLMOPT_SOCKETDATA:
     multi->socket_userp = va_arg(param, void *);
     break;
+  case CURLMOPT_PUSHFUNCTION:
+    multi->push_cb = va_arg(param, curl_push_callback);
+    break;
+  case CURLMOPT_PUSHDATA:
+    multi->push_userp = va_arg(param, void *);
+    break;
   case CURLMOPT_PIPELINING:
-    multi->pipelining_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    multi->pipelining = va_arg(param, long);
     break;
   case CURLMOPT_TIMERFUNCTION:
     multi->timer_cb = va_arg(param, curl_multi_timer_callback);
@@ -2437,7 +2446,7 @@ CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
 static CURLMcode multi_timeout(struct Curl_multi *multi,
                                long *timeout_ms)
 {
-  static struct timeval tv_zero = {0,0};
+  static struct timeval tv_zero = {0, 0};
 
   if(multi->timetree) {
     /* we have a tree of expire times */
@@ -2495,7 +2504,7 @@ static int update_timer(struct Curl_multi *multi)
     return -1;
   }
   if(timeout_ms < 0) {
-    static const struct timeval none={0,0};
+    static const struct timeval none={0, 0};
     if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
       multi->timer_lastcall = none;
       /* there's no timeout now but there was one previously, tell the app to
@@ -2517,22 +2526,6 @@ static int update_timer(struct Curl_multi *multi)
   return multi->timer_cb((CURLM*)multi, timeout_ms, multi->timer_userp);
 }
 
-void Curl_multi_set_easy_connection(struct SessionHandle *handle,
-                                    struct connectdata *conn)
-{
-  handle->easy_conn = conn;
-}
-
-static bool isHandleAtHead(struct SessionHandle *handle,
-                           struct curl_llist *pipeline)
-{
-  struct curl_llist_element *curr = pipeline->head;
-  if(curr)
-    return (curr->ptr == handle) ? TRUE : FALSE;
-
-  return FALSE;
-}
-
 /*
  * multi_freetimeout()
  *
@@ -2698,24 +2691,24 @@ void Curl_expire(struct SessionHandle *data, long milli)
  */
 void Curl_expire_latest(struct SessionHandle *data, long milli)
 {
-  struct timeval *exp = &data->state.expiretime;
+  struct timeval *expire = &data->state.expiretime;
 
   struct timeval set;
 
   set = Curl_tvnow();
-  set.tv_sec += milli/1000;
-  set.tv_usec += (milli%1000)*1000;
+  set.tv_sec += milli / 1000;
+  set.tv_usec += (milli % 1000) * 1000;
 
   if(set.tv_usec >= 1000000) {
     set.tv_sec++;
     set.tv_usec -= 1000000;
   }
 
-  if(exp->tv_sec || exp->tv_usec) {
+  if(expire->tv_sec || expire->tv_usec) {
     /* This means that the struct is added as a node in the splay tree.
        Compare if the new time is earlier, and only remove-old/add-new if it
          is. */
-    long diff = curlx_tvdiff(set, *exp);
+    long diff = curlx_tvdiff(set, *expire);
     if(diff > 0)
       /* the new expire time was later than the top time, so just skip this */
       return;
@@ -2732,7 +2725,8 @@ CURLMcode curl_multi_assign(CURLM *multi_handle,
   struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
 
   if(s != CURL_SOCKET_BAD)
-    there = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(curl_socket_t));
+    there = Curl_hash_pick(&multi->sockhash, (char *)&s,
+                           sizeof(curl_socket_t));
 
   if(!there)
     return CURLM_BAD_SOCKET;
@@ -2752,11 +2746,6 @@ size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
   return multi ? multi->max_total_connections : 0;
 }
 
-size_t Curl_multi_max_pipeline_length(struct Curl_multi *multi)
-{
-  return multi ? multi->max_pipeline_length : 0;
-}
-
 curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi)
 {
   return multi ? multi->content_length_penalty_size : 0;
@@ -2816,7 +2805,7 @@ void Curl_multi_dump(const struct Curl_multi *multi_handle)
       for(i=0; i < data->numsocks; i++) {
         curl_socket_t s = data->sockets[i];
         struct Curl_sh_entry *entry =
-          Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
+          Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
 
         fprintf(stderr, "%d ", (int)s);
         if(!entry) {
diff --git a/Utilities/cmcurl/lib/multihandle.h b/Utilities/cmcurl/lib/multihandle.h
index 1a4b1d9..6c24f50 100644
--- a/Utilities/cmcurl/lib/multihandle.h
+++ b/Utilities/cmcurl/lib/multihandle.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,6 +22,8 @@
  *
  ***************************************************************************/
 
+#include "conncache.h"
+
 struct Curl_message {
   /* the 'CURLMsg' is the part that is visible to the external user */
   struct CURLMsg extmsg;
@@ -35,22 +37,23 @@ typedef enum {
   CURLM_STATE_CONNECT_PEND, /* 1 - no connections, waiting for one */
   CURLM_STATE_CONNECT,      /* 2 - resolve/connect has been sent off */
   CURLM_STATE_WAITRESOLVE,  /* 3 - awaiting the resolve to finalize */
-  CURLM_STATE_WAITCONNECT,  /* 4 - awaiting the connect to finalize */
+  CURLM_STATE_WAITCONNECT,  /* 4 - awaiting the TCP connect to finalize */
   CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting proxy CONNECT to finalize */
-  CURLM_STATE_PROTOCONNECT, /* 6 - completing the protocol-specific connect
+  CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */
+  CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect
                                    phase */
-  CURLM_STATE_WAITDO,       /* 7 - wait for our turn to send the request */
-  CURLM_STATE_DO,           /* 8 - start send off the request (part 1) */
-  CURLM_STATE_DOING,        /* 9 - sending off the request (part 1) */
-  CURLM_STATE_DO_MORE,      /* 10 - send off the request (part 2) */
-  CURLM_STATE_DO_DONE,      /* 11 - done sending off request */
-  CURLM_STATE_WAITPERFORM,  /* 12 - wait for our turn to read the response */
-  CURLM_STATE_PERFORM,      /* 13 - transfer data */
-  CURLM_STATE_TOOFAST,      /* 14 - wait because limit-rate exceeded */
-  CURLM_STATE_DONE,         /* 15 - post data transfer operation */
-  CURLM_STATE_COMPLETED,    /* 16 - operation complete */
-  CURLM_STATE_MSGSENT,      /* 17 - the operation complete message is sent */
-  CURLM_STATE_LAST          /* 18 - not a true state, never use this */
+  CURLM_STATE_WAITDO,       /* 8 - wait for our turn to send the request */
+  CURLM_STATE_DO,           /* 9 - start send off the request (part 1) */
+  CURLM_STATE_DOING,        /* 10 - sending off the request (part 1) */
+  CURLM_STATE_DO_MORE,      /* 11 - send off the request (part 2) */
+  CURLM_STATE_DO_DONE,      /* 12 - done sending off request */
+  CURLM_STATE_WAITPERFORM,  /* 13 - wait for our turn to read the response */
+  CURLM_STATE_PERFORM,      /* 14 - transfer data */
+  CURLM_STATE_TOOFAST,      /* 15 - wait because limit-rate exceeded */
+  CURLM_STATE_DONE,         /* 16 - post data transfer operation */
+  CURLM_STATE_COMPLETED,    /* 17 - operation complete */
+  CURLM_STATE_MSGSENT,      /* 18 - the operation complete message is sent */
+  CURLM_STATE_LAST          /* 19 - not a true state, never use this */
 } CURLMstate;
 
 /* we support N sockets per easy handle. Set the corresponding bit to what
@@ -59,6 +62,8 @@ typedef enum {
 #define GETSOCK_READABLE (0x00ff)
 #define GETSOCK_WRITABLE (0xff00)
 
+#define CURLPIPE_ANY (CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX)
+
 /* This is the struct known as CURLM on the outside */
 struct Curl_multi {
   /* First a simple identifier to easier detect if a user mix up
@@ -82,8 +87,12 @@ struct Curl_multi {
   curl_socket_callback socket_cb;
   void *socket_userp;
 
+  /* callback function and user data pointer for server push */
+  curl_push_callback push_cb;
+  void *push_userp;
+
   /* Hostname cache */
-  struct curl_hash *hostcache;
+  struct curl_hash hostcache;
 
   /* timetree points to the splay-tree of time nodes to figure out expire
      times of all currently set timers */
@@ -92,13 +101,15 @@ struct Curl_multi {
   /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
      the pluralis form, there can be more than one easy handle waiting on the
      same actual socket) */
-  struct curl_hash *sockhash;
+  struct curl_hash sockhash;
 
-  /* Whether pipelining is enabled for this multi handle */
-  bool pipelining_enabled;
+  /* pipelining wanted bits (CURLPIPE*) */
+  long pipelining;
+
+  bool recheckstate; /* see Curl_multi_connchanged */
 
   /* Shared connection cache (bundles)*/
-  struct conncache *conn_cache;
+  struct conncache conn_cache;
 
   /* This handle will be used for closing the cached connections in
      curl_multi_cleanup() */
@@ -139,4 +150,3 @@ struct Curl_multi {
 };
 
 #endif /* HEADER_CURL_MULTIHANDLE_H */
-
diff --git a/Utilities/cmcurl/lib/multiif.h b/Utilities/cmcurl/lib/multiif.h
index c77b3ca..e6323ad 100644
--- a/Utilities/cmcurl/lib/multiif.h
+++ b/Utilities/cmcurl/lib/multiif.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,8 +27,7 @@
  */
 void Curl_expire(struct SessionHandle *data, long milli);
 void Curl_expire_latest(struct SessionHandle *data, long milli);
-
-bool Curl_multi_pipeline_enabled(const struct Curl_multi* multi);
+bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
 void Curl_multi_handlePipeBreak(struct SessionHandle *data);
 
 /* Internal version of curl_multi_init() accepts size parameters for the
@@ -55,18 +54,11 @@ struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize);
 void Curl_multi_dump(const struct Curl_multi *multi_handle);
 #endif
 
-/* Update the current connection of a One_Easy handle */
-void Curl_multi_set_easy_connection(struct SessionHandle *handle,
-                                    struct connectdata *conn);
-
 void Curl_multi_process_pending_handles(struct Curl_multi *multi);
 
 /* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */
 size_t Curl_multi_max_host_connections(struct Curl_multi *multi);
 
-/* Return the value of the CURLMOPT_MAX_PIPELINE_LENGTH option */
-size_t Curl_multi_max_pipeline_length(struct Curl_multi *multi);
-
 /* Return the value of the CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE option */
 curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi);
 
@@ -82,11 +74,13 @@ struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi);
 /* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
 size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
 
+void Curl_multi_connchanged(struct Curl_multi *multi);
+
 /*
  * Curl_multi_closed()
  *
  * Used by the connect code to tell the multi_socket code that one of the
- * sockets we were using have just been closed.  This function will then
+ * sockets we were using is about to be closed.  This function will then
  * remove it from the sockethash for this handle to make the multi_socket API
  * behave properly, especially for the case when libcurl will create another
  * socket again and it gets the same file descriptor number.
@@ -94,4 +88,10 @@ size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
 
 void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
 
+/*
+ * Add a handle and move it into PERFORM state at once. For pushed streams.
+ */
+CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
+                                 struct SessionHandle *data,
+                                 struct connectdata *conn);
 #endif /* HEADER_CURL_MULTIIF_H */
diff --git a/Utilities/cmcurl/lib/netrc.c b/Utilities/cmcurl/lib/netrc.c
index 7435d94..06f8ea1 100644
--- a/Utilities/cmcurl/lib/netrc.c
+++ b/Utilities/cmcurl/lib/netrc.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,13 +31,11 @@
 
 #include "strequal.h"
 #include "strtok.h"
-#include "curl_memory.h"
 #include "rawstr.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /* Get user and password from .netrc when given a machine name */
@@ -104,16 +102,16 @@ int Curl_parsenetrc(const char *host,
 
     netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
     if(home_alloc)
-      Curl_safefree(home);
+      free(home);
     if(!netrcfile) {
       return -1;
     }
     netrc_alloc = TRUE;
   }
 
-  file = fopen(netrcfile, "r");
+  file = fopen(netrcfile, FOPEN_READTEXT);
   if(netrc_alloc)
-    Curl_safefree(netrcfile);
+    free(netrcfile);
   if(file) {
     char *tok;
     char *tok_buf;
@@ -139,6 +137,10 @@ int Curl_parsenetrc(const char *host,
                'password'. */
             state=HOSTFOUND;
           }
+          else if(Curl_raw_equal("default", tok)) {
+            state=HOSTVALID;
+            retcode=0; /* we did find our host */
+          }
           break;
         case HOSTFOUND:
           if(Curl_raw_equal(host, tok)) {
diff --git a/Utilities/cmcurl/lib/non-ascii.c b/Utilities/cmcurl/lib/non-ascii.c
index 91d6a54..6ccb449 100644
--- a/Utilities/cmcurl/lib/non-ascii.c
+++ b/Utilities/cmcurl/lib/non-ascii.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -82,17 +82,16 @@ CURLcode Curl_convert_clone(struct SessionHandle *data,
 CURLcode Curl_convert_to_network(struct SessionHandle *data,
                                  char *buffer, size_t length)
 {
-  CURLcode rc;
-
   if(data->set.convtonetwork) {
     /* use translation callback */
-    rc = data->set.convtonetwork(buffer, length);
-    if(rc != CURLE_OK) {
+    CURLcode result = data->set.convtonetwork(buffer, length);
+    if(result) {
       failf(data,
             "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
-            (int)rc, curl_easy_strerror(rc));
+            (int)result, curl_easy_strerror(result));
     }
-    return rc;
+
+    return result;
   }
   else {
 #ifdef HAVE_ICONV
@@ -143,17 +142,16 @@ CURLcode Curl_convert_to_network(struct SessionHandle *data,
 CURLcode Curl_convert_from_network(struct SessionHandle *data,
                                    char *buffer, size_t length)
 {
-  CURLcode rc;
-
   if(data->set.convfromnetwork) {
     /* use translation callback */
-    rc = data->set.convfromnetwork(buffer, length);
-    if(rc != CURLE_OK) {
+    CURLcode result = data->set.convfromnetwork(buffer, length);
+    if(result) {
       failf(data,
             "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
-            (int)rc, curl_easy_strerror(rc));
+            (int)result, curl_easy_strerror(result));
     }
-    return rc;
+
+    return result;
   }
   else {
 #ifdef HAVE_ICONV
@@ -204,17 +202,16 @@ CURLcode Curl_convert_from_network(struct SessionHandle *data,
 CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
                                 char *buffer, size_t length)
 {
-  CURLcode rc;
-
   if(data->set.convfromutf8) {
     /* use translation callback */
-    rc = data->set.convfromutf8(buffer, length);
-    if(rc != CURLE_OK) {
+    CURLcode result = data->set.convfromutf8(buffer, length);
+    if(result) {
       failf(data,
             "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
-            (int)rc, curl_easy_strerror(rc));
+            (int)result, curl_easy_strerror(result));
     }
-    return rc;
+
+    return result;
   }
   else {
 #ifdef HAVE_ICONV
@@ -319,24 +316,22 @@ void Curl_convert_close(struct SessionHandle *data)
  */
 CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form)
 {
-  struct FormData *next;
-  CURLcode rc;
-
-  if(!form)
-    return CURLE_OK;
+  CURLcode result;
 
   if(!data)
     return CURLE_BAD_FUNCTION_ARGUMENT;
 
-  do {
-    next=form->next;  /* the following form line */
+  while(form) {
     if(form->type == FORM_DATA) {
-      rc = Curl_convert_to_network(data, form->line, form->length);
+      result = Curl_convert_to_network(data, form->line, form->length);
       /* Curl_convert_to_network calls failf if unsuccessful */
-      if(rc != CURLE_OK)
-        return rc;
+      if(result)
+        return result;
     }
-  } while((form = next) != NULL); /* continue */
+
+    form = form->next;
+  }
+
   return CURLE_OK;
 }
 
diff --git a/Utilities/cmcurl/lib/nwlib.c b/Utilities/cmcurl/lib/nwlib.c
index 252bf11..bd3f27e 100644
--- a/Utilities/cmcurl/lib/nwlib.c
+++ b/Utilities/cmcurl/lib/nwlib.c
@@ -282,9 +282,7 @@ int DisposeLibraryData( void *data )
   if(data) {
     void *tenbytes = ((libdata_t *) data)->tenbytes;
 
-    if(tenbytes)
-      free(tenbytes);
-
+    free(tenbytes);
     free(data);
   }
 
@@ -296,9 +294,7 @@ void DisposeThreadData( void *data )
   if(data) {
     void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
 
-    if(twentybytes)
-      free(twentybytes);
-
+    free(twentybytes);
     free(data);
   }
 }
diff --git a/Utilities/cmcurl/lib/openldap.c b/Utilities/cmcurl/lib/openldap.c
index df8d938..bee552f 100644
--- a/Utilities/cmcurl/lib/openldap.c
+++ b/Utilities/cmcurl/lib/openldap.c
@@ -5,8 +5,8 @@
  *                | (__| |_| |  _ <| |___
  *                 \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010, 2013, Howard Chu, <hyc at openldap.org>
- * Copyright (C) 2011 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2010, Howard Chu, <hyc at openldap.org>
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -44,13 +44,12 @@
 #include "vtls/vtls.h"
 #include "transfer.h"
 #include "curl_ldap.h"
-#include "curl_memory.h"
 #include "curl_base64.h"
 #include "connect.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #ifndef _LDAP_PVT_H
@@ -59,7 +58,7 @@ extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
                         LDAP **ld);
 #endif
 
-static CURLcode ldap_setup(struct connectdata *conn);
+static CURLcode ldap_setup_connection(struct connectdata *conn);
 static CURLcode ldap_do(struct connectdata *conn, bool *done);
 static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
 static CURLcode ldap_connect(struct connectdata *conn, bool *done);
@@ -74,7 +73,7 @@ static Curl_recv ldap_recv;
 
 const struct Curl_handler Curl_handler_ldap = {
   "LDAP",                               /* scheme */
-  ldap_setup,                           /* setup_connection */
+  ldap_setup_connection,                /* setup_connection */
   ldap_do,                              /* do_it */
   ldap_done,                            /* done */
   ZERO_NULL,                            /* do_more */
@@ -99,7 +98,7 @@ const struct Curl_handler Curl_handler_ldap = {
 
 const struct Curl_handler Curl_handler_ldaps = {
   "LDAPS",                              /* scheme */
-  ldap_setup,                           /* setup_connection */
+  ldap_setup_connection,                /* setup_connection */
   ldap_do,                              /* do_it */
   ldap_done,                            /* done */
   ZERO_NULL,                            /* do_more */
@@ -148,7 +147,7 @@ typedef struct ldapreqinfo {
   int nument;
 } ldapreqinfo;
 
-static CURLcode ldap_setup(struct connectdata *conn)
+static CURLcode ldap_setup_connection(struct connectdata *conn)
 {
   ldapconninfo *li;
   LDAPURLDesc *lud;
@@ -190,9 +189,11 @@ static Sockbuf_IO ldapsb_tls;
 static CURLcode ldap_connect(struct connectdata *conn, bool *done)
 {
   ldapconninfo *li = conn->proto.generic;
-  struct SessionHandle *data=conn->data;
+  struct SessionHandle *data = conn->data;
   int rc, proto = LDAP_VERSION3;
-  char hosturl[1024], *ptr;
+  char hosturl[1024];
+  char *ptr;
+
   (void)done;
 
   strcpy(hosturl, "ldap");
@@ -213,10 +214,10 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
 
 #ifdef USE_SSL
   if(conn->handler->flags & PROTOPT_SSL) {
-    CURLcode res;
-    res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
-    if(res)
-      return res;
+    CURLcode result;
+    result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
+    if(result)
+      return result;
   }
 #endif
 
@@ -226,9 +227,9 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
 static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
 {
   ldapconninfo *li = conn->proto.generic;
-  struct SessionHandle *data=conn->data;
-  LDAPMessage *result = NULL;
-  struct timeval tv = {0,1}, *tvp;
+  struct SessionHandle *data = conn->data;
+  LDAPMessage *msg = NULL;
+  struct timeval tv = {0, 1}, *tvp;
   int rc, err;
   char *info = NULL;
 
@@ -236,11 +237,12 @@ static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
   if(conn->handler->flags & PROTOPT_SSL) {
     /* Is the SSL handshake complete yet? */
     if(!li->ssldone) {
-      CURLcode res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
-                                                  &li->ssldone);
-      if(res || !li->ssldone)
-        return res;
+      CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
+                                                     &li->ssldone);
+      if(result || !li->ssldone)
+        return result;
     }
+
     /* Have we installed the libcurl SSL handlers into the sockbuf yet? */
     if(!li->sslinst) {
       Sockbuf *sb;
@@ -279,7 +281,7 @@ retry:
       return CURLE_OK;
   }
 
-  rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &result);
+  rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg);
   if(rc < 0) {
     failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
     return CURLE_LDAP_CANNOT_BIND;
@@ -288,11 +290,13 @@ retry:
     /* timed out */
     return CURLE_OK;
   }
-  rc = ldap_parse_result(li->ld, result, &err, NULL, &info, NULL, NULL, 1);
+
+  rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1);
   if(rc) {
     failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
     return CURLE_LDAP_CANNOT_BIND;
   }
+
   /* Try to fallback to LDAPv2? */
   if(err == LDAP_PROTOCOL_ERROR) {
     int proto;
@@ -321,6 +325,7 @@ retry:
     ldap_memfree(info);
   conn->recv[FIRSTSOCKET] = ldap_recv;
   *done = TRUE;
+
   return CURLE_OK;
 }
 
@@ -375,7 +380,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
     failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
     return CURLE_LDAP_SEARCH_FAILED;
   }
-  lr = calloc(1,sizeof(ldapreqinfo));
+  lr = calloc(1, sizeof(ldapreqinfo));
   if(!lr)
     return CURLE_OUT_OF_MEMORY;
   lr->msgid = msgid;
@@ -389,6 +394,7 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
                           bool premature)
 {
   ldapreqinfo *lr = conn->data->req.protop;
+
   (void)res;
   (void)premature;
 
@@ -402,6 +408,7 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
     conn->data->req.protop = NULL;
     free(lr);
   }
+
   return CURLE_OK;
 }
 
@@ -409,18 +416,19 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
                          size_t len, CURLcode *err)
 {
   ldapconninfo *li = conn->proto.generic;
-  struct SessionHandle *data=conn->data;
+  struct SessionHandle *data = conn->data;
   ldapreqinfo *lr = data->req.protop;
   int rc, ret;
-  LDAPMessage *result = NULL;
+  LDAPMessage *msg = NULL;
   LDAPMessage *ent;
   BerElement *ber = NULL;
-  struct timeval tv = {0,1};
+  struct timeval tv = {0, 1};
+
   (void)len;
   (void)buf;
   (void)sockindex;
 
-  rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &result);
+  rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
   if(rc < 0) {
     failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
     *err = CURLE_RECV_ERROR;
@@ -431,10 +439,10 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
   ret = -1;
 
   /* timed out */
-  if(result == NULL)
+  if(!msg)
     return ret;
 
-  for(ent = ldap_first_message(li->ld, result); ent;
+  for(ent = ldap_first_message(li->ld, msg); ent;
     ent = ldap_next_message(li->ld, ent)) {
     struct berval bv, *bvals, **bvp = &bvals;
     int binary = 0, msgtype;
@@ -477,9 +485,18 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
       *err = CURLE_RECV_ERROR;
       return -1;
     }
-    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
-    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len);
-    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+    if(*err)
+      return -1;
+
+    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+                             bv.bv_len);
+    if(*err)
+      return -1;
+
+    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+    if(*err)
+      return -1;
     data->req.bytecount += bv.bv_len + 5;
 
     for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
@@ -496,10 +513,18 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
 
       for(i=0; bvals[i].bv_val != NULL; i++) {
         int binval = 0;
-        Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
-        Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
-                          bv.bv_len);
-        Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
+        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+        if(*err)
+          return -1;
+
+        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+                                 bv.bv_len);
+        if(*err)
+          return -1;
+
+        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
+        if(*err)
+          return -1;
         data->req.bytecount += bv.bv_len + 2;
 
         if(!binary) {
@@ -529,36 +554,55 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
           if(error) {
             ber_memfree(bvals);
             ber_free(ber, 0);
-            ldap_msgfree(result);
+            ldap_msgfree(msg);
             *err = error;
             return -1;
           }
-          Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
+          *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
+          if(*err)
+            return -1;
+
           data->req.bytecount += 2;
           if(val_b64_sz > 0) {
-            Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);
+            *err = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+                                     val_b64_sz);
+            if(*err)
+              return -1;
             free(val_b64);
             data->req.bytecount += val_b64_sz;
           }
         }
         else {
-          Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
-          Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
-                            bvals[i].bv_len);
+          *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
+          if(*err)
+            return -1;
+
+          *err = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
+                                   bvals[i].bv_len);
+          if(*err)
+            return -1;
+
           data->req.bytecount += bvals[i].bv_len + 1;
         }
-        Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+        if(*err)
+          return -1;
+
         data->req.bytecount++;
       }
       ber_memfree(bvals);
-      Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+      *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+      if(*err)
+        return -1;
       data->req.bytecount++;
     }
-    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+    if(*err)
+      return -1;
     data->req.bytecount++;
     ber_free(ber, 0);
   }
-  ldap_msgfree(result);
+  ldap_msgfree(msg);
   return ret;
 }
 
diff --git a/Utilities/cmcurl/lib/parsedate.c b/Utilities/cmcurl/lib/parsedate.c
index ecb8dfb..3e168f5 100644
--- a/Utilities/cmcurl/lib/parsedate.c
+++ b/Utilities/cmcurl/lib/parsedate.c
@@ -545,7 +545,7 @@ static int parsedate(const char *date, time_t *output)
 
 time_t curl_getdate(const char *p, const time_t *now)
 {
-  time_t parsed;
+  time_t parsed = -1;
   int rc = parsedate(p, &parsed);
   (void)now; /* legacy argument from the past that we ignore */
 
diff --git a/Utilities/cmcurl/lib/pingpong.c b/Utilities/cmcurl/lib/pingpong.c
index c7e89d0..1670792 100644
--- a/Utilities/cmcurl/lib/pingpong.c
+++ b/Utilities/cmcurl/lib/pingpong.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -34,9 +34,7 @@
 #include "multiif.h"
 #include "non-ascii.h"
 #include "vtls/vtls.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -165,7 +163,7 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
   size_t write_len;
   char *fmt_crlf;
   char *s;
-  CURLcode error;
+  CURLcode result;
   struct connectdata *conn = pp->conn;
   struct SessionHandle *data = conn->data;
 
@@ -191,26 +189,26 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
 
   Curl_pp_init(pp);
 
-  error = Curl_convert_to_network(data, s, write_len);
+  result = Curl_convert_to_network(data, s, write_len);
   /* Curl_convert_to_network calls failf if unsuccessful */
-  if(error) {
+  if(result) {
     free(s);
-    return error;
+    return result;
   }
 
 #ifdef HAVE_GSSAPI
   conn->data_prot = PROT_CMD;
 #endif
-  error = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
+  result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
                      &bytes_written);
 #ifdef HAVE_GSSAPI
   DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
   conn->data_prot = data_sec;
 #endif
 
-  if(error) {
+  if(result) {
     free(s);
-    return error;
+    return result;
   }
 
   if(conn->data->set.verbose)
@@ -247,15 +245,15 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
 CURLcode Curl_pp_sendf(struct pingpong *pp,
                        const char *fmt, ...)
 {
-  CURLcode res;
+  CURLcode result;
   va_list ap;
   va_start(ap, fmt);
 
-  res = Curl_pp_vsendf(pp, fmt, ap);
+  result = Curl_pp_vsendf(pp, fmt, ap);
 
   va_end(ap);
 
-  return res;
+  return result;
 }
 
 /*
@@ -285,8 +283,6 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
   /* number of bytes in the current line, so far */
   perline = (ssize_t)(ptr-pp->linestart_resp);
 
-  keepon=TRUE;
-
   while((pp->nread_resp<BUFSIZE) && (keepon && !result)) {
 
     if(pp->cache) {
@@ -305,30 +301,28 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
       pp->cache_size = 0; /* zero the size just in case */
     }
     else {
-      int res;
 #ifdef HAVE_GSSAPI
       enum protection_level prot = conn->data_prot;
       conn->data_prot = PROT_CLEAR;
 #endif
       DEBUGASSERT((ptr+BUFSIZE-pp->nread_resp) <= (buf+BUFSIZE+1));
-      res = Curl_read(conn, sockfd, ptr, BUFSIZE-pp->nread_resp,
-                      &gotbytes);
+      result = Curl_read(conn, sockfd, ptr, BUFSIZE-pp->nread_resp,
+                         &gotbytes);
 #ifdef HAVE_GSSAPI
       DEBUGASSERT(prot  > PROT_NONE && prot < PROT_LAST);
       conn->data_prot = prot;
 #endif
-      if(res == CURLE_AGAIN)
+      if(result == CURLE_AGAIN)
         return CURLE_OK; /* return */
 
-      if((res == CURLE_OK) && (gotbytes > 0))
+      if(!result && (gotbytes > 0))
         /* convert from the network encoding */
-        res = Curl_convert_from_network(data, ptr, gotbytes);
+        result = Curl_convert_from_network(data, ptr, gotbytes);
       /* Curl_convert_from_network calls failf if unsuccessful */
 
-      if(CURLE_OK != res) {
-        result = (CURLcode)res; /* Set outer result variable to this error. */
+      if(result)
+        /* Set outer result variable to this error. */
         keepon = FALSE;
-      }
     }
 
     if(!keepon)
@@ -478,11 +472,9 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp)
   /* we have a piece of a command still left to send */
   struct connectdata *conn = pp->conn;
   ssize_t written;
-  CURLcode result = CURLE_OK;
   curl_socket_t sock = conn->sock[FIRSTSOCKET];
-
-  result = Curl_write(conn, sock, pp->sendthis + pp->sendsize -
-                      pp->sendleft, pp->sendleft, &written);
+  CURLcode result = Curl_write(conn, sock, pp->sendthis + pp->sendsize -
+                               pp->sendleft, pp->sendleft, &written);
   if(result)
     return result;
 
@@ -501,10 +493,8 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp)
 
 CURLcode Curl_pp_disconnect(struct pingpong *pp)
 {
-  if(pp->cache) {
-    free(pp->cache);
-    pp->cache = NULL;
-  }
+  free(pp->cache);
+  pp->cache = NULL;
   return CURLE_OK;
 }
 
diff --git a/Utilities/cmcurl/lib/pipeline.c b/Utilities/cmcurl/lib/pipeline.c
index 8d2544b..1b38836 100644
--- a/Utilities/cmcurl/lib/pipeline.c
+++ b/Utilities/cmcurl/lib/pipeline.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2013, Linus Nielsen Feltzing, <linus at haxx.se>
- * Copyright (C) 2013-2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2013-2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,7 +32,6 @@
 #include "pipeline.h"
 #include "sendf.h"
 #include "rawstr.h"
-#include "bundles.h"
 
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -49,15 +48,13 @@ static void site_blacklist_llist_dtor(void *user, void *element)
   (void)user;
 
   Curl_safefree(entry->hostname);
-  Curl_safefree(entry);
+  free(entry);
 }
 
 static void server_blacklist_llist_dtor(void *user, void *element)
 {
-  char *server_name = element;
   (void)user;
-
-  Curl_safefree(server_name);
+  free(element);
 }
 
 bool Curl_pipeline_penalized(struct SessionHandle *data,
@@ -94,20 +91,29 @@ bool Curl_pipeline_penalized(struct SessionHandle *data,
   return FALSE;
 }
 
+static CURLcode addHandleToPipeline(struct SessionHandle *data,
+                                    struct curl_llist *pipeline)
+{
+  if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
+    return CURLE_OUT_OF_MEMORY;
+  return CURLE_OK;
+}
+
+
 CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
                                      struct connectdata *conn)
 {
   struct curl_llist_element *sendhead = conn->send_pipe->head;
   struct curl_llist *pipeline;
-  CURLcode rc;
+  CURLcode result;
 
   pipeline = conn->send_pipe;
 
-  rc = Curl_addHandleToPipeline(handle, pipeline);
+  result = addHandleToPipeline(handle, pipeline);
 
   if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
     /* this is a new one as head, expire it */
-    conn->writechannel_inuse = FALSE; /* not in use yet */
+    Curl_pipeline_leave_write(conn); /* not in use yet */
     Curl_expire(conn->send_pipe->head->ptr, 1);
   }
 
@@ -115,7 +121,7 @@ CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
   print_pipeline(conn);
 #endif
 
-  return rc;
+  return result;
 }
 
 /* Move this transfer from the sending list to the receiving list.
@@ -138,7 +144,7 @@ void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle,
       if(conn->send_pipe->head) {
         /* Since there's a new easy handle at the start of the send pipeline,
            set its timeout value to 1ms to make it trigger instantly */
-        conn->writechannel_inuse = FALSE; /* not used now */
+        Curl_pipeline_leave_write(conn); /* not used now */
 #ifdef DEBUGBUILD
         infof(conn->data, "%p is at send pipe head B!\n",
               (void *)conn->send_pipe->head->ptr);
@@ -251,7 +257,7 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
 bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle,
                                       char *server_name)
 {
-  if(handle->multi) {
+  if(handle->multi && server_name) {
     struct curl_llist *blacklist =
       Curl_multi_pipelining_server_bl(handle->multi);
 
@@ -272,7 +278,7 @@ bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle,
       }
     }
 
-    infof(handle, "Server %s is not blacklisted\n", server_name);
+    DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name));
   }
   return FALSE;
 }
@@ -314,6 +320,93 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
   return CURLM_OK;
 }
 
+static bool pipe_head(struct SessionHandle *data,
+                      struct curl_llist *pipeline)
+{
+  struct curl_llist_element *curr = pipeline->head;
+  if(curr)
+    return (curr->ptr == data) ? TRUE : FALSE;
+
+  return FALSE;
+}
+
+/* returns TRUE if the given handle is head of the recv pipe */
+bool Curl_recvpipe_head(struct SessionHandle *data,
+                        struct connectdata *conn)
+{
+  return pipe_head(data, conn->recv_pipe);
+}
+
+/* returns TRUE if the given handle is head of the send pipe */
+bool Curl_sendpipe_head(struct SessionHandle *data,
+                        struct connectdata *conn)
+{
+  return pipe_head(data, conn->send_pipe);
+}
+
+
+/*
+ * Check if the write channel is available and this handle as at the head,
+ * then grab the channel and return TRUE.
+ *
+ * If not available, return FALSE.
+ */
+
+bool Curl_pipeline_checkget_write(struct SessionHandle *data,
+                                  struct connectdata *conn)
+{
+  if(conn->bits.multiplex)
+    /* when multiplexing, we can use it at once */
+    return TRUE;
+
+  if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) {
+    /* Grab the channel */
+    conn->writechannel_inuse = TRUE;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/*
+ * Check if the read channel is available and this handle as at the head, then
+ * grab the channel and return TRUE.
+ *
+ * If not available, return FALSE.
+ */
+
+bool Curl_pipeline_checkget_read(struct SessionHandle *data,
+                                 struct connectdata *conn)
+{
+  if(conn->bits.multiplex)
+    /* when multiplexing, we can use it at once */
+    return TRUE;
+
+  if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) {
+    /* Grab the channel */
+    conn->readchannel_inuse = TRUE;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/*
+ * The current user of the pipeline write channel gives it up.
+ */
+void Curl_pipeline_leave_write(struct connectdata *conn)
+{
+  conn->writechannel_inuse = FALSE;
+}
+
+/*
+ * The current user of the pipeline read channel gives it up.
+ */
+void Curl_pipeline_leave_read(struct connectdata *conn)
+{
+  conn->readchannel_inuse = FALSE;
+}
+
+
 #if 0
 void print_pipeline(struct connectdata *conn)
 {
diff --git a/Utilities/cmcurl/lib/pipeline.h b/Utilities/cmcurl/lib/pipeline.h
index 96c4c33..bf229f1 100644
--- a/Utilities/cmcurl/lib/pipeline.h
+++ b/Utilities/cmcurl/lib/pipeline.h
@@ -7,6 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
+ * Copyright (C) 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  * Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus at haxx.se>
  *
  * This software is licensed as described in the file COPYING, which
@@ -41,4 +42,15 @@ bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle,
 CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
                                              struct curl_llist **list_ptr);
 
+bool Curl_pipeline_checkget_write(struct SessionHandle *data,
+                                  struct connectdata *conn);
+bool Curl_pipeline_checkget_read(struct SessionHandle *data,
+                                 struct connectdata *conn);
+void Curl_pipeline_leave_write(struct connectdata *conn);
+void Curl_pipeline_leave_read(struct connectdata *conn);
+bool Curl_recvpipe_head(struct SessionHandle *data,
+                        struct connectdata *conn);
+bool Curl_sendpipe_head(struct SessionHandle *data,
+                        struct connectdata *conn);
+
 #endif /* HEADER_CURL_PIPELINE_H */
diff --git a/Utilities/cmcurl/lib/pop3.c b/Utilities/cmcurl/lib/pop3.c
index dc64f81..53510a2 100644
--- a/Utilities/cmcurl/lib/pop3.c
+++ b/Utilities/cmcurl/lib/pop3.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -63,7 +63,6 @@
 #include <curl/curl.h>
 #include "urldata.h"
 #include "sendf.h"
-#include "if2ip.h"
 #include "hostip.h"
 #include "progress.h"
 #include "transfer.h"
@@ -84,10 +83,7 @@
 #include "curl_sasl.h"
 #include "curl_md5.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -107,10 +103,10 @@ static CURLcode pop3_setup_connection(struct connectdata *conn);
 static CURLcode pop3_parse_url_options(struct connectdata *conn);
 static CURLcode pop3_parse_url_path(struct connectdata *conn);
 static CURLcode pop3_parse_custom_request(struct connectdata *conn);
-static CURLcode pop3_calc_sasl_details(struct connectdata *conn,
-                                       const char **mech,
-                                       char **initresp, size_t *len,
-                                       pop3state *state1, pop3state *state2);
+static CURLcode pop3_perform_auth(struct connectdata *conn, const char *mech,
+                                  const char *initresp);
+static CURLcode pop3_continue_auth(struct connectdata *conn, const char *resp);
+static void pop3_get_message(char *buffer, char** outptr);
 
 /*
  * POP3 protocol handler.
@@ -215,6 +211,17 @@ static const struct Curl_handler Curl_handler_pop3s_proxy = {
 #endif
 #endif
 
+/* SASL parameters for the pop3 protocol */
+static const struct SASLproto saslpop3 = {
+  "pop",                      /* The service name */
+  '+',                        /* Code received when continuation is expected */
+  '+',                        /* Code to receive upon authentication success */
+  255 - 8,                    /* Maximum initial response length (no max) */
+  pop3_perform_auth,          /* Send authentication command */
+  pop3_continue_auth,         /* Send authentication continuation */
+  pop3_get_message            /* Get SASL response message */
+};
+
 #ifdef USE_SSL
 static void pop3_to_pop3s(struct connectdata *conn)
 {
@@ -313,20 +320,7 @@ static void state(struct connectdata *conn, pop3state newstate)
     "CAPA",
     "STARTTLS",
     "UPGRADETLS",
-    "AUTH_PLAIN",
-    "AUTH_LOGIN",
-    "AUTH_LOGIN_PASSWD",
-    "AUTH_CRAMMD5",
-    "AUTH_DIGESTMD5",
-    "AUTH_DIGESTMD5_RESP",
-    "AUTH_NTLM",
-    "AUTH_NTLM_TYPE2MSG",
-    "AUTH_GSSAPI",
-    "AUTH_GSSAPI_TOKEN",
-    "AUTH_GSSAPI_NO_DATA",
-    "AUTH_XOAUTH2",
-    "AUTH_CANCEL",
-    "AUTH_FINAL",
+    "AUTH",
     "APOP",
     "USER",
     "PASS",
@@ -355,9 +349,9 @@ static CURLcode pop3_perform_capa(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
 
-  pop3c->authmechs = 0;         /* No known authentication mechanisms yet */
-  pop3c->authused = 0;          /* Clear the authentication mechanism used */
-  pop3c->tls_supported = FALSE; /* Clear the TLS capability */
+  pop3c->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */
+  pop3c->sasl.authused = SASL_AUTH_NONE;  /* Clear the auth. mechanism used */
+  pop3c->tls_supported = FALSE;           /* Clear the TLS capability */
 
   /* Send the CAPA command */
   result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA");
@@ -501,25 +495,18 @@ static CURLcode pop3_perform_apop(struct connectdata *conn)
  */
 static CURLcode pop3_perform_auth(struct connectdata *conn,
                                   const char *mech,
-                                  const char *initresp, size_t len,
-                                  pop3state state1, pop3state state2)
+                                  const char *initresp)
 {
   CURLcode result = CURLE_OK;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
 
-  if(initresp && 8 + strlen(mech) + len <= 255) { /* AUTH <mech> ...<crlf> */
+  if(initresp) {                                  /* AUTH <mech> ...<crlf> */
     /* Send the AUTH command with the initial response */
     result = Curl_pp_sendf(&pop3c->pp, "AUTH %s %s", mech, initresp);
-
-    if(!result)
-      state(conn, state2);
   }
   else {
     /* Send the AUTH command */
     result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
-
-    if(!result)
-      state(conn, state1);
   }
 
   return result;
@@ -527,6 +514,20 @@ static CURLcode pop3_perform_auth(struct connectdata *conn,
 
 /***********************************************************************
  *
+ * pop3_continue_auth()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode pop3_continue_auth(struct connectdata *conn,
+                                   const char *resp)
+{
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  return Curl_pp_sendf(&pop3c->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
  * pop3_perform_authentication()
  *
  * Initiates the authentication sequence, with the appropriate SASL
@@ -537,40 +538,32 @@ static CURLcode pop3_perform_authentication(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
-  const char *mech = NULL;
-  char *initresp = NULL;
-  size_t len = 0;
-  pop3state state1 = POP3_STOP;
-  pop3state state2 = POP3_STOP;
+  saslprogress progress = SASL_IDLE;
 
-  /* Check we have a username and password to authenticate with and end the
+  /* Check we have enough data to authenticate with and end the
      connect phase if we don't */
-  if(!conn->bits.user_passwd) {
+  if(!Curl_sasl_can_authenticate(&pop3c->sasl, conn)) {
     state(conn, POP3_STOP);
-
     return result;
   }
 
-  /* Calculate the SASL login details */
-  if(pop3c->authtypes & POP3_TYPE_SASL)
-    result = pop3_calc_sasl_details(conn, &mech, &initresp, &len, &state1,
-                                    &state2);
+  if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_SASL) {
+    /* Calculate the SASL login details */
+    result = Curl_sasl_start(&pop3c->sasl, conn, FALSE, &progress);
 
-  if(!result) {
-    if(mech && (pop3c->preftype & POP3_TYPE_SASL)) {
-      /* Perform SASL based authentication */
-      result = pop3_perform_auth(conn, mech, initresp, len, state1, state2);
+    if(!result)
+      if(progress == SASL_INPROGRESS)
+        state(conn, POP3_AUTH);
+  }
 
-      Curl_safefree(initresp);
-    }
+  if(!result && progress == SASL_IDLE) {
 #ifndef CURL_DISABLE_CRYPTO_AUTH
-    else if((pop3c->authtypes & POP3_TYPE_APOP) &&
-            (pop3c->preftype & POP3_TYPE_APOP))
+    if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
       /* Perform APOP authentication */
       result = pop3_perform_apop(conn);
+    else
 #endif
-    else if((pop3c->authtypes & POP3_TYPE_CLEARTEXT) &&
-            (pop3c->preftype & POP3_TYPE_CLEARTEXT))
+    if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
       /* Perform clear text authentication */
       result = pop3_perform_user(conn);
     else {
@@ -727,6 +720,9 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
 
       /* Loop through the data line */
       for(;;) {
+        size_t llen;
+        unsigned int mechbit;
+
         while(len &&
               (*line == ' ' || *line == '\t' ||
                *line == '\r' || *line == '\n')) {
@@ -745,22 +741,9 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
           wordlen++;
 
         /* Test the word for a matching authentication mechanism */
-        if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
-          pop3c->authmechs |= SASL_MECH_LOGIN;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
-          pop3c->authmechs |= SASL_MECH_PLAIN;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
-          pop3c->authmechs |= SASL_MECH_CRAM_MD5;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
-          pop3c->authmechs |= SASL_MECH_DIGEST_MD5;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
-          pop3c->authmechs |= SASL_MECH_GSSAPI;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
-          pop3c->authmechs |= SASL_MECH_EXTERNAL;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
-          pop3c->authmechs |= SASL_MECH_NTLM;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
-          pop3c->authmechs |= SASL_MECH_XOAUTH2;
+        if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+           llen == wordlen)
+          pop3c->sasl.authmechs |= mechbit;
 
         line += wordlen;
         len -= wordlen;
@@ -818,575 +801,42 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
   return result;
 }
 
-/* For AUTH PLAIN (without initial response) responses */
-static CURLcode pop3_state_auth_plain_resp(struct connectdata *conn,
-                                           int pop3code,
-                                           pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *plainauth = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied. %c", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the authorisation message */
-    result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
-                                            &plainauth, &len);
-    if(!result && plainauth) {
-      /* Send the message */
-      result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", plainauth);
-
-      if(!result)
-        state(conn, POP3_AUTH_FINAL);
-    }
-  }
-
-  Curl_safefree(plainauth);
-
-  return result;
-}
-
-/* For AUTH LOGIN (without initial response) responses */
-static CURLcode pop3_state_auth_login_resp(struct connectdata *conn,
-                                           int pop3code,
-                                           pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *authuser = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the user message */
-    result = Curl_sasl_create_login_message(data, conn->user,
-                                            &authuser, &len);
-    if(!result && authuser) {
-      /* Send the user */
-      result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", authuser);
-
-      if(!result)
-        state(conn, POP3_AUTH_LOGIN_PASSWD);
-    }
-  }
-
-  Curl_safefree(authuser);
-
-  return result;
-}
-
-/* For AUTH LOGIN user entry responses */
-static CURLcode pop3_state_auth_login_password_resp(struct connectdata *conn,
-                                                    int pop3code,
-                                                    pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *authpasswd = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the password message */
-    result = Curl_sasl_create_login_message(data, conn->passwd,
-                                            &authpasswd, &len);
-    if(!result && authpasswd) {
-      /* Send the password */
-      result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", authpasswd);
-
-      if(!result)
-        state(conn, POP3_AUTH_FINAL);
-    }
-  }
-
-  Curl_safefree(authpasswd);
-
-  return result;
-}
-
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-/* For AUTH CRAM-MD5 responses */
-static CURLcode pop3_state_auth_cram_resp(struct connectdata *conn,
-                                          int pop3code,
-                                          pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *chlg = NULL;
-  char *chlg64 = NULL;
-  char *rplyb64 = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    return CURLE_LOGIN_DENIED;
-  }
-
-  /* Get the challenge message */
-  pop3_get_message(data->state.buffer, &chlg64);
-
-  /* Decode the challenge message */
-  result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
-  if(result) {
-    /* Send the cancellation */
-    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
-
-    if(!result)
-      state(conn, POP3_AUTH_CANCEL);
-  }
-  else {
-    /* Create the response message */
-    result = Curl_sasl_create_cram_md5_message(data, chlg, conn->user,
-                                               conn->passwd, &rplyb64, &len);
-    if(!result && rplyb64) {
-      /* Send the response */
-      result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
-
-      if(!result)
-        state(conn, POP3_AUTH_FINAL);
-    }
-  }
-
-  Curl_safefree(chlg);
-  Curl_safefree(rplyb64);
-
-  return result;
-}
-
-/* For AUTH DIGEST-MD5 challenge responses */
-static CURLcode pop3_state_auth_digest_resp(struct connectdata *conn,
-                                            int pop3code,
-                                            pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *chlg64 = NULL;
-  char *rplyb64 = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    return CURLE_LOGIN_DENIED;
-  }
-
-  /* Get the challenge message */
-  pop3_get_message(data->state.buffer, &chlg64);
-
-  /* Create the response message */
-  result = Curl_sasl_create_digest_md5_message(data, chlg64,
-                                               conn->user, conn->passwd,
-                                               "pop", &rplyb64, &len);
-  if(result) {
-    if(result == CURLE_BAD_CONTENT_ENCODING) {
-      /* Send the cancellation */
-      result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
-
-      if(!result)
-        state(conn, POP3_AUTH_CANCEL);
-    }
-  }
-  else {
-    /* Send the response */
-    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
-
-    if(!result)
-      state(conn, POP3_AUTH_DIGESTMD5_RESP);
-  }
-
-  Curl_safefree(rplyb64);
-
-  return result;
-}
-
-/* For AUTH DIGEST-MD5 challenge-response responses */
-static CURLcode pop3_state_auth_digest_resp_resp(struct connectdata *conn,
-                                                 int pop3code,
-                                                 pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Authentication failed: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Send an empty response */
-    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "");
-
-    if(!result)
-      state(conn, POP3_AUTH_FINAL);
-  }
-
-  return result;
-}
-#endif
-
-#ifdef USE_NTLM
-/* For AUTH NTLM (without initial response) responses */
-static CURLcode pop3_state_auth_ntlm_resp(struct connectdata *conn,
-                                          int pop3code,
-                                          pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *type1msg = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the type-1 message */
-    result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
-                                                 &conn->ntlm,
-                                                 &type1msg, &len);
-    if(!result && type1msg) {
-      /* Send the message */
-      result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type1msg);
-
-      if(!result)
-        state(conn, POP3_AUTH_NTLM_TYPE2MSG);
-    }
-  }
-
-  Curl_safefree(type1msg);
-
-  return result;
-}
-
-/* For NTLM type-2 responses (sent in reponse to our type-1 message) */
-static CURLcode pop3_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
-                                                   int pop3code,
-                                                   pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *type2msg = NULL;
-  char *type3msg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Get the type-2 message */
-    pop3_get_message(data->state.buffer, &type2msg);
-
-    /* Decode the type-2 message */
-    result = Curl_sasl_decode_ntlm_type2_message(data, type2msg, &conn->ntlm);
-    if(result) {
-      /* Send the cancellation */
-      result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
-
-      if(!result)
-        state(conn, POP3_AUTH_CANCEL);
-    }
-    else {
-      /* Create the type-3 message */
-      result = Curl_sasl_create_ntlm_type3_message(data, conn->user,
-                                                   conn->passwd, &conn->ntlm,
-                                                   &type3msg, &len);
-      if(!result && type3msg) {
-        /* Send the message */
-        result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type3msg);
-
-        if(!result)
-          state(conn, POP3_AUTH_FINAL);
-      }
-    }
-  }
-
-  Curl_safefree(type3msg);
-
-  return result;
-}
-#endif
-
-#if defined(USE_WINDOWS_SSPI)
-/* For AUTH GSSAPI (without initial response) responses */
-static CURLcode pop3_state_auth_gssapi_resp(struct connectdata *conn,
-                                            int pop3code,
-                                            pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct pop3_conn *pop3c = &conn->proto.pop3c;
-  size_t len = 0;
-  char *respmsg = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the initial response message */
-    result = Curl_sasl_create_gssapi_user_message(data, conn->user,
-                                                  conn->passwd, "pop",
-                                                  pop3c->mutual_auth,
-                                                  NULL, &conn->krb5,
-                                                  &respmsg, &len);
-    if(!result && respmsg) {
-      /* Send the message */
-      result = Curl_pp_sendf(&pop3c->pp, "%s", respmsg);
-
-      if(!result)
-        state(conn, POP3_AUTH_GSSAPI_TOKEN);
-    }
-  }
-
-  Curl_safefree(respmsg);
-
-  return result;
-}
-
-/* For AUTH GSSAPI user token responses */
-static CURLcode pop3_state_auth_gssapi_token_resp(struct connectdata *conn,
-                                                  int pop3code,
-                                                  pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct pop3_conn *pop3c = &conn->proto.pop3c;
-  char *chlgmsg = NULL;
-  char *respmsg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Get the challenge message */
-    pop3_get_message(data->state.buffer, &chlgmsg);
-
-    if(pop3c->mutual_auth)
-      /* Decode the user token challenge and create the optional response
-         message */
-      result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
-                                                    pop3c->mutual_auth,
-                                                    chlgmsg, &conn->krb5,
-                                                    &respmsg, &len);
-    else
-      /* Decode the security challenge and create the response message */
-      result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
-                                                        &conn->krb5,
-                                                        &respmsg, &len);
-
-    if(result) {
-      if(result == CURLE_BAD_CONTENT_ENCODING) {
-        /* Send the cancellation */
-        result = Curl_pp_sendf(&pop3c->pp, "%s", "*");
-
-        if(!result)
-          state(conn, POP3_AUTH_CANCEL);
-      }
-    }
-    else {
-      /* Send the response */
-      if(respmsg)
-        result = Curl_pp_sendf(&pop3c->pp, "%s", respmsg);
-      else
-        result = Curl_pp_sendf(&pop3c->pp, "%s", "");
-
-      if(!result)
-        state(conn, (pop3c->mutual_auth ? POP3_AUTH_GSSAPI_NO_DATA :
-                                          POP3_AUTH_FINAL));
-    }
-  }
-
-  Curl_safefree(respmsg);
-
-  return result;
-}
-
-/* For AUTH GSSAPI no data responses */
-static CURLcode pop3_state_auth_gssapi_no_data_resp(struct connectdata *conn,
-                                                    int pop3code,
-                                                    pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *chlgmsg = NULL;
-  char *respmsg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Get the challenge message */
-    pop3_get_message(data->state.buffer, &chlgmsg);
-
-    /* Decode the security challenge and create the security message */
-    result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
-                                                      &conn->krb5,
-                                                      &respmsg, &len);
-    if(result) {
-      if(result == CURLE_BAD_CONTENT_ENCODING) {
-        /* Send the cancellation */
-        result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
-
-        if(!result)
-          state(conn, POP3_AUTH_CANCEL);
-      }
-    }
-    else {
-      /* Send the response */
-      if(respmsg) {
-        result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", respmsg);
-
-        if(!result)
-          state(conn, POP3_AUTH_FINAL);
-      }
-    }
-  }
-
-  Curl_safefree(respmsg);
-
-  return result;
-}
-#endif
-
-/* For AUTH XOAUTH2 (without initial response) responses */
-static CURLcode pop3_state_auth_xoauth2_resp(struct connectdata *conn,
-                                             int pop3code, pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *xoauth = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Access denied: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the authorisation message */
-    result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
-                                              conn->xoauth2_bearer,
-                                              &xoauth, &len);
-    if(!result && xoauth) {
-      /* Send the message */
-      result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", xoauth);
-
-      if(!result)
-        state(conn, POP3_AUTH_FINAL);
-    }
-  }
-
-  Curl_safefree(xoauth);
-
-  return result;
-}
-
-/* For AUTH cancellation responses */
-static CURLcode pop3_state_auth_cancel_resp(struct connectdata *conn,
-                                            int pop3code,
-                                            pop3state instate)
+/* For SASL authentication responses */
+static CURLcode pop3_state_auth_resp(struct connectdata *conn,
+                                     int pop3code,
+                                     pop3state instate)
 {
   CURLcode result = CURLE_OK;
   struct SessionHandle *data = conn->data;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
-  const char *mech = NULL;
-  char *initresp = NULL;
-  size_t len = 0;
-  pop3state state1 = POP3_STOP;
-  pop3state state2 = POP3_STOP;
+  saslprogress progress;
 
-  (void)pop3code;
   (void)instate; /* no use for this yet */
 
-  /* Remove the offending mechanism from the supported list */
-  pop3c->authmechs ^= pop3c->authused;
-
-  /* Calculate alternative SASL login details */
-  result = pop3_calc_sasl_details(conn, &mech, &initresp, &len, &state1,
-                                  &state2);
-
-  if(!result) {
-    /* Do we have any mechanisms left or can we fallback to another
-       authentication type? */
-    if(mech) {
-      /* Retry SASL based authentication */
-      result = pop3_perform_auth(conn, mech, initresp, len, state1, state2);
-
-      Curl_safefree(initresp);
-    }
+  result = Curl_sasl_continue(&pop3c->sasl, conn, pop3code, &progress);
+  if(!result)
+    switch(progress) {
+    case SASL_DONE:
+      state(conn, POP3_STOP);  /* Authenticated */
+      break;
+    case SASL_IDLE:            /* No mechanism left after cancellation */
 #ifndef CURL_DISABLE_CRYPTO_AUTH
-    else if((pop3c->authtypes & POP3_TYPE_APOP) &&
-            (pop3c->preftype & POP3_TYPE_APOP))
-      /* Perform APOP authentication */
-      result = pop3_perform_apop(conn);
+      if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
+        /* Perform APOP authentication */
+        result = pop3_perform_apop(conn);
+      else
 #endif
-    else if((pop3c->authtypes & POP3_TYPE_CLEARTEXT) &&
-            (pop3c->preftype & POP3_TYPE_CLEARTEXT))
-      /* Perform clear text authentication */
-      result = pop3_perform_user(conn);
-    else {
-      failf(data, "Authentication cancelled");
-
-      result = CURLE_LOGIN_DENIED;
+      if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
+        /* Perform clear text authentication */
+        result = pop3_perform_user(conn);
+      else {
+        failf(data, "Authentication cancelled");
+        result = CURLE_LOGIN_DENIED;
+      }
+      break;
+    default:
+      break;
     }
-  }
-
-  return result;
-}
-
-/* For final responses in the AUTH sequence */
-static CURLcode pop3_state_auth_final_resp(struct connectdata *conn,
-                                           int pop3code,
-                                           pop3state instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-
-  (void)instate; /* no use for this yet */
-
-  if(pop3code != '+') {
-    failf(data, "Authentication failed: %d", pop3code);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else
-    /* End of connect phase */
-    state(conn, POP3_STOP);
 
   return result;
 }
@@ -1553,69 +1003,8 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
       result = pop3_state_starttls_resp(conn, pop3code, pop3c->state);
       break;
 
-    case POP3_AUTH_PLAIN:
-      result = pop3_state_auth_plain_resp(conn, pop3code, pop3c->state);
-      break;
-
-    case POP3_AUTH_LOGIN:
-      result = pop3_state_auth_login_resp(conn, pop3code, pop3c->state);
-      break;
-
-    case POP3_AUTH_LOGIN_PASSWD:
-      result = pop3_state_auth_login_password_resp(conn, pop3code,
-                                                   pop3c->state);
-      break;
-
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-    case POP3_AUTH_CRAMMD5:
-      result = pop3_state_auth_cram_resp(conn, pop3code, pop3c->state);
-      break;
-
-    case POP3_AUTH_DIGESTMD5:
-      result = pop3_state_auth_digest_resp(conn, pop3code, pop3c->state);
-      break;
-
-    case POP3_AUTH_DIGESTMD5_RESP:
-      result = pop3_state_auth_digest_resp_resp(conn, pop3code, pop3c->state);
-      break;
-#endif
-
-#ifdef USE_NTLM
-    case POP3_AUTH_NTLM:
-      result = pop3_state_auth_ntlm_resp(conn, pop3code, pop3c->state);
-      break;
-
-    case POP3_AUTH_NTLM_TYPE2MSG:
-      result = pop3_state_auth_ntlm_type2msg_resp(conn, pop3code,
-                                                  pop3c->state);
-      break;
-#endif
-
-#if defined(USE_WINDOWS_SSPI)
-    case POP3_AUTH_GSSAPI:
-      result = pop3_state_auth_gssapi_resp(conn, pop3code, pop3c->state);
-      break;
-
-    case POP3_AUTH_GSSAPI_TOKEN:
-      result = pop3_state_auth_gssapi_token_resp(conn, pop3code, pop3c->state);
-      break;
-
-    case POP3_AUTH_GSSAPI_NO_DATA:
-      result = pop3_state_auth_gssapi_no_data_resp(conn, pop3code,
-                                                   pop3c->state);
-      break;
-#endif
-
-    case POP3_AUTH_XOAUTH2:
-      result = pop3_state_auth_xoauth2_resp(conn, pop3code, pop3c->state);
-      break;
-
-    case POP3_AUTH_CANCEL:
-      result = pop3_state_auth_cancel_resp(conn, pop3code, pop3c->state);
-      break;
-
-    case POP3_AUTH_FINAL:
-      result = pop3_state_auth_final_resp(conn, pop3code, pop3c->state);
+    case POP3_AUTH:
+      result = pop3_state_auth_resp(conn, pop3code, pop3c->state);
       break;
 
 #ifndef CURL_DISABLE_CRYPTO_AUTH
@@ -1728,7 +1117,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
 
   /* Set the default preferred authentication type and mechanism */
   pop3c->preftype = POP3_TYPE_ANY;
-  pop3c->prefmech = SASL_AUTH_ANY;
+  Curl_sasl_init(&pop3c->sasl, &saslpop3);
 
   /* Initialise the pingpong layer */
   Curl_pp_init(pp);
@@ -1880,7 +1269,7 @@ static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
   Curl_pp_disconnect(&pop3c->pp);
 
   /* Cleanup the SASL module */
-  Curl_sasl_cleanup(conn, pop3c->authused);
+  Curl_sasl_cleanup(conn, pop3c->sasl.authused);
 
   /* Cleanup our connection based variables */
   Curl_safefree(pop3c->apoptimestamp);
@@ -1995,75 +1384,52 @@ static CURLcode pop3_parse_url_options(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
-  const char *options = conn->options;
-  const char *ptr = options;
-  bool reset = TRUE;
+  const char *ptr = conn->options;
+
+  pop3c->sasl.resetprefs = TRUE;
 
-  while(ptr && *ptr) {
+  while(!result && ptr && *ptr) {
     const char *key = ptr;
+    const char *value;
 
     while(*ptr && *ptr != '=')
         ptr++;
 
-    if(strnequal(key, "AUTH", 4)) {
-      size_t len = 0;
-      const char *value = ++ptr;
+    value = ptr + 1;
 
-      if(reset) {
-        reset = FALSE;
-        pop3c->preftype = POP3_TYPE_NONE;
-        pop3c->prefmech = SASL_AUTH_NONE;
-      }
+    while(*ptr && *ptr != ';')
+      ptr++;
 
-      while(*ptr && *ptr != ';') {
-        ptr++;
-        len++;
-      }
+    if(strnequal(key, "AUTH=", 5)) {
+      result = Curl_sasl_parse_url_auth_option(&pop3c->sasl,
+                                               value, ptr - value);
 
-      if(strnequal(value, "*", len)) {
-        pop3c->preftype = POP3_TYPE_ANY;
-        pop3c->prefmech = SASL_AUTH_ANY;
-      }
-      else if(strnequal(value, "+APOP", len)) {
+      if(result && strnequal(value, "+APOP", ptr - value)) {
         pop3c->preftype = POP3_TYPE_APOP;
-        pop3c->prefmech = SASL_AUTH_NONE;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_LOGIN, len)) {
-        pop3c->preftype = POP3_TYPE_SASL;
-        pop3c->prefmech |= SASL_MECH_LOGIN;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_PLAIN, len)) {
-        pop3c->preftype = POP3_TYPE_SASL;
-        pop3c->prefmech |= SASL_MECH_PLAIN;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_CRAM_MD5, len)) {
-        pop3c->preftype = POP3_TYPE_SASL;
-        pop3c->prefmech |= SASL_MECH_CRAM_MD5;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_DIGEST_MD5, len)) {
-        pop3c->preftype = POP3_TYPE_SASL;
-        pop3c->prefmech |= SASL_MECH_DIGEST_MD5;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_GSSAPI, len)) {
-        pop3c->preftype = POP3_TYPE_SASL;
-        pop3c->prefmech |= SASL_MECH_GSSAPI;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_NTLM, len)) {
-        pop3c->preftype = POP3_TYPE_SASL;
-        pop3c->prefmech |= SASL_MECH_NTLM;
-      }
-      else if(strnequal(value, SASL_MECH_STRING_XOAUTH2, len)) {
-        pop3c->preftype = POP3_TYPE_SASL;
-        pop3c->prefmech |= SASL_MECH_XOAUTH2;
+        pop3c->sasl.prefmech = SASL_AUTH_NONE;
+        result = CURLE_OK;
       }
-
-      if(*ptr == ';')
-        ptr++;
     }
     else
       result = CURLE_URL_MALFORMAT;
+
+    if(*ptr == ';')
+      ptr++;
   }
 
+  if(pop3c->preftype != POP3_TYPE_APOP)
+    switch(pop3c->sasl.prefmech) {
+    case SASL_AUTH_NONE:
+      pop3c->preftype = POP3_TYPE_NONE;
+      break;
+    case SASL_AUTH_DEFAULT:
+      pop3c->preftype = POP3_TYPE_ANY;
+      break;
+    default:
+      pop3c->preftype = POP3_TYPE_SASL;
+      break;
+    }
+
   return result;
 }
 
@@ -2106,110 +1472,6 @@ static CURLcode pop3_parse_custom_request(struct connectdata *conn)
 
 /***********************************************************************
  *
- * pop3_calc_sasl_details()
- *
- * Calculate the required login details for SASL authentication.
- */
-static CURLcode pop3_calc_sasl_details(struct connectdata *conn,
-                                       const char **mech,
-                                       char **initresp, size_t *len,
-                                       pop3state *state1, pop3state *state2)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct pop3_conn *pop3c = &conn->proto.pop3c;
-
-  /* Calculate the supported authentication mechanism, by decreasing order of
-     security, as well as the initial response where appropriate */
-#if defined(USE_WINDOWS_SSPI)
-  if((pop3c->authmechs & SASL_MECH_GSSAPI) &&
-      (pop3c->prefmech & SASL_MECH_GSSAPI)) {
-    pop3c->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
-
-    *mech = SASL_MECH_STRING_GSSAPI;
-    *state1 = POP3_AUTH_GSSAPI;
-    *state2 = POP3_AUTH_GSSAPI_TOKEN;
-    pop3c->authused = SASL_MECH_GSSAPI;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_gssapi_user_message(data, conn->user,
-                                                    conn->passwd, "pop",
-                                                    pop3c->mutual_auth,
-                                                    NULL, &conn->krb5,
-                                                    initresp, len);
-  }
-  else
-#endif
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-  if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
-      (pop3c->prefmech & SASL_MECH_DIGEST_MD5)) {
-    *mech = SASL_MECH_STRING_DIGEST_MD5;
-    *state1 = POP3_AUTH_DIGESTMD5;
-    pop3c->authused = SASL_MECH_DIGEST_MD5;
-  }
-  else if((pop3c->authmechs & SASL_MECH_CRAM_MD5) &&
-          (pop3c->prefmech & SASL_MECH_CRAM_MD5)) {
-    *mech = SASL_MECH_STRING_CRAM_MD5;
-    *state1 = POP3_AUTH_CRAMMD5;
-    pop3c->authused = SASL_MECH_CRAM_MD5;
-  }
-  else
-#endif
-#ifdef USE_NTLM
-  if((pop3c->authmechs & SASL_MECH_NTLM) &&
-      (pop3c->prefmech & SASL_MECH_NTLM)) {
-    *mech = SASL_MECH_STRING_NTLM;
-    *state1 = POP3_AUTH_NTLM;
-    *state2 = POP3_AUTH_NTLM_TYPE2MSG;
-    pop3c->authused = SASL_MECH_NTLM;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
-                                                    &conn->ntlm,
-                                                    initresp, len);
-  }
-  else
-#endif
-  if(((pop3c->authmechs & SASL_MECH_XOAUTH2) &&
-      (pop3c->prefmech & SASL_MECH_XOAUTH2) &&
-      (pop3c->prefmech != SASL_AUTH_ANY)) || conn->xoauth2_bearer) {
-    *mech = SASL_MECH_STRING_XOAUTH2;
-    *state1 = POP3_AUTH_XOAUTH2;
-    *state2 = POP3_AUTH_FINAL;
-    pop3c->authused = SASL_MECH_XOAUTH2;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_xoauth2_message(data, conn->user,
-                                                conn->xoauth2_bearer,
-                                                initresp, len);
-  }
-  else if((pop3c->authmechs & SASL_MECH_LOGIN) &&
-          (pop3c->prefmech & SASL_MECH_LOGIN)) {
-    *mech = SASL_MECH_STRING_LOGIN;
-    *state1 = POP3_AUTH_LOGIN;
-    *state2 = POP3_AUTH_LOGIN_PASSWD;
-    pop3c->authused = SASL_MECH_LOGIN;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_login_message(data, conn->user, initresp, len);
-  }
-  else if((pop3c->authmechs & SASL_MECH_PLAIN) &&
-          (pop3c->prefmech & SASL_MECH_PLAIN)) {
-    *mech = SASL_MECH_STRING_PLAIN;
-    *state1 = POP3_AUTH_PLAIN;
-    *state2 = POP3_AUTH_FINAL;
-    pop3c->authused = SASL_MECH_PLAIN;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
-                                              initresp, len);
-  }
-
-  return result;
-}
-
-/***********************************************************************
- *
  * Curl_pop3_write()
  *
  * This function scans the body after the end-of-body and writes everything
diff --git a/Utilities/cmcurl/lib/pop3.h b/Utilities/cmcurl/lib/pop3.h
index 729a55a..7bc53aa 100644
--- a/Utilities/cmcurl/lib/pop3.h
+++ b/Utilities/cmcurl/lib/pop3.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,6 +23,7 @@
  ***************************************************************************/
 
 #include "pingpong.h"
+#include "curl_sasl.h"
 
 /****************************************************************************
  * POP3 unique setup
@@ -35,20 +36,7 @@ typedef enum {
   POP3_STARTTLS,
   POP3_UPGRADETLS,   /* asynchronously upgrade the connection to SSL/TLS
                        (multi mode only) */
-  POP3_AUTH_PLAIN,
-  POP3_AUTH_LOGIN,
-  POP3_AUTH_LOGIN_PASSWD,
-  POP3_AUTH_CRAMMD5,
-  POP3_AUTH_DIGESTMD5,
-  POP3_AUTH_DIGESTMD5_RESP,
-  POP3_AUTH_NTLM,
-  POP3_AUTH_NTLM_TYPE2MSG,
-  POP3_AUTH_GSSAPI,
-  POP3_AUTH_GSSAPI_TOKEN,
-  POP3_AUTH_GSSAPI_NO_DATA,
-  POP3_AUTH_XOAUTH2,
-  POP3_AUTH_CANCEL,
-  POP3_AUTH_FINAL,
+  POP3_AUTH,
   POP3_APOP,
   POP3_USER,
   POP3_PASS,
@@ -77,14 +65,11 @@ struct pop3_conn {
                              have been received so far */
   size_t strip;           /* Number of bytes from the start to ignore as
                              non-body */
+  struct SASL sasl;       /* SASL-related storage */
   unsigned int authtypes; /* Accepted authentication types */
-  unsigned int authmechs; /* Accepted SASL authentication mechanisms */
   unsigned int preftype;  /* Preferred authentication type */
-  unsigned int prefmech;  /* Preferred SASL authentication mechanism */
-  unsigned int authused;  /* SASL auth mechanism used for the connection */
   char *apoptimestamp;    /* APOP timestamp from the server greeting */
   bool tls_supported;     /* StartTLS capability supported by server */
-  bool mutual_auth;       /* Mutual authentication enabled (GSSAPI only) */
 };
 
 extern const struct Curl_handler Curl_handler_pop3;
diff --git a/Utilities/cmcurl/lib/progress.c b/Utilities/cmcurl/lib/progress.c
index f147ce7..b46e274 100644
--- a/Utilities/cmcurl/lib/progress.c
+++ b/Utilities/cmcurl/lib/progress.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,9 +25,7 @@
 #include "urldata.h"
 #include "sendf.h"
 #include "progress.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 /* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
    byte) */
diff --git a/Utilities/cmcurl/lib/rtsp.c b/Utilities/cmcurl/lib/rtsp.c
index 029738d..c30afd3 100644
--- a/Utilities/cmcurl/lib/rtsp.c
+++ b/Utilities/cmcurl/lib/rtsp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -34,14 +34,12 @@
 #include "progress.h"
 #include "rtsp.h"
 #include "rawstr.h"
-#include "curl_memory.h"
 #include "select.h"
 #include "connect.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /*
@@ -265,11 +263,10 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
    * Since all RTSP requests are included here, there is no need to
    * support custom requests like HTTP.
    **/
-  DEBUGASSERT((rtspreq > RTSPREQ_NONE && rtspreq < RTSPREQ_LAST));
   data->set.opt_no_body = TRUE; /* most requests don't contain a body */
   switch(rtspreq) {
-  case RTSPREQ_NONE:
-    failf(data, "Got invalid RTSP request: RTSPREQ_NONE");
+  default:
+    failf(data, "Got invalid RTSP request");
     return CURLE_BAD_FUNCTION_ARGUMENT;
   case RTSPREQ_OPTIONS:
     p_request = "OPTIONS";
@@ -325,7 +322,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
   if(!p_session_id &&
      (rtspreq & ~(RTSPREQ_OPTIONS | RTSPREQ_DESCRIBE | RTSPREQ_SETUP))) {
     failf(data, "Refusing to issue an RTSP request [%s] without a session ID.",
-          p_request ? p_request : "");
+          p_request);
     return CURLE_BAD_FUNCTION_ARGUMENT;
   }
 
@@ -443,8 +440,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
     Curl_add_bufferf(req_buffer,
                      "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
                      "CSeq: %ld\r\n", /* CSeq */
-                     (p_request ? p_request : ""), p_stream_uri,
-                     rtsp->CSeq_sent);
+                     p_request, p_stream_uri, rtsp->CSeq_sent);
   if(result)
     return result;
 
@@ -498,8 +494,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
 
     }
     else {
-      postsize = (data->set.postfieldsize != -1)?
-        data->set.postfieldsize:
+      postsize = (data->state.infilesize != -1)?
+        data->state.infilesize:
         (data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
       data->set.httpreq = HTTPREQ_POST;
     }
diff --git a/Utilities/cmcurl/lib/security.c b/Utilities/cmcurl/lib/security.c
index 508c7b4..014bbf1 100644
--- a/Utilities/cmcurl/lib/security.c
+++ b/Utilities/cmcurl/lib/security.c
@@ -7,10 +7,10 @@
  * rewrite to work around the paragraph 2 in the BSD licenses as explained
  * below.
  *
- * Copyright (c) 1998, 1999, 2013 Kungliga Tekniska H�gskolan
+ * Copyright (c) 1998, 1999 Kungliga Tekniska H�gskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  *
- * Copyright (C) 2001 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2001 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * All rights reserved.
  *
@@ -109,19 +109,12 @@ static char level_to_char(int level) {
   return 'P';
 }
 
-static const struct Curl_sec_client_mech * const mechs[] = {
-#ifdef HAVE_GSSAPI
-  &Curl_krb5_client_mech,
-#endif
-  NULL
-};
-
 /* Send an FTP command defined by |message| and the optional arguments. The
    function returns the ftp_code. If an error occurs, -1 is returned. */
 static int ftp_send_command(struct connectdata *conn, const char *message, ...)
 {
   int ftp_code;
-  ssize_t nread;
+  ssize_t nread=0;
   va_list args;
   char print_buffer[50];
 
@@ -129,11 +122,11 @@ static int ftp_send_command(struct connectdata *conn, const char *message, ...)
   vsnprintf(print_buffer, sizeof(print_buffer), message, args);
   va_end(args);
 
-  if(Curl_ftpsendf(conn, print_buffer) != CURLE_OK) {
+  if(Curl_ftpsendf(conn, print_buffer)) {
     ftp_code = -1;
   }
   else {
-    if(Curl_GetFTPResponse(&nread, conn, &ftp_code) != CURLE_OK)
+    if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
       ftp_code = -1;
   }
 
@@ -147,20 +140,20 @@ static CURLcode
 socket_read(curl_socket_t fd, void *to, size_t len)
 {
   char *to_p = to;
-  CURLcode code;
+  CURLcode result;
   ssize_t nread;
 
   while(len > 0) {
-    code = Curl_read_plain(fd, to_p, len, &nread);
-    if(code == CURLE_OK) {
+    result = Curl_read_plain(fd, to_p, len, &nread);
+    if(!result) {
       len -= nread;
       to_p += nread;
     }
     else {
       /* FIXME: We are doing a busy wait */
-      if(code == CURLE_AGAIN)
+      if(result == CURLE_AGAIN)
         continue;
-      return code;
+      return result;
     }
   }
   return CURLE_OK;
@@ -175,20 +168,20 @@ socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
              size_t len)
 {
   const char *to_p = to;
-  CURLcode code;
+  CURLcode result;
   ssize_t written;
 
   while(len > 0) {
-    code = Curl_write_plain(conn, fd, to_p, len, &written);
-    if(code == CURLE_OK) {
+    result = Curl_write_plain(conn, fd, to_p, len, &written);
+    if(!result) {
       len -= written;
       to_p += written;
     }
     else {
       /* FIXME: We are doing a busy wait */
-      if(code == CURLE_AGAIN)
+      if(result == CURLE_AGAIN)
         continue;
-      return code;
+      return result;
     }
   }
   return CURLE_OK;
@@ -200,11 +193,11 @@ static CURLcode read_data(struct connectdata *conn,
 {
   int len;
   void* tmp;
-  CURLcode ret;
+  CURLcode result;
 
-  ret = socket_read(fd, &len, sizeof(len));
-  if(ret != CURLE_OK)
-    return ret;
+  result = socket_read(fd, &len, sizeof(len));
+  if(result)
+    return result;
 
   len = ntohl(len);
   tmp = realloc(buf->data, len);
@@ -212,9 +205,9 @@ static CURLcode read_data(struct connectdata *conn,
     return CURLE_OUT_OF_MEMORY;
 
   buf->data = tmp;
-  ret = socket_read(fd, buf->data, len);
-  if(ret != CURLE_OK)
-    return ret;
+  result = socket_read(fd, buf->data, len);
+  if(result)
+    return result;
   buf->size = conn->mech->decode(conn->app_data, buf->data, len,
                                  conn->data_prot, conn);
   buf->index = 0;
@@ -256,7 +249,7 @@ static ssize_t sec_recv(struct connectdata *conn, int sockindex,
   buffer += bytes_read;
 
   while(len > 0) {
-    if(read_data(conn, fd, &conn->in_buffer) != CURLE_OK)
+    if(read_data(conn, fd, &conn->in_buffer))
       return -1;
     if(conn->in_buffer.size == 0) {
       if(bytes_read > 0)
@@ -295,7 +288,7 @@ static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
       prot_level = conn->command_prot;
   }
   bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
-                             (void**)&buffer, conn);
+                             (void**)&buffer);
   if(!buffer || bytes <= 0)
     return; /* error */
 
@@ -332,7 +325,6 @@ static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
 static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
                          const char *buffer, size_t length)
 {
-  /* FIXME: Check for overflow */
   ssize_t tx = 0, len = conn->buffer_size;
 
   len -= conn->mech->overhead(conn->app_data, conn->data_prot,
@@ -340,10 +332,9 @@ static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
   if(len <= 0)
     len = length;
   while(length) {
-    if(len >= 0 || length < (size_t)len) {
-      /* FIXME: Check for overflow. */
+    if(length < (size_t)len)
       len = length;
-    }
+
     do_sec_send(conn, fd, buffer, curlx_sztosi(len));
     length -= len;
     buffer += len;
@@ -368,7 +359,7 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
      int */
   int decoded_len;
   char *buf;
-  int ret_code;
+  int ret_code = 0;
   size_t decoded_sz = 0;
   CURLcode error;
 
@@ -397,13 +388,13 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
   }
 
   buf[decoded_len] = '\0';
-  DEBUGASSERT(decoded_len > 3);
-  if(buf[3] == '-')
-    ret_code = 0;
-  else {
-    /* Check for error? */
-    sscanf(buf, "%d", &ret_code);
-  }
+  if(decoded_len <= 3)
+    /* suspiciously short */
+    return 0;
+
+  if(buf[3] != '-')
+    /* safe to ignore return code */
+    (void)sscanf(buf, "%d", &ret_code);
 
   if(buf[decoded_len - 1] == '\n')
     buf[decoded_len - 1] = '\0';
@@ -446,8 +437,8 @@ static int sec_set_protection_level(struct connectdata *conn)
 
     pbsz = strstr(conn->data->state.buffer, "PBSZ=");
     if(pbsz) {
-      /* FIXME: Checks for errors in sscanf? */
-      sscanf(pbsz, "PBSZ=%u", &buffer_size);
+      /* ignore return code, use default value if it fails */
+      (void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
       if(buffer_size < conn->buffer_size)
         conn->buffer_size = buffer_size;
     }
@@ -486,72 +477,63 @@ static CURLcode choose_mech(struct connectdata *conn)
 {
   int ret;
   struct SessionHandle *data = conn->data;
-  const struct Curl_sec_client_mech * const *mech;
   void *tmp_allocation;
-  const char *mech_name;
-
-  for(mech = mechs; (*mech); ++mech) {
-    mech_name = (*mech)->name;
-    /* We have no mechanism with a NULL name but keep this check */
-    DEBUGASSERT(mech_name != NULL);
-    if(mech_name == NULL) {
-      infof(data, "Skipping mechanism with empty name (%p)\n", (void *)mech);
-      continue;
-    }
-    tmp_allocation = realloc(conn->app_data, (*mech)->size);
-    if(tmp_allocation == NULL) {
-      failf(data, "Failed realloc of size %u", (*mech)->size);
-      mech = NULL;
-      return CURLE_OUT_OF_MEMORY;
-    }
-    conn->app_data = tmp_allocation;
+  const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
 
-    if((*mech)->init) {
-      ret = (*mech)->init(conn->app_data);
-      if(ret != 0) {
-        infof(data, "Failed initialization for %s. Skipping it.\n", mech_name);
-        continue;
-      }
+  tmp_allocation = realloc(conn->app_data, mech->size);
+  if(tmp_allocation == NULL) {
+    failf(data, "Failed realloc of size %u", mech->size);
+    mech = NULL;
+    return CURLE_OUT_OF_MEMORY;
+  }
+  conn->app_data = tmp_allocation;
+
+  if(mech->init) {
+    ret = mech->init(conn->app_data);
+    if(ret) {
+      infof(data, "Failed initialization for %s. Skipping it.\n",
+            mech->name);
+      return CURLE_FAILED_INIT;
     }
+  }
 
-    infof(data, "Trying mechanism %s...\n", mech_name);
-    ret = ftp_send_command(conn, "AUTH %s", mech_name);
-    if(ret < 0)
-      /* FIXME: This error is too generic but it is OK for now. */
-      return CURLE_COULDNT_CONNECT;
-
-    if(ret/100 != 3) {
-      switch(ret) {
-      case 504:
-        infof(data, "Mechanism %s is not supported by the server (server "
-                    "returned ftp code: 504).\n", mech_name);
-        break;
-      case 534:
-        infof(data, "Mechanism %s was rejected by the server (server returned "
-                    "ftp code: 534).\n", mech_name);
-        break;
-      default:
-        if(ret/100 == 5) {
-          infof(data, "server does not support the security extensions\n");
-          return CURLE_USE_SSL_FAILED;
-        }
-        break;
+  infof(data, "Trying mechanism %s...\n", mech->name);
+  ret = ftp_send_command(conn, "AUTH %s", mech->name);
+  if(ret < 0)
+    /* FIXME: This error is too generic but it is OK for now. */
+    return CURLE_COULDNT_CONNECT;
+
+  if(ret/100 != 3) {
+    switch(ret) {
+    case 504:
+      infof(data, "Mechanism %s is not supported by the server (server "
+            "returned ftp code: 504).\n", mech->name);
+      break;
+    case 534:
+      infof(data, "Mechanism %s was rejected by the server (server returned "
+            "ftp code: 534).\n", mech->name);
+      break;
+    default:
+      if(ret/100 == 5) {
+        infof(data, "server does not support the security extensions\n");
+        return CURLE_USE_SSL_FAILED;
       }
-      continue;
+      break;
     }
+    return CURLE_LOGIN_DENIED;
+  }
 
-    /* Authenticate */
-    ret = (*mech)->auth(conn->app_data, conn);
+  /* Authenticate */
+  ret = mech->auth(conn->app_data, conn);
 
-    if(ret == AUTH_CONTINUE)
-      continue;
-    else if(ret != AUTH_OK) {
+  if(ret != AUTH_CONTINUE) {
+    if(ret != AUTH_OK) {
       /* Mechanism has dumped the error to stderr, don't error here. */
       return -1;
     }
     DEBUGASSERT(ret == AUTH_OK);
 
-    conn->mech = *mech;
+    conn->mech = mech;
     conn->sec_complete = 1;
     conn->recv[FIRSTSOCKET] = sec_recv;
     conn->send[FIRSTSOCKET] = sec_send;
@@ -561,10 +543,9 @@ static CURLcode choose_mech(struct connectdata *conn)
     /* Set the requested protection level */
     /* BLOCKING */
     (void)sec_set_protection_level(conn);
-    break;
   }
 
-  return mech != NULL ? CURLE_OK : CURLE_FAILED_INIT;
+  return CURLE_OK;
 }
 
 CURLcode
@@ -579,10 +560,8 @@ Curl_sec_end(struct connectdata *conn)
 {
   if(conn->mech != NULL && conn->mech->end)
     conn->mech->end(conn->app_data);
-  if(conn->app_data) {
-    free(conn->app_data);
-    conn->app_data = NULL;
-  }
+  free(conn->app_data);
+  conn->app_data = NULL;
   if(conn->in_buffer.data) {
     free(conn->in_buffer.data);
     conn->in_buffer.data = NULL;
diff --git a/Utilities/cmcurl/lib/select.c b/Utilities/cmcurl/lib/select.c
index 03c93f3..6eff070 100644
--- a/Utilities/cmcurl/lib/select.c
+++ b/Utilities/cmcurl/lib/select.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -39,6 +39,10 @@
 #include <dos.h>  /* delay() */
 #endif
 
+#ifdef __VXWORKS__
+#include <strings.h>  /* bzero() in FD_SET */
+#endif
+
 #include <curl/curl.h>
 
 #include "urldata.h"
@@ -155,7 +159,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
   fd_set fds_err;
   curl_socket_t maxfd;
 #endif
-  struct timeval initial_tv = {0,0};
+  struct timeval initial_tv = {0, 0};
   int pending_ms = 0;
   int error;
   int r;
@@ -389,7 +393,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
   fd_set fds_err;
   curl_socket_t maxfd;
 #endif
-  struct timeval initial_tv = {0,0};
+  struct timeval initial_tv = {0, 0};
   bool fds_none = TRUE;
   unsigned int i;
   int pending_ms = 0;
@@ -569,6 +573,6 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
 
    rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
    tpf_process_signals();
-   return(rc);
+   return rc;
 }
 #endif /* TPF */
diff --git a/Utilities/cmcurl/lib/sendf.c b/Utilities/cmcurl/lib/sendf.c
index 4a87c79..5f39d1f 100644
--- a/Utilities/cmcurl/lib/sendf.c
+++ b/Utilities/cmcurl/lib/sendf.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,14 +31,11 @@
 #include "ssh.h"
 #include "multiif.h"
 #include "non-ascii.h"
-
-#define _MPRINTF_REPLACE /* use the internal *printf() functions */
-#include <curl/mprintf.h>
-
-#include "curl_memory.h"
+#include "curl_printf.h"
 #include "strerror.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #ifdef CURL_DO_LINEEND_CONV
@@ -55,7 +52,7 @@ static size_t convert_lineends(struct SessionHandle *data,
 
   /* sanity check */
   if((startPtr == NULL) || (size < 1)) {
-    return(size);
+    return size;
   }
 
   if(data->state.prev_block_had_trailing_cr) {
@@ -117,9 +114,9 @@ static size_t convert_lineends(struct SessionHandle *data,
       /* tidy up by null terminating the now shorter data */
       *outPtr = '\0';
 
-    return(outPtr - startPtr);
+    return (outPtr - startPtr);
   }
-  return(size);
+  return size;
 }
 #endif /* CURL_DO_LINEEND_CONV */
 
@@ -174,7 +171,7 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
   struct SessionHandle *data = conn->data;
   ssize_t bytes_written;
   size_t write_len;
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
   char *s;
   char *sptr;
   va_list ap;
@@ -190,9 +187,9 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
 
   for(;;) {
     /* Write the buffer to the socket */
-    res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
+    result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
 
-    if(CURLE_OK != res)
+    if(result)
       break;
 
     if(data->set.verbose)
@@ -210,7 +207,7 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
 
   free(s); /* free the output string */
 
-  return res;
+  return result;
 }
 
 /*
@@ -227,10 +224,10 @@ CURLcode Curl_write(struct connectdata *conn,
                     ssize_t *written)
 {
   ssize_t bytes_written;
-  CURLcode curlcode = CURLE_OK;
+  CURLcode result = CURLE_OK;
   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
 
-  bytes_written = conn->send[num](conn, num, mem, len, &curlcode);
+  bytes_written = conn->send[num](conn, num, mem, len, &result);
 
   *written = bytes_written;
   if(bytes_written >= 0)
@@ -238,7 +235,7 @@ CURLcode Curl_write(struct connectdata *conn,
     return CURLE_OK;
 
   /* handle CURLE_AGAIN or a send failure */
-  switch(curlcode) {
+  switch(result) {
   case CURLE_AGAIN:
     *written = 0;
     return CURLE_OK;
@@ -249,7 +246,7 @@ CURLcode Curl_write(struct connectdata *conn,
 
   default:
     /* we got a specific curlcode, forward it */
-    return curlcode;
+    return result;
   }
 }
 
@@ -300,14 +297,14 @@ CURLcode Curl_write_plain(struct connectdata *conn,
                           ssize_t *written)
 {
   ssize_t bytes_written;
-  CURLcode retcode;
+  CURLcode result;
   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
 
-  bytes_written = Curl_send_plain(conn, num, mem, len, &retcode);
+  bytes_written = Curl_send_plain(conn, num, mem, len, &result);
 
   *written = bytes_written;
 
-  return retcode;
+  return result;
 }
 
 ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
@@ -374,25 +371,21 @@ static CURLcode pausewrite(struct SessionHandle *data,
 }
 
 
-/* Curl_client_write() sends data to the write callback(s)
-
-   The bit pattern defines to what "streams" to write to. Body and/or header.
-   The defines are in sendf.h of course.
-
-   If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
-   local character encoding.  This is a problem and should be changed in
-   the future to leave the original data alone.
+/* Curl_client_chop_write() writes chunks of data not larger than
+ * CURL_MAX_WRITE_SIZE via client write callback(s) and
+ * takes care of pause requests from the callbacks.
  */
-CURLcode Curl_client_write(struct connectdata *conn,
-                           int type,
-                           char *ptr,
-                           size_t len)
+CURLcode Curl_client_chop_write(struct connectdata *conn,
+                                int type,
+                                char * ptr,
+                                size_t len)
 {
   struct SessionHandle *data = conn->data;
-  size_t wrote;
+  curl_write_callback writeheader = NULL;
+  curl_write_callback writebody = NULL;
 
-  if(0 == len)
-    len = strlen(ptr);
+  if(!len)
+    return CURLE_OK;
 
   /* If reading is actually paused, we're forced to append this chunk of data
      to the already held data, but only if it is the same type as otherwise it
@@ -417,78 +410,107 @@ CURLcode Curl_client_write(struct connectdata *conn,
     /* update the pointer and the size */
     data->state.tempwrite = newptr;
     data->state.tempwritesize = newlen;
-
     return CURLE_OK;
   }
 
-  if(type & CLIENTWRITE_BODY) {
-    if((conn->handler->protocol&PROTO_FAMILY_FTP) &&
-       conn->proto.ftpc.transfertype == 'A') {
-      /* convert from the network encoding */
-      CURLcode rc = Curl_convert_from_network(data, ptr, len);
-      /* Curl_convert_from_network calls failf if unsuccessful */
-      if(rc)
-        return rc;
+  /* Determine the callback(s) to use. */
+  if(type & CLIENTWRITE_BODY)
+    writebody = data->set.fwrite_func;
+  if((type & CLIENTWRITE_HEADER) &&
+     (data->set.fwrite_header || data->set.writeheader)) {
+    /*
+     * Write headers to the same callback or to the especially setup
+     * header callback function (added after version 7.7.1).
+     */
+    writeheader =
+      data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
+  }
 
-#ifdef CURL_DO_LINEEND_CONV
-      /* convert end-of-line markers */
-      len = convert_lineends(data, ptr, len);
-#endif /* CURL_DO_LINEEND_CONV */
-    }
-    /* If the previous block of data ended with CR and this block of data is
-       just a NL, then the length might be zero */
-    if(len) {
-      wrote = data->set.fwrite_func(ptr, 1, len, data->set.out);
-    }
-    else {
-      wrote = len;
-    }
+  /* Chop data, write chunks. */
+  while(len) {
+    size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
+
+    if(writebody) {
+      size_t wrote = writebody(ptr, 1, chunklen, data->set.out);
 
-    if(CURL_WRITEFUNC_PAUSE == wrote) {
-      if(conn->handler->flags & PROTOPT_NONETWORK) {
-        /* Protocols that work without network cannot be paused. This is
-           actually only FILE:// just now, and it can't pause since the
-           transfer isn't done using the "normal" procedure. */
-        failf(data, "Write callback asked for PAUSE when not supported!");
+      if(CURL_WRITEFUNC_PAUSE == wrote) {
+        if(conn->handler->flags & PROTOPT_NONETWORK) {
+          /* Protocols that work without network cannot be paused. This is
+             actually only FILE:// just now, and it can't pause since the
+             transfer isn't done using the "normal" procedure. */
+          failf(data, "Write callback asked for PAUSE when not supported!");
+          return CURLE_WRITE_ERROR;
+        }
+        else
+          return pausewrite(data, type, ptr, len);
+      }
+      else if(wrote != chunklen) {
+        failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
         return CURLE_WRITE_ERROR;
       }
-      else
-        return pausewrite(data, type, ptr, len);
     }
-    else if(wrote != len) {
-      failf(data, "Failed writing body (%zu != %zu)", wrote, len);
-      return CURLE_WRITE_ERROR;
-    }
-  }
 
-  if((type & CLIENTWRITE_HEADER) &&
-     (data->set.fwrite_header || data->set.writeheader) ) {
-    /*
-     * Write headers to the same callback or to the especially setup
-     * header callback function (added after version 7.7.1).
-     */
-    curl_write_callback writeit=
-      data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite_func;
-
-    /* Note: The header is in the host encoding
-       regardless of the ftp transfer mode (ASCII/Image) */
-
-    wrote = writeit(ptr, 1, len, data->set.writeheader);
-    if(CURL_WRITEFUNC_PAUSE == wrote)
-      /* here we pass in the HEADER bit only since if this was body as well
-         then it was passed already and clearly that didn't trigger the pause,
-         so this is saved for later with the HEADER bit only */
-      return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
-
-    if(wrote != len) {
-      failf (data, "Failed writing header");
-      return CURLE_WRITE_ERROR;
+    if(writeheader) {
+      size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader);
+
+      if(CURL_WRITEFUNC_PAUSE == wrote)
+        /* here we pass in the HEADER bit only since if this was body as well
+           then it was passed already and clearly that didn't trigger the
+           pause, so this is saved for later with the HEADER bit only */
+        return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
+
+      if(wrote != chunklen) {
+        failf (data, "Failed writing header");
+        return CURLE_WRITE_ERROR;
+      }
     }
+
+    ptr += chunklen;
+    len -= chunklen;
   }
 
   return CURLE_OK;
 }
 
+
+/* Curl_client_write() sends data to the write callback(s)
+
+   The bit pattern defines to what "streams" to write to. Body and/or header.
+   The defines are in sendf.h of course.
+
+   If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
+   local character encoding.  This is a problem and should be changed in
+   the future to leave the original data alone.
+ */
+CURLcode Curl_client_write(struct connectdata *conn,
+                           int type,
+                           char *ptr,
+                           size_t len)
+{
+  struct SessionHandle *data = conn->data;
+
+  if(0 == len)
+    len = strlen(ptr);
+
+  /* FTP data may need conversion. */
+  if((type & CLIENTWRITE_BODY) &&
+    (conn->handler->protocol & PROTO_FAMILY_FTP) &&
+    conn->proto.ftpc.transfertype == 'A') {
+    /* convert from the network encoding */
+    CURLcode result = Curl_convert_from_network(data, ptr, len);
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    if(result)
+      return result;
+
+#ifdef CURL_DO_LINEEND_CONV
+    /* convert end-of-line markers */
+    len = convert_lineends(data, ptr, len);
+#endif /* CURL_DO_LINEEND_CONV */
+    }
+
+  return Curl_client_chop_write(conn, type, ptr, len);
+}
+
 CURLcode Curl_read_plain(curl_socket_t sockfd,
                          char *buf,
                          size_t bytesfromsocket,
@@ -525,11 +547,11 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
                    size_t sizerequested,     /* max amount to read */
                    ssize_t *n)               /* amount bytes read */
 {
-  CURLcode curlcode = CURLE_RECV_ERROR;
+  CURLcode result = CURLE_RECV_ERROR;
   ssize_t nread = 0;
   size_t bytesfromsocket = 0;
   char *buffertofill = NULL;
-  bool pipelining = Curl_multi_pipeline_enabled(conn->data->multi);
+  bool pipelining = Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1);
 
   /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
      If it is the second socket, we set num to 1. Otherwise to 0. This lets
@@ -564,9 +586,9 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
     buffertofill = buf;
   }
 
-  nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &curlcode);
+  nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
   if(nread < 0)
-    return curlcode;
+    return result;
 
   if(pipelining) {
     memcpy(buf, conn->master_buffer, nread);
@@ -661,11 +683,13 @@ int Curl_debug(struct SessionHandle *data, curl_infotype type,
     switch (type) {
     case CURLINFO_HEADER_IN:
       w = "Header";
+      /* FALLTHROUGH */
     case CURLINFO_DATA_IN:
       t = "from";
       break;
     case CURLINFO_HEADER_OUT:
       w = "Header";
+      /* FALLTHROUGH */
     case CURLINFO_DATA_OUT:
       t = "to";
       break;
diff --git a/Utilities/cmcurl/lib/sendf.h b/Utilities/cmcurl/lib/sendf.h
index 39489e4..86f06cf 100644
--- a/Utilities/cmcurl/lib/sendf.h
+++ b/Utilities/cmcurl/lib/sendf.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -51,8 +51,10 @@ void Curl_failf(struct SessionHandle *, const char *fmt, ...);
 #define CLIENTWRITE_HEADER (1<<1)
 #define CLIENTWRITE_BOTH   (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
 
+CURLcode Curl_client_chop_write(struct connectdata *conn, int type, char *ptr,
+                                size_t len) WARN_UNUSED_RESULT;
 CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr,
-                           size_t len);
+                           size_t len) WARN_UNUSED_RESULT;
 
 /* internal read-function, does plain socket only */
 CURLcode Curl_read_plain(curl_socket_t sockfd,
diff --git a/Utilities/cmcurl/lib/setup-os400.h b/Utilities/cmcurl/lib/setup-os400.h
index 0331464..fae8567 100644
--- a/Utilities/cmcurl/lib/setup-os400.h
+++ b/Utilities/cmcurl/lib/setup-os400.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -37,7 +37,6 @@ typedef unsigned long   u_int32_t;
 
 #include <sys/socket.h>
 #include <netdb.h>
-#include <qsossl.h>
 #include <gskssl.h>
 #include <qsoasync.h>
 #include <gssapi.h>
@@ -57,21 +56,6 @@ extern int      Curl_getnameinfo_a(const struct sockaddr * sa,
 #define getnameinfo             Curl_getnameinfo_a
 
 
-/* SSL wrappers. */
-
-extern int      Curl_SSL_Init_Application_a(SSLInitApp * init_app);
-#define SSL_Init_Application    Curl_SSL_Init_Application_a
-
-
-extern int      Curl_SSL_Init_a(SSLInit * init);
-#define SSL_Init                Curl_SSL_Init_a
-
-
-extern char *   Curl_SSL_Strerror_a(int sslreturnvalue,
-                                    SSLErrorMsg * serrmsgp);
-#define SSL_Strerror            Curl_SSL_Strerror_a
-
-
 /* GSKit wrappers. */
 
 extern int      Curl_gsk_environment_open(gsk_handle * my_env_handle);
diff --git a/Utilities/cmcurl/lib/setup-vms.h b/Utilities/cmcurl/lib/setup-vms.h
index f5eedf7..520a35d 100644
--- a/Utilities/cmcurl/lib/setup-vms.h
+++ b/Utilities/cmcurl/lib/setup-vms.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -203,6 +203,19 @@ char * unix_path;
 #define CRYPTO_cleanup_all_ex_data CRYPTO_CLEANUP_ALL_EX_DATA
 #define CRYPTO_free CRYPTO_FREE
 #define CRYPTO_malloc CRYPTO_MALLOC
+#define CONF_modules_load_file CONF_MODULES_LOAD_FILE
+#ifdef __VAX
+#  ifdef VMS_OLD_SSL
+  /* Ancient OpenSSL on VAX/VMS missing this constant */
+#    define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10
+#    undef CONF_modules_load_file
+     static int CONF_modules_load_file(const char *filename,
+                                       const char *appname,
+                                       unsigned long flags) {
+             return 1;
+     }
+#  endif
+#endif
 #define DES_ecb_encrypt DES_ECB_ENCRYPT
 #define DES_set_key DES_SET_KEY
 #define DES_set_odd_parity DES_SET_ODD_PARITY
@@ -228,6 +241,7 @@ char * unix_path;
 #define EVP_PKEY_free EVP_PKEY_FREE
 #define EVP_cleanup EVP_CLEANUP
 #define GENERAL_NAMES_free GENERAL_NAMES_FREE
+#define i2d_X509_PUBKEY I2D_X509_PUBKEY
 #define MD4_Final MD4_FINAL
 #define MD4_Init MD4_INIT
 #define MD4_Update MD4_UPDATE
@@ -235,6 +249,9 @@ char * unix_path;
 #define MD5_Init MD5_INIT
 #define MD5_Update MD5_UPDATE
 #define OPENSSL_add_all_algo_noconf OPENSSL_ADD_ALL_ALGO_NOCONF
+#ifndef __VAX
+#define OPENSSL_load_builtin_modules OPENSSL_LOAD_BUILTIN_MODULES
+#endif
 #define PEM_read_X509 PEM_READ_X509
 #define PEM_write_bio_X509 PEM_WRITE_BIO_X509
 #define PKCS12_PBE_add PKCS12_PBE_ADD
@@ -258,6 +275,7 @@ char * unix_path;
 #define SSL_CTX_set_cipher_list SSL_CTX_SET_CIPHER_LIST
 #define SSL_CTX_set_def_passwd_cb_ud SSL_CTX_SET_DEF_PASSWD_CB_UD
 #define SSL_CTX_set_default_passwd_cb SSL_CTX_SET_DEFAULT_PASSWD_CB
+#define SSL_CTX_set_msg_callback SSL_CTX_SET_MSG_CALLBACK
 #define SSL_CTX_set_verify SSL_CTX_SET_VERIFY
 #define SSL_CTX_use_PrivateKey SSL_CTX_USE_PRIVATEKEY
 #define SSL_CTX_use_PrivateKey_file SSL_CTX_USE_PRIVATEKEY_FILE
@@ -274,6 +292,7 @@ char * unix_path;
 #define SSL_get_peer_cert_chain SSL_GET_PEER_CERT_CHAIN
 #define SSL_get_peer_certificate SSL_GET_PEER_CERTIFICATE
 #define SSL_get_privatekey SSL_GET_PRIVATEKEY
+#define SSL_get_session SSL_GET_SESSION
 #define SSL_get_shutdown SSL_GET_SHUTDOWN
 #define SSL_get_verify_result SSL_GET_VERIFY_RESULT
 #define SSL_library_init SSL_LIBRARY_INIT
@@ -286,14 +305,32 @@ char * unix_path;
 #define SSL_set_fd SSL_SET_FD
 #define SSL_set_session SSL_SET_SESSION
 #define SSL_shutdown SSL_SHUTDOWN
+#define SSL_version SSL_VERSION
 #define SSL_write SSL_WRITE
 #define SSLeay SSLEAY
 #define SSLv23_client_method SSLV23_CLIENT_METHOD
 #define SSLv3_client_method SSLV3_CLIENT_METHOD
 #define TLSv1_client_method TLSV1_CLIENT_METHOD
+#define UI_create_method UI_CREATE_METHOD
+#define UI_destroy_method UI_DESTROY_METHOD
+#define UI_get0_user_data UI_GET0_USER_DATA
+#define UI_get_input_flags UI_GET_INPUT_FLAGS
+#define UI_get_string_type UI_GET_STRING_TYPE
+#define UI_create_method UI_CREATE_METHOD
+#define UI_destroy_method UI_DESTROY_METHOD
+#define UI_method_get_closer UI_METHOD_GET_CLOSER
+#define UI_method_get_opener UI_METHOD_GET_OPENER
+#define UI_method_get_reader UI_METHOD_GET_READER
+#define UI_method_get_writer UI_METHOD_GET_WRITER
+#define UI_method_set_closer UI_METHOD_SET_CLOSER
+#define UI_method_set_opener UI_METHOD_SET_OPENER
+#define UI_method_set_reader UI_METHOD_SET_READER
+#define UI_method_set_writer UI_METHOD_SET_WRITER
 #define UI_OpenSSL UI_OPENSSL
+#define UI_set_result UI_SET_RESULT
 #define X509V3_EXT_print X509V3_EXT_PRINT
 #define X509_EXTENSION_get_critical X509_EXTENSION_GET_CRITICAL
+#define X509_EXTENSION_get_data X509_EXTENSION_GET_DATA
 #define X509_EXTENSION_get_object X509_EXTENSION_GET_OBJECT
 #define X509_LOOKUP_file X509_LOOKUP_FILE
 #define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_GET_DATA
@@ -318,6 +355,12 @@ char * unix_path;
 #define sk_pop SK_POP
 #define sk_pop_free SK_POP_FREE
 #define sk_value SK_VALUE
+#ifdef __VAX
+#define OPENSSL_NO_SHA256
+#endif
+#define SHA256_Final SHA256_FINAL
+#define SHA256_Init SHA256_INIT
+#define SHA256_Update SHA256_UPDATE
 
 #define USE_UPPERCASE_GSSAPI 1
 #define gss_seal GSS_SEAL
@@ -383,7 +426,7 @@ char * unix_path;
 
         static void des_ecb_encrypt(const_des_cblock *input,
                                     des_cblock *output,
-                                    des_key_schedule ks,int enc) {
+                                    des_key_schedule ks, int enc) {
             DES_ECB_ENCRYPT(input, output, ks, enc);
         }
 #endif
diff --git a/Utilities/cmcurl/lib/share.c b/Utilities/cmcurl/lib/share.c
index b8b6bee..1720248 100644
--- a/Utilities/cmcurl/lib/share.c
+++ b/Utilities/cmcurl/lib/share.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,9 +35,15 @@ CURLSH *
 curl_share_init(void)
 {
   struct Curl_share *share = calloc(1, sizeof(struct Curl_share));
-  if(share)
+  if(share) {
     share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
 
+    if(Curl_mk_dnscache(&share->hostcache)) {
+      free(share);
+      return NULL;
+    }
+  }
+
   return share;
 }
 
@@ -67,11 +73,6 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
     share->specifier |= (1<<type);
     switch( type ) {
     case CURL_LOCK_DATA_DNS:
-      if(!share->hostcache) {
-        share->hostcache = Curl_mk_dnscache();
-        if(!share->hostcache)
-          res = CURLSHE_NOMEM;
-      }
       break;
 
     case CURL_LOCK_DATA_COOKIE:
@@ -115,10 +116,6 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
     share->specifier &= ~(1<<type);
     switch( type ) {
     case CURL_LOCK_DATA_DNS:
-      if(share->hostcache) {
-        Curl_hash_destroy(share->hostcache);
-        share->hostcache = NULL;
-      }
       break;
 
     case CURL_LOCK_DATA_COOKIE:
@@ -192,14 +189,10 @@ curl_share_cleanup(CURLSH *sh)
     return CURLSHE_IN_USE;
   }
 
-  if(share->hostcache) {
-    Curl_hash_destroy(share->hostcache);
-    share->hostcache = NULL;
-  }
+  Curl_hash_destroy(&share->hostcache);
 
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
-  if(share->cookies)
-    Curl_cookie_cleanup(share->cookies);
+  Curl_cookie_cleanup(share->cookies);
 #endif
 
 #ifdef USE_SSL
diff --git a/Utilities/cmcurl/lib/share.h b/Utilities/cmcurl/lib/share.h
index 9a5128e..8e6629b 100644
--- a/Utilities/cmcurl/lib/share.h
+++ b/Utilities/cmcurl/lib/share.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -44,7 +44,7 @@ struct Curl_share {
   curl_unlock_function unlockfunc;
   void *clientdata;
 
-  struct curl_hash *hostcache;
+  struct curl_hash hostcache;
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
   struct CookieInfo *cookies;
 #endif
diff --git a/Utilities/cmcurl/lib/slist.c b/Utilities/cmcurl/lib/slist.c
index 3cac6ca..9c0b2a5 100644
--- a/Utilities/cmcurl/lib/slist.c
+++ b/Utilities/cmcurl/lib/slist.c
@@ -22,10 +22,10 @@
 
 #include "curl_setup.h"
 
-#include "curl_memory.h"
 #include "slist.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /* returns last node in linked list */
diff --git a/Utilities/cmcurl/lib/smb.c b/Utilities/cmcurl/lib/smb.c
new file mode 100644
index 0000000..d461a71
--- /dev/null
+++ b/Utilities/cmcurl/lib/smb.c
@@ -0,0 +1,976 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014, Bill Nagel <wnagel at tycoint.com>, Exacq Technologies
+ * Copyright (C) 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+    (CURL_SIZEOF_CURL_OFF_T > 4)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#define BUILDING_CURL_SMB_C
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#define getpid _getpid
+#endif
+
+#include "smb.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "connect.h"
+#include "progress.h"
+#include "transfer.h"
+#include "vtls/vtls.h"
+#include "curl_ntlm_core.h"
+#include "escape.h"
+#include "curl_endian.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode smb_setup_connection(struct connectdata *conn);
+static CURLcode smb_connect(struct connectdata *conn, bool *done);
+static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
+static CURLcode smb_request_state(struct connectdata *conn, bool *done);
+static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+                         bool premature);
+static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
+                       int numsocks);
+static CURLcode smb_parse_url_path(struct connectdata *conn);
+
+/*
+ * SMB handler interface
+ */
+const struct Curl_handler Curl_handler_smb = {
+  "SMB",                                /* scheme */
+  smb_setup_connection,                 /* setup_connection */
+  ZERO_NULL,                            /* do_it */
+  smb_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  smb_connect,                          /* connect_it */
+  smb_connection_state,                 /* connecting */
+  smb_request_state,                    /* doing */
+  smb_getsock,                          /* proto_getsock */
+  smb_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  smb_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_SMB,                             /* defport */
+  CURLPROTO_SMB,                        /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * SMBS handler interface
+ */
+const struct Curl_handler Curl_handler_smbs = {
+  "SMBS",                               /* scheme */
+  smb_setup_connection,                 /* setup_connection */
+  ZERO_NULL,                            /* do_it */
+  smb_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  smb_connect,                          /* connect_it */
+  smb_connection_state,                 /* connecting */
+  smb_request_state,                    /* doing */
+  smb_getsock,                          /* proto_getsock */
+  smb_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  smb_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  PORT_SMBS,                            /* defport */
+  CURLPROTO_SMBS,                       /* protocol */
+  PROTOPT_SSL                           /* flags */
+};
+#endif
+
+#define MAX_PAYLOAD_SIZE  0x8000
+#define MAX_MESSAGE_SIZE  (MAX_PAYLOAD_SIZE + 0x1000)
+#define CLIENTNAME        "curl"
+#define SERVICENAME       "?????"
+
+/* Append a string to an SMB message */
+#define MSGCAT(str) \
+  strcpy(p, (str)); \
+  p += strlen(str);
+
+/* Append a null-terminated string to an SMB message */
+#define MSGCATNULL(str) \
+  strcpy(p, (str)); \
+  p += strlen(str) + 1;
+
+/* SMB is mostly little endian */
+#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
+   defined(__OS400__)
+static unsigned short smb_swap16(unsigned short x)
+{
+  return (x << 8) | ((x >> 8) & 0xff);
+}
+
+static unsigned int smb_swap32(unsigned int x)
+{
+  return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
+         ((x >> 24) & 0xff);
+}
+
+#ifdef HAVE_LONGLONG
+static unsigned long long smb_swap64(unsigned long long x)
+{
+  return ((unsigned long long)smb_swap32(x) << 32) | smb_swap32(x >> 32);
+}
+#else
+static unsigned __int64 smb_swap64(unsigned __int64 x)
+{
+  return ((unsigned __int64)smb_swap32(x) << 32) | smb_swap32(x >> 32);
+}
+#endif
+#else
+#  define smb_swap16(x) (x)
+#  define smb_swap32(x) (x)
+#  define smb_swap64(x) (x)
+#endif
+
+/* SMB request state */
+enum smb_req_state {
+  SMB_REQUESTING,
+  SMB_TREE_CONNECT,
+  SMB_OPEN,
+  SMB_DOWNLOAD,
+  SMB_UPLOAD,
+  SMB_CLOSE,
+  SMB_TREE_DISCONNECT,
+  SMB_DONE
+};
+
+/* SMB request data */
+struct smb_request {
+  enum smb_req_state state;
+  char *share;
+  char *path;
+  unsigned short tid; /* Even if we connect to the same tree as another */
+  unsigned short fid; /* request, the tid will be different */
+  CURLcode result;
+};
+
+static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
+{
+  struct smb_conn *smb = &conn->proto.smbc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* For debug purposes */
+  static const char * const names[] = {
+    "SMB_NOT_CONNECTED",
+    "SMB_CONNECTING",
+    "SMB_NEGOTIATE",
+    "SMB_SETUP",
+    "SMB_CONNECTED",
+    /* LAST */
+  };
+
+  if(smb->state != newstate)
+    infof(conn->data, "SMB conn %p state change from %s to %s\n",
+    (void *)smb, names[smb->state], names[newstate]);
+#endif
+
+  smb->state = newstate;
+}
+
+static void request_state(struct connectdata *conn,
+                          enum smb_req_state newstate)
+{
+  struct smb_request *req = conn->data->req.protop;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* For debug purposes */
+  static const char * const names[] = {
+    "SMB_REQUESTING",
+    "SMB_TREE_CONNECT",
+    "SMB_OPEN",
+    "SMB_DOWNLOAD",
+    "SMB_UPLOAD",
+    "SMB_CLOSE",
+    "SMB_TREE_DISCONNECT",
+    "SMB_DONE",
+    /* LAST */
+  };
+
+  if(req->state != newstate)
+    infof(conn->data, "SMB request %p state change from %s to %s\n",
+    (void *)req, names[req->state], names[newstate]);
+#endif
+
+  req->state = newstate;
+}
+
+static CURLcode smb_setup_connection(struct connectdata *conn)
+{
+  struct smb_request *req;
+
+  /* Initialize the request state */
+  conn->data->req.protop = req = calloc(1, sizeof(struct smb_request));
+  if(!req)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Parse the URL path */
+  return smb_parse_url_path(conn);
+}
+
+static CURLcode smb_connect(struct connectdata *conn, bool *done)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  char *slash;
+
+  (void) done;
+
+  /* Check we have a username and password to authenticate with */
+  if(!conn->bits.user_passwd)
+    return CURLE_LOGIN_DENIED;
+
+  /* Initialize the connection state */
+  memset(smbc, 0, sizeof(*smbc));
+  smbc->state = SMB_CONNECTING;
+  smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
+  if(!smbc->recv_buf)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Multiple requests are allowed with this connection */
+  connkeep(conn, "SMB default");
+
+  /* Parse the username, domain, and password */
+  slash = strchr(conn->user, '/');
+  if(!slash)
+    slash = strchr(conn->user, '\\');
+
+  if(slash) {
+    smbc->user = slash + 1;
+    smbc->domain = strdup(conn->user);
+    if(!smbc->domain)
+      return CURLE_OUT_OF_MEMORY;
+    smbc->domain[slash - conn->user] = 0;
+  }
+  else {
+    smbc->user = conn->user;
+    smbc->domain = strdup(conn->host.name);
+    if(!smbc->domain)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  char *buf = smbc->recv_buf;
+  ssize_t bytes_read;
+  size_t nbt_size;
+  size_t msg_size;
+  size_t len = MAX_MESSAGE_SIZE - smbc->got;
+  CURLcode result;
+
+  result = Curl_read(conn, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
+  if(result)
+    return result;
+
+  if(!bytes_read)
+    return CURLE_OK;
+
+  smbc->got += bytes_read;
+
+  /* Check for a 32-bit nbt header */
+  if(smbc->got < sizeof(unsigned int))
+    return CURLE_OK;
+
+  nbt_size = Curl_read16_be((unsigned char *)(buf + sizeof(unsigned short))) +
+             sizeof(unsigned int);
+  if(smbc->got < nbt_size)
+    return CURLE_OK;
+
+  msg_size = sizeof(struct smb_header);
+  if(nbt_size >= msg_size + 1) {
+    /* Add the word count */
+    msg_size += 1 + ((unsigned char) buf[msg_size]) * sizeof(unsigned short);
+    if(nbt_size >= msg_size + sizeof(unsigned short)) {
+      /* Add the byte count */
+      msg_size += sizeof(unsigned short) +
+                  Curl_read16_le((unsigned char *)&buf[msg_size]);
+      if(nbt_size < msg_size)
+        return CURLE_READ_ERROR;
+    }
+  }
+
+  *msg = buf;
+
+  return CURLE_OK;
+}
+
+static void smb_pop_message(struct connectdata *conn)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+
+  smbc->got = 0;
+}
+
+static void smb_format_message(struct connectdata *conn, struct smb_header *h,
+                               unsigned char cmd, size_t len)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_request *req = conn->data->req.protop;
+  unsigned int pid;
+
+  memset(h, 0, sizeof(*h));
+  h->nbt_length = htons((unsigned short) (sizeof(*h) - sizeof(unsigned int) +
+                                          len));
+  memcpy((char *)h->magic, "\xffSMB", 4);
+  h->command = cmd;
+  h->flags = SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES;
+  h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME);
+  h->uid = smb_swap16(smbc->uid);
+  h->tid = smb_swap16(req->tid);
+  pid = getpid();
+  h->pid_high = smb_swap16((unsigned short)(pid >> 16));
+  h->pid = smb_swap16((unsigned short) pid);
+}
+
+static CURLcode smb_send(struct connectdata *conn, ssize_t len,
+                         size_t upload_size)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  ssize_t bytes_written;
+  CURLcode result;
+
+  result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer,
+                      len, &bytes_written);
+  if(result)
+    return result;
+
+  if(bytes_written != len) {
+    smbc->send_size = len;
+    smbc->sent = bytes_written;
+  }
+
+  smbc->upload_size = upload_size;
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_flush(struct connectdata *conn)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  ssize_t bytes_written;
+  ssize_t len = smbc->send_size - smbc->sent;
+  CURLcode result;
+
+  if(!smbc->send_size)
+    return CURLE_OK;
+
+  result = Curl_write(conn, FIRSTSOCKET,
+                      conn->data->state.uploadbuffer + smbc->sent,
+                      len, &bytes_written);
+  if(result)
+    return result;
+
+  if(bytes_written != len)
+    smbc->sent += bytes_written;
+  else
+    smbc->send_size = 0;
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
+                                 const void *msg, size_t msg_len)
+{
+  smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer,
+                     cmd, msg_len);
+  memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header),
+         msg, msg_len);
+
+  return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
+}
+
+static CURLcode smb_send_negotiate(struct connectdata *conn)
+{
+  const char *msg = "\x00\x0c\x00\x02NT LM 0.12";
+
+  return smb_send_message(conn, SMB_COM_NEGOTIATE, msg, 15);
+}
+
+static CURLcode smb_send_setup(struct connectdata *conn)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_setup msg;
+  char *p = msg.bytes;
+  unsigned char lm_hash[21];
+  unsigned char lm[24];
+  unsigned char nt_hash[21];
+  unsigned char nt[24];
+
+  size_t byte_count = sizeof(lm) + sizeof(nt);
+  byte_count += strlen(smbc->user) + strlen(smbc->domain);
+  byte_count += strlen(OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */
+  if(byte_count > sizeof(msg.bytes))
+    return CURLE_FILESIZE_EXCEEDED;
+
+  Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash);
+  Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
+#if USE_NTRESPONSES
+  Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash);
+  Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
+#else
+  memset(nt, 0, sizeof(nt));
+#endif
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_SETUP_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE);
+  msg.max_mpx_count = smb_swap16(1);
+  msg.vc_number = smb_swap16(1);
+  msg.session_key = smb_swap32(smbc->session_key);
+  msg.capabilities = smb_swap32(SMB_CAP_LARGE_FILES);
+  msg.lengths[0] = smb_swap16(sizeof(lm));
+  msg.lengths[1] = smb_swap16(sizeof(nt));
+  memcpy(p, lm, sizeof(lm));
+  p += sizeof(lm);
+  memcpy(p, nt, sizeof(nt));
+  p += sizeof(nt);
+  MSGCATNULL(smbc->user);
+  MSGCATNULL(smbc->domain);
+  MSGCATNULL(OS);
+  MSGCATNULL(CLIENTNAME);
+  byte_count = p - msg.bytes;
+  msg.byte_count = smb_swap16((unsigned short)byte_count);
+
+  return smb_send_message(conn, SMB_COM_SETUP_ANDX, &msg,
+                          sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_tree_connect(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_tree_connect msg;
+  char *p = msg.bytes;
+
+  size_t byte_count = strlen(conn->host.name) + strlen(req->share);
+  byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
+  if(byte_count > sizeof(msg.bytes))
+    return CURLE_FILESIZE_EXCEEDED;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_TREE_CONNECT_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg.pw_len = 0;
+  MSGCAT("\\\\");
+  MSGCAT(conn->host.name);
+  MSGCAT("\\");
+  MSGCATNULL(req->share);
+  MSGCATNULL(SERVICENAME); /* Match any type of service */
+  byte_count = p - msg.bytes;
+  msg.byte_count = smb_swap16((unsigned short)byte_count);
+
+  return smb_send_message(conn, SMB_COM_TREE_CONNECT_ANDX, &msg,
+                          sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_open(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_nt_create msg;
+  size_t byte_count;
+
+  if((strlen(req->path) + 1) > sizeof(msg.bytes))
+    return CURLE_FILESIZE_EXCEEDED;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_NT_CREATE_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  byte_count = strlen(req->path);
+  msg.name_length = smb_swap16((unsigned short)byte_count);
+  msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
+  if(conn->data->set.upload) {
+    msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
+    msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
+  }
+  else {
+    msg.access = smb_swap32(SMB_GENERIC_READ);
+    msg.create_disposition = smb_swap32(SMB_FILE_OPEN);
+  }
+  msg.byte_count = smb_swap16((unsigned short) ++byte_count);
+  strcpy(msg.bytes, req->path);
+
+  return smb_send_message(conn, SMB_COM_NT_CREATE_ANDX, &msg,
+                          sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_close(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_close msg;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_CLOSE;
+  msg.fid = smb_swap16(req->fid);
+
+  return smb_send_message(conn, SMB_COM_CLOSE, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_tree_disconnect(struct connectdata *conn)
+{
+  struct smb_tree_disconnect msg;
+
+  memset(&msg, 0, sizeof(msg));
+
+  return smb_send_message(conn, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_read(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  curl_off_t offset = conn->data->req.offset;
+  struct smb_read msg;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_READ_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg.fid = smb_swap16(req->fid);
+  msg.offset = smb_swap32((unsigned int) offset);
+  msg.offset_high = smb_swap32((unsigned int) (offset >> 32));
+  msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
+  msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
+
+  return smb_send_message(conn, SMB_COM_READ_ANDX, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_write(struct connectdata *conn)
+{
+  struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer;
+  struct smb_request *req = conn->data->req.protop;
+  curl_off_t offset = conn->data->req.offset;
+
+  curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
+  if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
+    upload_size = MAX_PAYLOAD_SIZE - 1;
+
+  memset(msg, 0, sizeof(*msg));
+  msg->word_count = SMB_WC_WRITE_ANDX;
+  msg->andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg->fid = smb_swap16(req->fid);
+  msg->offset = smb_swap32((unsigned int) offset);
+  msg->offset_high = smb_swap32((unsigned int) (offset >> 32));
+  msg->data_length = smb_swap16((unsigned short) upload_size);
+  msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
+  msg->byte_count = smb_swap16((unsigned short) (upload_size + 1));
+
+  smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX,
+                     sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size);
+
+  return smb_send(conn, sizeof(*msg), (size_t) upload_size);
+}
+
+static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  CURLcode result;
+
+  /* Check if there is data in the transfer buffer */
+  if(!smbc->send_size && smbc->upload_size) {
+    int nread = smbc->upload_size > BUFSIZE ? BUFSIZE :
+                                              (int) smbc->upload_size;
+    conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
+    result = Curl_fillreadbuffer(conn, nread, &nread);
+    if(result && result != CURLE_AGAIN)
+      return result;
+    if(!nread)
+      return CURLE_OK;
+
+    smbc->upload_size -= nread;
+    smbc->send_size = nread;
+    smbc->sent = 0;
+  }
+
+  /* Check if there is data to send */
+  if(smbc->send_size) {
+    result = smb_flush(conn);
+    if(result)
+      return result;
+  }
+
+  /* Check if there is still data to be sent */
+  if(smbc->send_size || smbc->upload_size)
+    return CURLE_AGAIN;
+
+  return smb_recv_message(conn, msg);
+}
+
+static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_negotiate_response *nrsp;
+  struct smb_header *h;
+  CURLcode result;
+  void *msg = NULL;
+
+  if(smbc->state == SMB_CONNECTING) {
+#ifdef USE_SSL
+    if((conn->handler->flags & PROTOPT_SSL)) {
+      bool ssl_done;
+      result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &ssl_done);
+      if(result && result != CURLE_AGAIN)
+        return result;
+      if(!ssl_done)
+        return CURLE_OK;
+    }
+#endif
+
+    result = smb_send_negotiate(conn);
+    if(result) {
+      connclose(conn, "SMB: failed to send negotiate message");
+      return result;
+    }
+
+    conn_state(conn, SMB_NEGOTIATE);
+  }
+
+  /* Send the previous message and check for a response */
+  result = smb_send_and_recv(conn, &msg);
+  if(result && result != CURLE_AGAIN) {
+    connclose(conn, "SMB: failed to communicate");
+    return result;
+  }
+
+  if(!msg)
+    return CURLE_OK;
+
+  h = msg;
+
+  switch(smbc->state) {
+  case SMB_NEGOTIATE:
+    if(h->status) {
+      connclose(conn, "SMB: negotiation failed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    nrsp = msg;
+    memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge));
+    smbc->session_key = smb_swap32(nrsp->session_key);
+    result = smb_send_setup(conn);
+    if(result) {
+      connclose(conn, "SMB: failed to send setup message");
+      return result;
+    }
+    conn_state(conn, SMB_SETUP);
+    break;
+
+  case SMB_SETUP:
+    if(h->status) {
+      connclose(conn, "SMB: authentication failed");
+      return CURLE_LOGIN_DENIED;
+    }
+    smbc->uid = smb_swap16(h->uid);
+    conn_state(conn, SMB_CONNECTED);
+    *done = true;
+    break;
+
+  default:
+    smb_pop_message(conn);
+    return CURLE_OK; /* ignore */
+  }
+
+  smb_pop_message(conn);
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_request_state(struct connectdata *conn, bool *done)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_header *h;
+  enum smb_req_state next_state = SMB_DONE;
+  unsigned short len;
+  unsigned short off;
+  CURLcode result;
+  void *msg = NULL;
+
+  /* Start the request */
+  if(req->state == SMB_REQUESTING) {
+    result = smb_send_tree_connect(conn);
+    if(result) {
+      connclose(conn, "SMB: failed to send tree connect message");
+      return result;
+    }
+
+    request_state(conn, SMB_TREE_CONNECT);
+  }
+
+  /* Send the previous message and check for a response */
+  result = smb_send_and_recv(conn, &msg);
+  if(result && result != CURLE_AGAIN) {
+    connclose(conn, "SMB: failed to communicate");
+    return result;
+  }
+
+  if(!msg)
+    return CURLE_OK;
+
+  h = msg;
+
+  switch(req->state) {
+  case SMB_TREE_CONNECT:
+    if(h->status) {
+      req->result = CURLE_REMOTE_FILE_NOT_FOUND;
+      if(h->status == smb_swap32(SMB_ERR_NOACCESS))
+        req->result = CURLE_REMOTE_ACCESS_DENIED;
+      break;
+    }
+    req->tid = smb_swap16(h->tid);
+    next_state = SMB_OPEN;
+    break;
+
+  case SMB_OPEN:
+    if(h->status) {
+      req->result = CURLE_REMOTE_FILE_NOT_FOUND;
+      next_state = SMB_TREE_DISCONNECT;
+      break;
+    }
+    req->fid = smb_swap16(((struct smb_nt_create_response *)msg)->fid);
+    conn->data->req.offset = 0;
+    if(conn->data->set.upload) {
+      conn->data->req.size = conn->data->state.infilesize;
+      Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
+      next_state = SMB_UPLOAD;
+    }
+    else {
+      conn->data->req.size =
+        smb_swap64(((struct smb_nt_create_response *)msg)->end_of_file);
+      Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size);
+      next_state = SMB_DOWNLOAD;
+    }
+    break;
+
+  case SMB_DOWNLOAD:
+    if(h->status) {
+      req->result = CURLE_RECV_ERROR;
+      next_state = SMB_CLOSE;
+      break;
+    }
+    len = Curl_read16_le(((unsigned char *) msg) +
+                         sizeof(struct smb_header) + 11);
+    off = Curl_read16_le(((unsigned char *) msg) +
+                         sizeof(struct smb_header) + 13);
+    if(len > 0) {
+      struct smb_conn *smbc = &conn->proto.smbc;
+      if(off + sizeof(unsigned int) + len > smbc->got) {
+        failf(conn->data, "Invalid input packet");
+        result = CURLE_RECV_ERROR;
+      }
+      else
+        result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                   (char *)msg + off + sizeof(unsigned int),
+                                   len);
+      if(result) {
+        req->result = result;
+        next_state = SMB_CLOSE;
+        break;
+      }
+    }
+    conn->data->req.bytecount += len;
+    conn->data->req.offset += len;
+    Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount);
+    next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD;
+    break;
+
+  case SMB_UPLOAD:
+    if(h->status) {
+      req->result = CURLE_UPLOAD_FAILED;
+      next_state = SMB_CLOSE;
+      break;
+    }
+    len = Curl_read16_le(((unsigned char *) msg) +
+                         sizeof(struct smb_header) + 5);
+    conn->data->req.bytecount += len;
+    conn->data->req.offset += len;
+    Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount);
+    if(conn->data->req.bytecount >= conn->data->req.size)
+      next_state = SMB_CLOSE;
+    else
+      next_state = SMB_UPLOAD;
+    break;
+
+  case SMB_CLOSE:
+    /* We don't care if the close failed, proceed to tree disconnect anyway */
+    next_state = SMB_TREE_DISCONNECT;
+    break;
+
+  case SMB_TREE_DISCONNECT:
+    next_state = SMB_DONE;
+    break;
+
+  default:
+    smb_pop_message(conn);
+    return CURLE_OK; /* ignore */
+  }
+
+  smb_pop_message(conn);
+
+  switch(next_state) {
+  case SMB_OPEN:
+    result = smb_send_open(conn);
+    break;
+
+  case SMB_DOWNLOAD:
+    result = smb_send_read(conn);
+    break;
+
+  case SMB_UPLOAD:
+    result = smb_send_write(conn);
+    break;
+
+  case SMB_CLOSE:
+    result = smb_send_close(conn);
+    break;
+
+  case SMB_TREE_DISCONNECT:
+    result = smb_send_tree_disconnect(conn);
+    break;
+
+  case SMB_DONE:
+    result = req->result;
+    *done = true;
+    break;
+
+  default:
+    break;
+  }
+
+  if(result) {
+    connclose(conn, "SMB: failed to send message");
+    return result;
+  }
+
+  request_state(conn, next_state);
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  struct smb_request *req = conn->data->req.protop;
+
+  (void) premature;
+
+  Curl_safefree(req->share);
+  Curl_safefree(conn->data->req.protop);
+
+  return status;
+}
+
+static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_request *req = conn->data->req.protop;
+
+  (void) dead;
+
+  Curl_safefree(smbc->domain);
+  Curl_safefree(smbc->recv_buf);
+
+  /* smb_done is not always called, so cleanup the request */
+  if(req) {
+    Curl_safefree(req->share);
+    Curl_safefree(conn->data->req.protop);
+  }
+
+  return CURLE_OK;
+}
+
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
+                       int numsocks)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  socks[0] = conn->sock[FIRSTSOCKET];
+
+  if(smbc->send_size || smbc->upload_size)
+    return GETSOCK_WRITESOCK(0);
+
+  return GETSOCK_READSOCK(0);
+}
+
+static CURLcode smb_parse_url_path(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct smb_request *req = data->req.protop;
+  char *path;
+  char *slash;
+
+  /* URL decode the path */
+  result = Curl_urldecode(data, data->state.path, 0, &path, NULL, TRUE);
+  if(result)
+    return result;
+
+  /* Parse the path for the share */
+  req->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
+  if(!req->share) {
+    free(path);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  slash = strchr(req->share, '/');
+  if(!slash)
+    slash = strchr(req->share, '\\');
+
+  /* The share must be present */
+  if(!slash) {
+    free(path);
+
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Parse the path for the file path converting any forward slashes into
+     backslashes */
+  *slash++ = 0;
+  req->path = slash;
+  for(; *slash; slash++) {
+    if(*slash == '/')
+      *slash = '\\';
+  }
+
+  free(path);
+
+  return CURLE_OK;
+}
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
diff --git a/Utilities/cmcurl/lib/smb.h b/Utilities/cmcurl/lib/smb.h
new file mode 100644
index 0000000..7852fa1
--- /dev/null
+++ b/Utilities/cmcurl/lib/smb.h
@@ -0,0 +1,271 @@
+#ifndef HEADER_CURL_SMB_H
+#define HEADER_CURL_SMB_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014, Bill Nagel <wnagel at tycoint.com>, Exacq Technologies
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+enum smb_conn_state {
+  SMB_NOT_CONNECTED = 0,
+  SMB_CONNECTING,
+  SMB_NEGOTIATE,
+  SMB_SETUP,
+  SMB_CONNECTED
+};
+
+struct smb_conn {
+  enum smb_conn_state state;
+  char *user;
+  char *domain;
+  unsigned char challenge[8];
+  unsigned int session_key;
+  unsigned short uid;
+  char *recv_buf;
+  size_t upload_size;
+  size_t send_size;
+  size_t sent;
+  size_t got;
+};
+
+/*
+ * Definitions for SMB protocol data structures
+ */
+#ifdef BUILDING_CURL_SMB_C
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+#  define PACK
+#  pragma pack(push)
+#  pragma pack(1)
+#elif defined(__GNUC__)
+#  define PACK __attribute__((packed))
+#else
+#  define PACK
+#endif
+
+#define SMB_COM_CLOSE                 0x04
+#define SMB_COM_READ_ANDX             0x2e
+#define SMB_COM_WRITE_ANDX            0x2f
+#define SMB_COM_TREE_DISCONNECT       0x71
+#define SMB_COM_NEGOTIATE             0x72
+#define SMB_COM_SETUP_ANDX            0x73
+#define SMB_COM_TREE_CONNECT_ANDX     0x75
+#define SMB_COM_NT_CREATE_ANDX        0xa2
+#define SMB_COM_NO_ANDX_COMMAND       0xff
+
+#define SMB_WC_CLOSE                  0x03
+#define SMB_WC_READ_ANDX              0x0c
+#define SMB_WC_WRITE_ANDX             0x0e
+#define SMB_WC_SETUP_ANDX             0x0d
+#define SMB_WC_TREE_CONNECT_ANDX      0x04
+#define SMB_WC_NT_CREATE_ANDX         0x18
+
+#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
+#define SMB_FLAGS_CASELESS_PATHNAMES  0x08
+#define SMB_FLAGS2_UNICODE_STRINGS    0x8000
+#define SMB_FLAGS2_IS_LONG_NAME       0x0040
+#define SMB_FLAGS2_KNOWS_LONG_NAME    0x0001
+
+#define SMB_CAP_LARGE_FILES           0x08
+#define SMB_GENERIC_WRITE             0x40000000
+#define SMB_GENERIC_READ              0x80000000
+#define SMB_FILE_SHARE_ALL            0x07
+#define SMB_FILE_OPEN                 0x01
+#define SMB_FILE_OVERWRITE_IF         0x05
+
+#define SMB_ERR_NOACCESS              0x00050001
+
+struct smb_header {
+  unsigned char nbt_type;
+  unsigned char nbt_flags;
+  unsigned short nbt_length;
+  unsigned char magic[4];
+  unsigned char command;
+  unsigned int status;
+  unsigned char flags;
+  unsigned short flags2;
+  unsigned short pid_high;
+  unsigned char signature[8];
+  unsigned short pad;
+  unsigned short tid;
+  unsigned short pid;
+  unsigned short uid;
+  unsigned short mid;
+} PACK;
+
+struct smb_negotiate_response {
+  struct smb_header h;
+  unsigned char word_count;
+  unsigned short dialect_index;
+  unsigned char security_mode;
+  unsigned short max_mpx_count;
+  unsigned short max_number_vcs;
+  unsigned int max_buffer_size;
+  unsigned int max_raw_size;
+  unsigned int session_key;
+  unsigned int capabilities;
+  unsigned int system_time_low;
+  unsigned int system_time_high;
+  unsigned short server_time_zone;
+  unsigned char encryption_key_length;
+  unsigned short byte_count;
+  char bytes[1];
+} PACK;
+
+struct andx {
+  unsigned char command;
+  unsigned char pad;
+  unsigned short offset;
+} PACK;
+
+struct smb_setup {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short max_buffer_size;
+  unsigned short max_mpx_count;
+  unsigned short vc_number;
+  unsigned int session_key;
+  unsigned short lengths[2];
+  unsigned int pad;
+  unsigned int capabilities;
+  unsigned short byte_count;
+  char bytes[1024];
+} PACK;
+
+struct smb_tree_connect {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short flags;
+  unsigned short pw_len;
+  unsigned short byte_count;
+  char bytes[1024];
+} PACK;
+
+struct smb_nt_create {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned char pad;
+  unsigned short name_length;
+  unsigned int flags;
+  unsigned int root_fid;
+  unsigned int access;
+#ifdef HAVE_LONGLONG
+  unsigned long long allocation_size;
+#else
+  unsigned __int64 allocation_size;
+#endif
+  unsigned int ext_file_attributes;
+  unsigned int share_access;
+  unsigned int create_disposition;
+  unsigned int create_options;
+  unsigned int impersonation_level;
+  unsigned char security_flags;
+  unsigned short byte_count;
+  char bytes[1024];
+} PACK;
+
+struct smb_nt_create_response {
+  struct smb_header h;
+  unsigned char word_count;
+  struct andx andx;
+  unsigned char op_lock_level;
+  unsigned short fid;
+  unsigned int create_disposition;
+#ifdef HAVE_LONGLONG
+  unsigned long long create_time;
+  unsigned long long last_access_time;
+  unsigned long long last_write_time;
+  unsigned long long last_change_time;
+#else
+  unsigned __int64 create_time;
+  unsigned __int64 last_access_time;
+  unsigned __int64 last_write_time;
+  unsigned __int64 last_change_time;
+#endif
+  unsigned int ext_file_attributes;
+#ifdef HAVE_LONGLONG
+  unsigned long long allocation_size;
+  unsigned long long end_of_file;
+#else
+  unsigned __int64 allocation_size;
+  unsigned __int64 end_of_file;
+#endif
+} PACK;
+
+struct smb_read {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short fid;
+  unsigned int offset;
+  unsigned short max_bytes;
+  unsigned short min_bytes;
+  unsigned int timeout;
+  unsigned short remaining;
+  unsigned int offset_high;
+  unsigned short byte_count;
+} PACK;
+
+struct smb_write {
+  struct smb_header h;
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short fid;
+  unsigned int offset;
+  unsigned int timeout;
+  unsigned short write_mode;
+  unsigned short remaining;
+  unsigned short pad;
+  unsigned short data_length;
+  unsigned short data_offset;
+  unsigned int offset_high;
+  unsigned short byte_count;
+  unsigned char pad2;
+} PACK;
+
+struct smb_close {
+  unsigned char word_count;
+  unsigned short fid;
+  unsigned int last_mtime;
+  unsigned short byte_count;
+} PACK;
+
+struct smb_tree_disconnect {
+  unsigned char word_count;
+  unsigned short byte_count;
+} PACK;
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+#  pragma pack(pop)
+#endif
+
+#endif /* BUILDING_CURL_SMB_C */
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+    (CURL_SIZEOF_CURL_OFF_T > 4)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+extern const struct Curl_handler Curl_handler_smb;
+extern const struct Curl_handler Curl_handler_smbs;
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
+
+#endif /* HEADER_CURL_SMB_H */
diff --git a/Utilities/cmcurl/lib/smtp.c b/Utilities/cmcurl/lib/smtp.c
index 9aa8b15..dada087 100644
--- a/Utilities/cmcurl/lib/smtp.c
+++ b/Utilities/cmcurl/lib/smtp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -62,7 +62,6 @@
 #include <curl/curl.h>
 #include "urldata.h"
 #include "sendf.h"
-#include "if2ip.h"
 #include "hostip.h"
 #include "progress.h"
 #include "transfer.h"
@@ -83,10 +82,7 @@
 #include "curl_gethostname.h"
 #include "curl_sasl.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -106,10 +102,10 @@ static CURLcode smtp_setup_connection(struct connectdata *conn);
 static CURLcode smtp_parse_url_options(struct connectdata *conn);
 static CURLcode smtp_parse_url_path(struct connectdata *conn);
 static CURLcode smtp_parse_custom_request(struct connectdata *conn);
-static CURLcode smtp_calc_sasl_details(struct connectdata *conn,
-                                       const char **mech,
-                                       char **initresp, size_t *len,
-                                       smtpstate *state1, smtpstate *state2);
+static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech,
+                                  const char *initresp);
+static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp);
+static void smtp_get_message(char *buffer, char** outptr);
 
 /*
  * SMTP protocol handler.
@@ -214,6 +210,17 @@ static const struct Curl_handler Curl_handler_smtps_proxy = {
 #endif
 #endif
 
+/* SASL parameters for the smtp protocol */
+static const struct SASLproto saslsmtp = {
+  "smtp",                     /* The service name */
+  334,                        /* Code received when continuation is expected */
+  235,                        /* Code to receive upon authentication success */
+  512 - 8,                    /* Maximum initial response length (no max) */
+  smtp_perform_auth,          /* Send authentication command */
+  smtp_continue_auth,         /* Send authentication continuation */
+  smtp_get_message            /* Get SASL response message */
+};
+
 #ifdef USE_SSL
 static void smtp_to_smtps(struct connectdata *conn)
 {
@@ -310,20 +317,7 @@ static void state(struct connectdata *conn, smtpstate newstate)
     "HELO",
     "STARTTLS",
     "UPGRADETLS",
-    "AUTH_PLAIN",
-    "AUTH_LOGIN",
-    "AUTH_LOGIN_PASSWD",
-    "AUTH_CRAMMD5",
-    "AUTH_DIGESTMD5",
-    "AUTH_DIGESTMD5_RESP",
-    "AUTH_NTLM",
-    "AUTH_NTLM_TYPE2MSG",
-    "AUTH_GSSAPI",
-    "AUTH_GSSAPI_TOKEN",
-    "AUTH_GSSAPI_NO_DATA",
-    "AUTH_XOAUTH2",
-    "AUTH_CANCEL",
-    "AUTH_FINAL",
+    "AUTH",
     "COMMAND",
     "MAIL",
     "RCPT",
@@ -353,11 +347,11 @@ static CURLcode smtp_perform_ehlo(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   struct smtp_conn *smtpc = &conn->proto.smtpc;
 
-  smtpc->authmechs = 0;           /* No known authentication mechanisms yet */
-  smtpc->authused = 0;            /* Clear the authentication mechanism used
-                                     for esmtp connections */
-  smtpc->tls_supported = FALSE;   /* Clear the TLS capability */
-  smtpc->auth_supported = FALSE;  /* Clear the AUTH capability */
+  smtpc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanism yet */
+  smtpc->sasl.authused = SASL_AUTH_NONE;  /* Clear the authentication mechanism
+                                             used for esmtp connections */
+  smtpc->tls_supported = FALSE;           /* Clear the TLS capability */
+  smtpc->auth_supported = FALSE;          /* Clear the AUTH capability */
 
   /* Send the EHLO command */
   result = Curl_pp_sendf(&smtpc->pp, "EHLO %s", smtpc->domain);
@@ -379,8 +373,8 @@ static CURLcode smtp_perform_helo(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   struct smtp_conn *smtpc = &conn->proto.smtpc;
 
-  smtpc->authused = 0;          /* No authentication mechanism used in smtp
-                                   connections */
+  smtpc->sasl.authused = SASL_AUTH_NONE; /* No authentication mechanism used
+                                            in smtp connections */
 
   /* Send the HELO command */
   result = Curl_pp_sendf(&smtpc->pp, "HELO %s", smtpc->domain);
@@ -446,25 +440,18 @@ static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn)
  */
 static CURLcode smtp_perform_auth(struct connectdata *conn,
                                   const char *mech,
-                                  const char *initresp, size_t len,
-                                  smtpstate state1, smtpstate state2)
+                                  const char *initresp)
 {
   CURLcode result = CURLE_OK;
   struct smtp_conn *smtpc = &conn->proto.smtpc;
 
-  if(initresp && 8 + strlen(mech) + len <= 512) { /* AUTH <mech> ...<crlf> */
+  if(initresp) {                                  /* AUTH <mech> ...<crlf> */
     /* Send the AUTH command with the initial response */
     result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
-
-    if(!result)
-      state(conn, state2);
   }
   else {
     /* Send the AUTH command */
     result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
-
-    if(!result)
-      state(conn, state1);
   }
 
   return result;
@@ -472,6 +459,19 @@ static CURLcode smtp_perform_auth(struct connectdata *conn,
 
 /***********************************************************************
  *
+ * smtp_continue_auth()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  return Curl_pp_sendf(&smtpc->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
  * smtp_perform_authentication()
  *
  * Initiates the authentication sequence, with the appropriate SASL
@@ -481,31 +481,22 @@ static CURLcode smtp_perform_authentication(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct smtp_conn *smtpc = &conn->proto.smtpc;
-  const char *mech = NULL;
-  char *initresp = NULL;
-  size_t len = 0;
-  smtpstate state1 = SMTP_STOP;
-  smtpstate state2 = SMTP_STOP;
+  saslprogress progress;
 
-  /* Check we have a username and password to authenticate with, and the
+  /* Check we have enough data to authenticate with, and the
      server supports authentiation, and end the connect phase if not */
-  if(!conn->bits.user_passwd || !smtpc->auth_supported) {
+  if(!smtpc->auth_supported ||
+      !Curl_sasl_can_authenticate(&smtpc->sasl, conn)) {
     state(conn, SMTP_STOP);
-
     return result;
   }
 
   /* Calculate the SASL login details */
-  result = smtp_calc_sasl_details(conn, &mech, &initresp, &len, &state1,
-                                  &state2);
+  result = Curl_sasl_start(&smtpc->sasl, conn, FALSE, &progress);
 
   if(!result) {
-    if(mech) {
-      /* Perform SASL based authentication */
-      result = smtp_perform_auth(conn, mech, initresp, len, state1, state2);
-
-      Curl_safefree(initresp);
-    }
+    if(progress == SASL_INPROGRESS)
+      state(conn, SMTP_AUTH);
     else {
       /* Other mechanisms not supported */
       infof(conn->data, "No known authentication mechanisms supported!\n");
@@ -572,7 +563,7 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
     return CURLE_OUT_OF_MEMORY;
 
   /* Calculate the optional AUTH parameter */
-  if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.authused) {
+  if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.sasl.authused) {
     if(data->set.str[STRING_MAIL_AUTH][0] != '\0')
       auth = aprintf("%s", data->set.str[STRING_MAIL_AUTH]);
     else
@@ -580,7 +571,7 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
       auth = strdup("<>");
 
     if(!auth) {
-      Curl_safefree(from);
+      free(from);
 
       return CURLE_OUT_OF_MEMORY;
     }
@@ -591,8 +582,8 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
     size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->state.infilesize);
 
     if(!size) {
-      Curl_safefree(from);
-      Curl_safefree(auth);
+      free(from);
+      free(auth);
 
       return CURLE_OUT_OF_MEMORY;
     }
@@ -612,9 +603,9 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
     result = Curl_pp_sendf(&conn->proto.smtpc.pp,
                            "MAIL FROM:%s SIZE=%s", from, size);
 
-  Curl_safefree(from);
-  Curl_safefree(auth);
-  Curl_safefree(size);
+  free(from);
+  free(auth);
+  free(size);
 
   if(!result)
     state(conn, SMTP_MAIL);
@@ -754,6 +745,9 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
 
       /* Loop through the data line */
       for(;;) {
+        size_t llen;
+        unsigned int mechbit;
+
         while(len &&
               (*line == ' ' || *line == '\t' ||
                *line == '\r' || *line == '\n')) {
@@ -772,22 +766,9 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
           wordlen++;
 
         /* Test the word for a matching authentication mechanism */
-        if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
-          smtpc->authmechs |= SASL_MECH_LOGIN;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
-          smtpc->authmechs |= SASL_MECH_PLAIN;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
-          smtpc->authmechs |= SASL_MECH_CRAM_MD5;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
-          smtpc->authmechs |= SASL_MECH_DIGEST_MD5;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
-          smtpc->authmechs |= SASL_MECH_GSSAPI;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
-          smtpc->authmechs |= SASL_MECH_EXTERNAL;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
-          smtpc->authmechs |= SASL_MECH_NTLM;
-        else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
-          smtpc->authmechs |= SASL_MECH_XOAUTH2;
+        if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+           llen == wordlen)
+          smtpc->sasl.authmechs |= mechbit;
 
         line += wordlen;
         len -= wordlen;
@@ -836,565 +817,31 @@ static CURLcode smtp_state_helo_resp(struct connectdata *conn, int smtpcode,
   return result;
 }
 
-/* For AUTH PLAIN (without initial response) responses */
-static CURLcode smtp_state_auth_plain_resp(struct connectdata *conn,
-                                           int smtpcode,
-                                           smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *plainauth = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the authorisation message */
-    result = Curl_sasl_create_plain_message(conn->data, conn->user,
-                                            conn->passwd, &plainauth, &len);
-    if(!result && plainauth) {
-      /* Send the message */
-      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", plainauth);
-
-      if(!result)
-        state(conn, SMTP_AUTH_FINAL);
-    }
-  }
-
-  Curl_safefree(plainauth);
-
-  return result;
-}
-
-/* For AUTH LOGIN (without initial response) responses */
-static CURLcode smtp_state_auth_login_resp(struct connectdata *conn,
-                                           int smtpcode,
-                                           smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *authuser = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the user message */
-    result = Curl_sasl_create_login_message(conn->data, conn->user,
-                                            &authuser, &len);
-    if(!result && authuser) {
-      /* Send the user */
-      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authuser);
-
-      if(!result)
-        state(conn, SMTP_AUTH_LOGIN_PASSWD);
-    }
-  }
-
-  Curl_safefree(authuser);
-
-  return result;
-}
-
-/* For AUTH LOGIN user entry responses */
-static CURLcode smtp_state_auth_login_password_resp(struct connectdata *conn,
-                                                    int smtpcode,
-                                                    smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *authpasswd = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the password message */
-    result = Curl_sasl_create_login_message(conn->data, conn->passwd,
-                                            &authpasswd, &len);
-    if(!result && authpasswd) {
-      /* Send the password */
-      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authpasswd);
-
-      if(!result)
-        state(conn, SMTP_AUTH_FINAL);
-    }
-  }
-
-  Curl_safefree(authpasswd);
-
-  return result;
-}
-
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-/* For AUTH CRAM-MD5 responses */
-static CURLcode smtp_state_auth_cram_resp(struct connectdata *conn,
-                                          int smtpcode,
-                                          smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *chlg = NULL;
-  char *chlg64 = NULL;
-  char *rplyb64 = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    return CURLE_LOGIN_DENIED;
-  }
-
-  /* Get the challenge message */
-  smtp_get_message(data->state.buffer, &chlg64);
-
-  /* Decode the challenge message */
-  result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
-  if(result) {
-    /* Send the cancellation */
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
-
-    if(!result)
-      state(conn, SMTP_AUTH_CANCEL);
-  }
-  else {
-    /* Create the response message */
-    result = Curl_sasl_create_cram_md5_message(data, chlg, conn->user,
-                                               conn->passwd, &rplyb64, &len);
-    if(!result && rplyb64) {
-      /* Send the response */
-      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
-
-      if(!result)
-        state(conn, SMTP_AUTH_FINAL);
-    }
-  }
-
-  Curl_safefree(chlg);
-  Curl_safefree(rplyb64);
-
-  return result;
-}
-
-/* For AUTH DIGEST-MD5 challenge responses */
-static CURLcode smtp_state_auth_digest_resp(struct connectdata *conn,
-                                            int smtpcode,
-                                            smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *chlg64 = NULL;
-  char *rplyb64 = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    return CURLE_LOGIN_DENIED;
-  }
-
-  /* Get the challenge message */
-  smtp_get_message(data->state.buffer, &chlg64);
-
-  /* Create the response message */
-  result = Curl_sasl_create_digest_md5_message(data, chlg64,
-                                               conn->user, conn->passwd,
-                                               "smtp", &rplyb64, &len);
-  if(result) {
-    if(result == CURLE_BAD_CONTENT_ENCODING) {
-      /* Send the cancellation */
-      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
-
-      if(!result)
-        state(conn, SMTP_AUTH_CANCEL);
-    }
-  }
-  else {
-    /* Send the response */
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
-
-    if(!result)
-      state(conn, SMTP_AUTH_DIGESTMD5_RESP);
-  }
-
-  Curl_safefree(rplyb64);
-
-  return result;
-}
-
-/* For AUTH DIGEST-MD5 challenge-response responses */
-static CURLcode smtp_state_auth_digest_resp_resp(struct connectdata *conn,
-                                                 int smtpcode,
-                                                 smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Authentication failed: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Send an empty response */
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "");
-
-    if(!result)
-      state(conn, SMTP_AUTH_FINAL);
-  }
-
-  return result;
-}
-
-#endif
-
-#ifdef USE_NTLM
-/* For AUTH NTLM (without initial response) responses */
-static CURLcode smtp_state_auth_ntlm_resp(struct connectdata *conn,
-                                          int smtpcode,
-                                          smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *type1msg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the type-1 message */
-    result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
-                                                 &conn->ntlm,
-                                                 &type1msg, &len);
-    if(!result && type1msg) {
-      /* Send the message */
-      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type1msg);
-
-      if(!result)
-        state(conn, SMTP_AUTH_NTLM_TYPE2MSG);
-    }
-  }
-
-  Curl_safefree(type1msg);
-
-  return result;
-}
-
-/* For NTLM type-2 responses (sent in reponse to our type-1 message) */
-static CURLcode smtp_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
-                                                   int smtpcode,
-                                                   smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *type2msg = NULL;
-  char *type3msg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Get the type-2 message */
-    smtp_get_message(data->state.buffer, &type2msg);
-
-    /* Decode the type-2 message */
-    result = Curl_sasl_decode_ntlm_type2_message(data, type2msg, &conn->ntlm);
-    if(result) {
-      /* Send the cancellation */
-      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
-
-      if(!result)
-        state(conn, SMTP_AUTH_CANCEL);
-    }
-    else {
-      /* Create the type-3 message */
-      result = Curl_sasl_create_ntlm_type3_message(data, conn->user,
-                                                   conn->passwd, &conn->ntlm,
-                                                   &type3msg, &len);
-      if(!result && type3msg) {
-        /* Send the message */
-        result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type3msg);
-
-        if(!result)
-          state(conn, SMTP_AUTH_FINAL);
-      }
-    }
-  }
-
-  Curl_safefree(type3msg);
-
-  return result;
-}
-#endif
-
-#if defined(USE_WINDOWS_SSPI)
-/* For AUTH GSSAPI (without initial response) responses */
-static CURLcode smtp_state_auth_gssapi_resp(struct connectdata *conn,
-                                            int smtpcode,
-                                            smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct smtp_conn *smtpc = &conn->proto.smtpc;
-  char *respmsg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the initial response message */
-    result = Curl_sasl_create_gssapi_user_message(data, conn->user,
-                                                  conn->passwd, "smtp",
-                                                  smtpc->mutual_auth, NULL,
-                                                  &conn->krb5,
-                                                  &respmsg, &len);
-    if(!result && respmsg) {
-      /* Send the message */
-      result = Curl_pp_sendf(&smtpc->pp, "%s", respmsg);
-
-      if(!result)
-        state(conn, SMTP_AUTH_GSSAPI_TOKEN);
-    }
-  }
-
-  Curl_safefree(respmsg);
-
-  return result;
-}
-
-/* For AUTH GSSAPI user token responses */
-static CURLcode smtp_state_auth_gssapi_token_resp(struct connectdata *conn,
-                                                  int smtpcode,
-                                                  smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct smtp_conn *smtpc = &conn->proto.smtpc;
-  char *chlgmsg = NULL;
-  char *respmsg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Get the challenge message */
-    smtp_get_message(data->state.buffer, &chlgmsg);
-
-    if(smtpc->mutual_auth)
-      /* Decode the user token challenge and create the optional response
-         message */
-      result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
-                                                    smtpc->mutual_auth,
-                                                    chlgmsg, &conn->krb5,
-                                                    &respmsg, &len);
-    else
-      /* Decode the security challenge and create the response message */
-      result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
-                                                        &conn->krb5,
-                                                        &respmsg, &len);
-
-    if(result) {
-      if(result == CURLE_BAD_CONTENT_ENCODING) {
-        /* Send the cancellation */
-        result = Curl_pp_sendf(&smtpc->pp, "%s", "*");
-
-        if(!result)
-          state(conn, SMTP_AUTH_CANCEL);
-      }
-    }
-    else {
-      /* Send the response */
-      if(respmsg)
-        result = Curl_pp_sendf(&smtpc->pp, "%s", respmsg);
-      else
-        result = Curl_pp_sendf(&smtpc->pp, "%s", "");
-
-      if(!result)
-        state(conn, (smtpc->mutual_auth ? SMTP_AUTH_GSSAPI_NO_DATA :
-                                          SMTP_AUTH_FINAL));
-    }
-  }
-
-  Curl_safefree(respmsg);
-
-  return result;
-}
-
-/* For AUTH GSSAPI no data responses */
-static CURLcode smtp_state_auth_gssapi_no_data_resp(struct connectdata *conn,
-                                                    int smtpcode,
-                                                    smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  char *chlgmsg = NULL;
-  char *respmsg = NULL;
-  size_t len = 0;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Get the challenge message */
-    smtp_get_message(data->state.buffer, &chlgmsg);
-
-    /* Decode the security challenge and create the response message */
-    result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
-                                                      &conn->krb5,
-                                                      &respmsg, &len);
-    if(result) {
-      if(result == CURLE_BAD_CONTENT_ENCODING) {
-        /* Send the cancellation */
-        result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
-
-        if(!result)
-          state(conn, SMTP_AUTH_CANCEL);
-      }
-    }
-    else {
-      /* Send the response */
-      if(respmsg) {
-        result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", respmsg);
-
-        if(!result)
-          state(conn, SMTP_AUTH_FINAL);
-      }
-    }
-  }
-
-  Curl_safefree(respmsg);
-
-  return result;
-}
-#endif
-
-/* For AUTH XOAUTH2 (without initial response) responses */
-static CURLcode smtp_state_auth_xoauth2_resp(struct connectdata *conn,
-                                             int smtpcode, smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  size_t len = 0;
-  char *xoauth = NULL;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 334) {
-    failf(data, "Access denied: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else {
-    /* Create the authorisation message */
-    result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
-                                              conn->xoauth2_bearer,
-                                              &xoauth, &len);
-    if(!result && xoauth) {
-      /* Send the message */
-      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", xoauth);
-
-      if(!result)
-        state(conn, SMTP_AUTH_FINAL);
-    }
-  }
-
-  Curl_safefree(xoauth);
-
-  return result;
-}
-
-/* For AUTH cancellation responses */
-static CURLcode smtp_state_auth_cancel_resp(struct connectdata *conn,
-                                            int smtpcode,
-                                            smtpstate instate)
+/* For SASL authentication responses */
+static CURLcode smtp_state_auth_resp(struct connectdata *conn,
+                                     int smtpcode,
+                                     smtpstate instate)
 {
   CURLcode result = CURLE_OK;
   struct SessionHandle *data = conn->data;
   struct smtp_conn *smtpc = &conn->proto.smtpc;
-  const char *mech = NULL;
-  char *initresp = NULL;
-  size_t len = 0;
-  smtpstate state1 = SMTP_STOP;
-  smtpstate state2 = SMTP_STOP;
+  saslprogress progress;
 
-  (void)smtpcode;
   (void)instate; /* no use for this yet */
 
-  /* Remove the offending mechanism from the supported list */
-  smtpc->authmechs ^= smtpc->authused;
-
-  /* Calculate alternative SASL login details */
-  result = smtp_calc_sasl_details(conn, &mech, &initresp, &len, &state1,
-                                  &state2);
-
-  if(!result) {
-    /* Do we have any mechanisms left? */
-    if(mech) {
-      /* Retry SASL based authentication */
-      result = smtp_perform_auth(conn, mech, initresp, len, state1, state2);
-
-      Curl_safefree(initresp);
-    }
-    else {
+  result = Curl_sasl_continue(&smtpc->sasl, conn, smtpcode, &progress);
+  if(!result)
+    switch(progress) {
+    case SASL_DONE:
+      state(conn, SMTP_STOP);  /* Authenticated */
+      break;
+    case SASL_IDLE:            /* No mechanism left after cancellation */
       failf(data, "Authentication cancelled");
-
       result = CURLE_LOGIN_DENIED;
+      break;
+    default:
+      break;
     }
-  }
-
-  return result;
-}
-
-/* For final responses in the AUTH sequence */
-static CURLcode smtp_state_auth_final_resp(struct connectdata *conn,
-                                           int smtpcode,
-                                           smtpstate instate)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-
-  (void)instate; /* no use for this yet */
-
-  if(smtpcode != 235) {
-    failf(data, "Authentication failed: %d", smtpcode);
-    result = CURLE_LOGIN_DENIED;
-  }
-  else
-    /* End of connect phase */
-    state(conn, SMTP_STOP);
 
   return result;
 }
@@ -1592,69 +1039,8 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
       result = smtp_state_starttls_resp(conn, smtpcode, smtpc->state);
       break;
 
-    case SMTP_AUTH_PLAIN:
-      result = smtp_state_auth_plain_resp(conn, smtpcode, smtpc->state);
-      break;
-
-    case SMTP_AUTH_LOGIN:
-      result = smtp_state_auth_login_resp(conn, smtpcode, smtpc->state);
-      break;
-
-    case SMTP_AUTH_LOGIN_PASSWD:
-      result = smtp_state_auth_login_password_resp(conn, smtpcode,
-                                                   smtpc->state);
-      break;
-
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-    case SMTP_AUTH_CRAMMD5:
-      result = smtp_state_auth_cram_resp(conn, smtpcode, smtpc->state);
-      break;
-
-    case SMTP_AUTH_DIGESTMD5:
-      result = smtp_state_auth_digest_resp(conn, smtpcode, smtpc->state);
-      break;
-
-    case SMTP_AUTH_DIGESTMD5_RESP:
-      result = smtp_state_auth_digest_resp_resp(conn, smtpcode, smtpc->state);
-      break;
-#endif
-
-#ifdef USE_NTLM
-    case SMTP_AUTH_NTLM:
-      result = smtp_state_auth_ntlm_resp(conn, smtpcode, smtpc->state);
-      break;
-
-    case SMTP_AUTH_NTLM_TYPE2MSG:
-      result = smtp_state_auth_ntlm_type2msg_resp(conn, smtpcode,
-                                                  smtpc->state);
-      break;
-#endif
-
-#if defined(USE_WINDOWS_SSPI)
-    case SMTP_AUTH_GSSAPI:
-      result = smtp_state_auth_gssapi_resp(conn, smtpcode, smtpc->state);
-      break;
-
-    case SMTP_AUTH_GSSAPI_TOKEN:
-      result = smtp_state_auth_gssapi_token_resp(conn, smtpcode, smtpc->state);
-      break;
-
-    case SMTP_AUTH_GSSAPI_NO_DATA:
-      result = smtp_state_auth_gssapi_no_data_resp(conn, smtpcode,
-                                                   smtpc->state);
-      break;
-#endif
-
-    case SMTP_AUTH_XOAUTH2:
-      result = smtp_state_auth_xoauth2_resp(conn, smtpcode, smtpc->state);
-      break;
-
-    case SMTP_AUTH_CANCEL:
-      result = smtp_state_auth_cancel_resp(conn, smtpcode, smtpc->state);
-      break;
-
-    case SMTP_AUTH_FINAL:
-      result = smtp_state_auth_final_resp(conn, smtpcode, smtpc->state);
+    case SMTP_AUTH:
+      result = smtp_state_auth_resp(conn, smtpcode, smtpc->state);
       break;
 
     case SMTP_COMMAND:
@@ -1767,8 +1153,8 @@ static CURLcode smtp_connect(struct connectdata *conn, bool *done)
   pp->endofresp = smtp_endofresp;
   pp->conn = conn;
 
-  /* Set the default preferred authentication mechanism */
-  smtpc->prefmech = SASL_AUTH_ANY;
+  /* Initialize the SASL storage */
+  Curl_sasl_init(&smtpc->sasl, &saslsmtp);
 
   /* Initialise the pingpong layer */
   Curl_pp_init(pp);
@@ -1807,7 +1193,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
   struct SessionHandle *data = conn->data;
   struct SMTP *smtp = data->req.protop;
   struct pingpong *pp = &conn->proto.smtpc.pp;
-  const char *eob;
+  char *eob;
   ssize_t len;
   ssize_t bytes_written;
 
@@ -1827,30 +1213,45 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
   else if(!data->set.connect_only && data->set.upload && data->set.mail_rcpt) {
     /* Calculate the EOB taking into account any terminating CRLF from the
        previous line of the email or the CRLF of the DATA command when there
-       is "no mail data". RFC-5321, sect. 4.1.1.4. */
-    eob = SMTP_EOB;
-    len = SMTP_EOB_LEN;
+       is "no mail data". RFC-5321, sect. 4.1.1.4.
+
+       Note: As some SSL backends, such as OpenSSL, will cause Curl_write() to
+       fail when using a different pointer following a previous write, that
+       returned CURLE_AGAIN, we duplicate the EOB now rather than when the
+       bytes written doesn't equal len. */
     if(smtp->trailing_crlf || !conn->data->state.infilesize) {
-      eob += 2;
-      len -= 2;
+      eob = strdup(SMTP_EOB + 2);
+      len = SMTP_EOB_LEN - 2;
+    }
+    else {
+      eob = strdup(SMTP_EOB);
+      len = SMTP_EOB_LEN;
     }
 
+    if(!eob)
+      return CURLE_OUT_OF_MEMORY;
+
     /* Send the end of block data */
     result = Curl_write(conn, conn->writesockfd, eob, len, &bytes_written);
-    if(result)
+    if(result) {
+      free(eob);
       return result;
+    }
 
     if(bytes_written != len) {
       /* The whole chunk was not sent so keep it around and adjust the
          pingpong structure accordingly */
-      pp->sendthis = strdup(eob);
+      pp->sendthis = eob;
       pp->sendsize = len;
       pp->sendleft = len - bytes_written;
     }
-    else
+    else {
       /* Successfully sent so adjust the response timeout relative to now */
       pp->response = Curl_tvnow();
 
+      free(eob);
+    }
+
     state(conn, SMTP_POSTDATA);
 
     /* Run the state-machine
@@ -1971,7 +1372,7 @@ static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
   Curl_pp_disconnect(&smtpc->pp);
 
   /* Cleanup the SASL module */
-  Curl_sasl_cleanup(conn, smtpc->authused);
+  Curl_sasl_cleanup(conn, smtpc->sasl.authused);
 
   /* Cleanup our connection based variables */
   Curl_safefree(smtpc->domain);
@@ -2092,52 +1493,30 @@ static CURLcode smtp_parse_url_options(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct smtp_conn *smtpc = &conn->proto.smtpc;
-  const char *options = conn->options;
-  const char *ptr = options;
-  bool reset = TRUE;
+  const char *ptr = conn->options;
 
-  while(ptr && *ptr) {
+  smtpc->sasl.resetprefs = TRUE;
+
+  while(!result && ptr && *ptr) {
     const char *key = ptr;
+    const char *value;
 
     while(*ptr && *ptr != '=')
         ptr++;
 
-    if(strnequal(key, "AUTH", 4)) {
-      size_t len = 0;
-      const char *value = ++ptr;
-
-      if(reset) {
-        reset = FALSE;
-        smtpc->prefmech = SASL_AUTH_NONE;
-      }
+    value = ptr + 1;
 
-      while(*ptr && *ptr != ';') {
-        ptr++;
-        len++;
-      }
+    while(*ptr && *ptr != ';')
+      ptr++;
 
-      if(strnequal(value, "*", len))
-        smtpc->prefmech = SASL_AUTH_ANY;
-      else if(strnequal(value, SASL_MECH_STRING_LOGIN, len))
-        smtpc->prefmech |= SASL_MECH_LOGIN;
-      else if(strnequal(value, SASL_MECH_STRING_PLAIN, len))
-        smtpc->prefmech |= SASL_MECH_PLAIN;
-      else if(strnequal(value, SASL_MECH_STRING_CRAM_MD5, len))
-        smtpc->prefmech |= SASL_MECH_CRAM_MD5;
-      else if(strnequal(value, SASL_MECH_STRING_DIGEST_MD5, len))
-        smtpc->prefmech |= SASL_MECH_DIGEST_MD5;
-      else if(strnequal(value, SASL_MECH_STRING_GSSAPI, len))
-        smtpc->prefmech |= SASL_MECH_GSSAPI;
-      else if(strnequal(value, SASL_MECH_STRING_NTLM, len))
-        smtpc->prefmech |= SASL_MECH_NTLM;
-      else if(strnequal(value, SASL_MECH_STRING_XOAUTH2, len))
-        smtpc->prefmech |= SASL_MECH_XOAUTH2;
-
-      if(*ptr == ';')
-        ptr++;
-    }
+    if(strnequal(key, "AUTH=", 5))
+      result = Curl_sasl_parse_url_auth_option(&smtpc->sasl,
+                                               value, ptr - value);
     else
       result = CURLE_URL_MALFORMAT;
+
+    if(*ptr == ';')
+      ptr++;
   }
 
   return result;
@@ -2189,111 +1568,7 @@ static CURLcode smtp_parse_custom_request(struct connectdata *conn)
   return result;
 }
 
-/***********************************************************************
- *
- * smtp_calc_sasl_details()
- *
- * Calculate the required login details for SASL authentication.
- */
-static CURLcode smtp_calc_sasl_details(struct connectdata *conn,
-                                       const char **mech,
-                                       char **initresp, size_t *len,
-                                       smtpstate *state1, smtpstate *state2)
-{
-  CURLcode result = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct smtp_conn *smtpc = &conn->proto.smtpc;
-
-  /* Calculate the supported authentication mechanism, by decreasing order of
-     security, as well as the initial response where appropriate */
-#if defined(USE_WINDOWS_SSPI)
-  if((smtpc->authmechs & SASL_MECH_GSSAPI) &&
-     (smtpc->prefmech & SASL_MECH_GSSAPI)) {
-    smtpc->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
-
-    *mech = SASL_MECH_STRING_GSSAPI;
-    *state1 = SMTP_AUTH_GSSAPI;
-    *state2 = SMTP_AUTH_GSSAPI_TOKEN;
-    smtpc->authused = SASL_MECH_GSSAPI;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_gssapi_user_message(data, conn->user,
-                                                    conn->passwd, "smtp",
-                                                    smtpc->mutual_auth,
-                                                    NULL, &conn->krb5,
-                                                    initresp, len);
-    }
-  else
-#endif
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-  if((smtpc->authmechs & SASL_MECH_DIGEST_MD5) &&
-     (smtpc->prefmech & SASL_MECH_DIGEST_MD5)) {
-    *mech = SASL_MECH_STRING_DIGEST_MD5;
-    *state1 = SMTP_AUTH_DIGESTMD5;
-    smtpc->authused = SASL_MECH_DIGEST_MD5;
-  }
-  else if((smtpc->authmechs & SASL_MECH_CRAM_MD5) &&
-          (smtpc->prefmech & SASL_MECH_CRAM_MD5)) {
-    *mech = SASL_MECH_STRING_CRAM_MD5;
-    *state1 = SMTP_AUTH_CRAMMD5;
-    smtpc->authused = SASL_MECH_CRAM_MD5;
-  }
-  else
-#endif
-#ifdef USE_NTLM
-  if((smtpc->authmechs & SASL_MECH_NTLM) &&
-     (smtpc->prefmech & SASL_MECH_NTLM)) {
-    *mech = SASL_MECH_STRING_NTLM;
-    *state1 = SMTP_AUTH_NTLM;
-    *state2 = SMTP_AUTH_NTLM_TYPE2MSG;
-    smtpc->authused = SASL_MECH_NTLM;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
-                                                   &conn->ntlm,
-                                                   initresp, len);
-    }
-  else
-#endif
-  if(((smtpc->authmechs & SASL_MECH_XOAUTH2) &&
-      (smtpc->prefmech & SASL_MECH_XOAUTH2) &&
-      (smtpc->prefmech != SASL_AUTH_ANY)) || conn->xoauth2_bearer) {
-    *mech = SASL_MECH_STRING_XOAUTH2;
-    *state1 = SMTP_AUTH_XOAUTH2;
-    *state2 = SMTP_AUTH_FINAL;
-    smtpc->authused = SASL_MECH_XOAUTH2;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_xoauth2_message(data, conn->user,
-                                                conn->xoauth2_bearer,
-                                                initresp, len);
-  }
-  else if((smtpc->authmechs & SASL_MECH_LOGIN) &&
-          (smtpc->prefmech & SASL_MECH_LOGIN)) {
-    *mech = SASL_MECH_STRING_LOGIN;
-    *state1 = SMTP_AUTH_LOGIN;
-    *state2 = SMTP_AUTH_LOGIN_PASSWD;
-    smtpc->authused = SASL_MECH_LOGIN;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_login_message(data, conn->user, initresp, len);
-  }
-  else if((smtpc->authmechs & SASL_MECH_PLAIN) &&
-          (smtpc->prefmech & SASL_MECH_PLAIN)) {
-    *mech = SASL_MECH_STRING_PLAIN;
-    *state1 = SMTP_AUTH_PLAIN;
-    *state2 = SMTP_AUTH_FINAL;
-    smtpc->authused = SASL_MECH_PLAIN;
-
-    if(data->set.sasl_ir)
-      result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
-                                              initresp, len);
-  }
-
-  return result;
-}
-
-CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
+CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
 {
   /* When sending a SMTP payload we must detect CRLF. sequences making sure
      they are sent as CRLF.. instead, as a . on the beginning of a line will
@@ -2305,17 +1580,26 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
   ssize_t si;
   struct SessionHandle *data = conn->data;
   struct SMTP *smtp = data->req.protop;
+  char *scratch = data->state.scratch;
+  char *newscratch = NULL;
+  char *oldscratch = NULL;
+  size_t eob_sent;
+
+  /* Do we need to allocate a scratch buffer? */
+  if(!scratch || data->set.crlf) {
+    oldscratch = scratch;
 
-  /* Do we need to allocate the scatch buffer? */
-  if(!data->state.scratch) {
-    data->state.scratch = malloc(2 * BUFSIZE);
+    scratch = newscratch = malloc(2 * BUFSIZE);
+    if(!newscratch) {
+      failf(data, "Failed to alloc scratch buffer!");
 
-    if(!data->state.scratch) {
-      failf (data, "Failed to alloc scratch buffer!");
       return CURLE_OUT_OF_MEMORY;
     }
   }
 
+  /* Have we already sent part of the EOB? */
+  eob_sent = smtp->eob;
+
   /* This loop can be improved by some kind of Boyer-Moore style of
      approach but that is saved for later... */
   for(i = 0, si = 0; i < nread; i++) {
@@ -2330,8 +1614,8 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
     }
     else if(smtp->eob) {
       /* A previous substring matched so output that first */
-      memcpy(&data->state.scratch[si], SMTP_EOB, smtp->eob);
-      si += smtp->eob;
+      memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent);
+      si += smtp->eob - eob_sent;
 
       /* Then compare the first byte */
       if(SMTP_EOB[0] == data->req.upload_fromhere[i])
@@ -2339,6 +1623,8 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
       else
         smtp->eob = 0;
 
+      eob_sent = 0;
+
       /* Reset the trailing CRLF flag as there was more data */
       smtp->trailing_crlf = FALSE;
     }
@@ -2346,31 +1632,38 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
     /* Do we have a match for CRLF. as per RFC-5321, sect. 4.5.2 */
     if(SMTP_EOB_FIND_LEN == smtp->eob) {
       /* Copy the replacement data to the target buffer */
-      memcpy(&data->state.scratch[si], SMTP_EOB_REPL, SMTP_EOB_REPL_LEN);
-      si += SMTP_EOB_REPL_LEN;
+      memcpy(&scratch[si], &SMTP_EOB_REPL[eob_sent],
+             SMTP_EOB_REPL_LEN - eob_sent);
+      si += SMTP_EOB_REPL_LEN - eob_sent;
       smtp->eob = 0;
+      eob_sent = 0;
     }
     else if(!smtp->eob)
-      data->state.scratch[si++] = data->req.upload_fromhere[i];
+      scratch[si++] = data->req.upload_fromhere[i];
   }
 
-  if(smtp->eob) {
+  if(smtp->eob - eob_sent) {
     /* A substring matched before processing ended so output that now */
-    memcpy(&data->state.scratch[si], SMTP_EOB, smtp->eob);
-    si += smtp->eob;
-    smtp->eob = 0;
+    memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent);
+    si += smtp->eob - eob_sent;
   }
 
+  /* Only use the new buffer if we replaced something */
   if(si != nread) {
-    /* Only use the new buffer if we replaced something */
-    nread = si;
-
     /* Upload from the new (replaced) buffer instead */
-    data->req.upload_fromhere = data->state.scratch;
+    data->req.upload_fromhere = scratch;
+
+    /* Save the buffer so it can be freed later */
+    data->state.scratch = scratch;
+
+    /* Free the old scratch buffer */
+    free(oldscratch);
 
     /* Set the new amount too */
-    data->req.upload_present = nread;
+    data->req.upload_present = si;
   }
+  else
+    free(newscratch);
 
   return CURLE_OK;
 }
diff --git a/Utilities/cmcurl/lib/smtp.h b/Utilities/cmcurl/lib/smtp.h
index db1b1e6..9fbe0c5 100644
--- a/Utilities/cmcurl/lib/smtp.h
+++ b/Utilities/cmcurl/lib/smtp.h
@@ -23,6 +23,7 @@
  ***************************************************************************/
 
 #include "pingpong.h"
+#include "curl_sasl.h"
 
 /****************************************************************************
  * SMTP unique setup
@@ -36,20 +37,7 @@ typedef enum {
   SMTP_STARTTLS,
   SMTP_UPGRADETLS,  /* asynchronously upgrade the connection to SSL/TLS
                        (multi mode only) */
-  SMTP_AUTH_PLAIN,
-  SMTP_AUTH_LOGIN,
-  SMTP_AUTH_LOGIN_PASSWD,
-  SMTP_AUTH_CRAMMD5,
-  SMTP_AUTH_DIGESTMD5,
-  SMTP_AUTH_DIGESTMD5_RESP,
-  SMTP_AUTH_NTLM,
-  SMTP_AUTH_NTLM_TYPE2MSG,
-  SMTP_AUTH_GSSAPI,
-  SMTP_AUTH_GSSAPI_TOKEN,
-  SMTP_AUTH_GSSAPI_NO_DATA,
-  SMTP_AUTH_XOAUTH2,
-  SMTP_AUTH_CANCEL,
-  SMTP_AUTH_FINAL,
+  SMTP_AUTH,
   SMTP_COMMAND,     /* VRFY, EXPN, NOOP, RSET and HELP */
   SMTP_MAIL,        /* MAIL FROM */
   SMTP_RCPT,        /* RCPT TO */
@@ -79,14 +67,11 @@ struct smtp_conn {
   smtpstate state;         /* Always use smtp.c:state() to change state! */
   bool ssldone;            /* Is connect() over SSL done? */
   char *domain;            /* Client address/name to send in the EHLO */
-  unsigned int authmechs;  /* Accepted authentication mechanisms */
-  unsigned int prefmech;   /* Preferred authentication mechanism */
-  unsigned int authused;   /* Auth mechanism used for the connection */
+  struct SASL sasl;        /* SASL-related storage */
   bool tls_supported;      /* StartTLS capability supported by server */
   bool size_supported;     /* If server supports SIZE extension according to
                               RFC 1870 */
   bool auth_supported;     /* AUTH capability supported by server */
-  bool mutual_auth;        /* Mutual authentication enabled (GSSAPI only) */
 };
 
 extern const struct Curl_handler Curl_handler_smtp;
@@ -101,6 +86,6 @@ extern const struct Curl_handler Curl_handler_smtps;
 #define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e"
 #define SMTP_EOB_REPL_LEN 4
 
-CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread);
+CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread);
 
 #endif /* HEADER_CURL_SMTP_H */
diff --git a/Utilities/cmcurl/lib/socks.c b/Utilities/cmcurl/lib/socks.c
index 028475c..7d3f782 100644
--- a/Utilities/cmcurl/lib/socks.c
+++ b/Utilities/cmcurl/lib/socks.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -127,7 +127,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
     return CURLE_OPERATION_TIMEDOUT;
   }
 
-  curlx_nonblock(sock, FALSE);
+  (void)curlx_nonblock(sock, FALSE);
 
   infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
 
@@ -238,7 +238,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
     code = Curl_write_plain(conn, sock, (char *)socksreq,
                             packetsize + hostnamelen,
                             &written);
-    if((code != CURLE_OK) || (written != packetsize + hostnamelen)) {
+    if(code || (written != packetsize + hostnamelen)) {
       failf(data, "Failed to send SOCKS4 connect request.");
       return CURLE_COULDNT_CONNECT;
     }
@@ -247,7 +247,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
       hostnamelen = (ssize_t)strlen(hostname) + 1;
       code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
                               &written);
-      if((code != CURLE_OK) || (written != hostnamelen)) {
+      if(code || (written != hostnamelen)) {
         failf(data, "Failed to send SOCKS4 connect request.");
         return CURLE_COULDNT_CONNECT;
       }
@@ -258,7 +258,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
     /* Receive response */
     result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
                                 &actualread);
-    if((result != CURLE_OK) || (actualread != packetsize)) {
+    if(result || (actualread != packetsize)) {
       failf(data, "Failed to receive SOCKS4 connect request ack.");
       return CURLE_COULDNT_CONNECT;
     }
@@ -335,7 +335,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
     }
   }
 
-  curlx_nonblock(sock, TRUE);
+  (void)curlx_nonblock(sock, TRUE);
 
   return CURLE_OK; /* Proxy was successful! */
 }
@@ -382,7 +382,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
 
   /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
   if(!socks5_resolve_local && hostname_len > 255) {
-    infof(conn->data,"SOCKS5: server resolving disabled for hostnames of "
+    infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
           "length > 255 [actual len=%zu]\n", hostname_len);
     socks5_resolve_local = TRUE;
   }
@@ -396,7 +396,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     return CURLE_OPERATION_TIMEDOUT;
   }
 
-  curlx_nonblock(sock, TRUE);
+  (void)curlx_nonblock(sock, TRUE);
 
   /* wait until socket gets connected */
   result = Curl_socket_ready(CURL_SOCKET_BAD, sock, timeout);
@@ -427,16 +427,16 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
   socksreq[3] = 2; /* username/password */
 #endif
 
-  curlx_nonblock(sock, FALSE);
+  (void)curlx_nonblock(sock, FALSE);
 
   code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
                           &written);
-  if((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
+  if(code || (written != (2 + (int)socksreq[1]))) {
     failf(data, "Unable to send initial SOCKS5 request.");
     return CURLE_COULDNT_CONNECT;
   }
 
-  curlx_nonblock(sock, TRUE);
+  (void)curlx_nonblock(sock, TRUE);
 
   result = Curl_socket_ready(sock, CURL_SOCKET_BAD, timeout);
 
@@ -454,10 +454,10 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     return CURLE_RECV_ERROR;
   }
 
-  curlx_nonblock(sock, FALSE);
+  (void)curlx_nonblock(sock, FALSE);
 
   result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
-  if((result != CURLE_OK) || (actualread != 2)) {
+  if(result || (actualread != 2)) {
     failf(data, "Unable to receive initial SOCKS5 response.");
     return CURLE_COULDNT_CONNECT;
   }
@@ -473,7 +473,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
   else if(socksreq[1] == 1) {
     code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
-    if(code != CURLE_OK) {
+    if(code) {
       failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
       return CURLE_COULDNT_CONNECT;
     }
@@ -510,13 +510,13 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     len += proxy_password_len;
 
     code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
-    if((code != CURLE_OK) || (len != written)) {
+    if(code || (len != written)) {
       failf(data, "Failed to send SOCKS5 sub-negotiation request.");
       return CURLE_COULDNT_CONNECT;
     }
 
     result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
-    if((result != CURLE_OK) || (actualread != 2)) {
+    if(result || (actualread != 2)) {
       failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
       return CURLE_COULDNT_CONNECT;
     }
@@ -583,7 +583,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     if(rc == CURLRESOLV_PENDING) {
       /* this requires that we're in "wait for resolve" state */
       code = Curl_resolver_wait_resolv(conn, &dns);
-      if(code != CURLE_OK)
+      if(code)
         return code;
     }
 
@@ -642,7 +642,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
 #endif
     code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
 
-  if((code != CURLE_OK) || (len != written)) {
+  if(code || (len != written)) {
     failf(data, "Failed to send SOCKS5 connect request.");
     return CURLE_COULDNT_CONNECT;
   }
@@ -658,7 +658,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
     result = Curl_blockread_all(conn, sock, (char *)socksreq,
                                 len, &actualread);
 
-  if((result != CURLE_OK) || (len != actualread)) {
+  if(result || (len != actualread)) {
     failf(data, "Failed to receive SOCKS5 connect request ack.");
     return CURLE_COULDNT_CONNECT;
   }
@@ -738,7 +738,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
       len -= 10;
       result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
                                   len, &actualread);
-      if((result != CURLE_OK) || (len != actualread)) {
+      if(result || (len != actualread)) {
         failf(data, "Failed to receive SOCKS5 connect request ack.");
         return CURLE_COULDNT_CONNECT;
       }
@@ -747,7 +747,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
   }
 #endif
 
-  curlx_nonblock(sock, TRUE);
+  (void)curlx_nonblock(sock, TRUE);
   return CURLE_OK; /* Proxy was successful! */
 }
 
diff --git a/Utilities/cmcurl/lib/socks_gssapi.c b/Utilities/cmcurl/lib/socks_gssapi.c
index 0eaa74c..8e575c2 100644
--- a/Utilities/cmcurl/lib/socks_gssapi.c
+++ b/Utilities/cmcurl/lib/socks_gssapi.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller at compuserve.com>
- * Copyright (C) 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,16 +23,7 @@
 
 #include "curl_setup.h"
 
-#ifndef CURL_DISABLE_PROXY
-
-#ifdef HAVE_GSSAPI
-#ifdef HAVE_OLD_GSSMIT
-#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
-#define NCOMPAT 1
-#endif
-#ifndef gss_nt_service_name
-#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
-#endif
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_PROXY)
 
 #include "curl_gssapi.h"
 #include "urldata.h"
@@ -41,10 +32,7 @@
 #include "timeval.h"
 #include "socks.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -60,7 +48,7 @@ static int check_gss_err(struct SessionHandle *data,
                          const char* function)
 {
   if(GSS_ERROR(major_status)) {
-    OM_uint32 maj_stat,min_stat;
+    OM_uint32 maj_stat, min_stat;
     OM_uint32 msg_ctx = 0;
     gss_buffer_desc status_string;
     char buf[1024];
@@ -104,10 +92,10 @@ static int check_gss_err(struct SessionHandle *data,
       gss_release_buffer(&min_stat, &status_string);
     }
     failf(data, "GSS-API error: %s failed:\n%s", function, buf);
-    return(1);
+    return 1;
   }
 
-  return(0);
+  return 0;
 }
 
 CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
@@ -143,7 +131,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
    */
 
   /* prepare service name */
-  if(strchr(serviceptr,'/')) {
+  if(strchr(serviceptr, '/')) {
     service.value = malloc(strlen(serviceptr));
     if(!service.value)
       return CURLE_OUT_OF_MEMORY;
@@ -162,13 +150,13 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
              serviceptr, conn->proxy.name);
 
     gss_major_status = gss_import_name(&gss_minor_status, &service,
-                                       gss_nt_service_name, &server);
+                                       GSS_C_NT_HOSTBASED_SERVICE, &server);
   }
 
   gss_release_buffer(&gss_status, &service); /* clear allocated memory */
 
-  if(check_gss_err(data,gss_major_status,
-                   gss_minor_status,"gss_import_name()")) {
+  if(check_gss_err(data, gss_major_status,
+                   gss_minor_status, "gss_import_name()")) {
     failf(data, "Failed to create service name.");
     gss_release_name(&gss_status, &server);
     return CURLE_COULDNT_CONNECT;
@@ -185,12 +173,13 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
                                                  NULL,
                                                  gss_token,
                                                  &gss_send_token,
+                                                 TRUE,
                                                  &gss_ret_flags);
 
     if(gss_token != GSS_C_NO_BUFFER)
       gss_release_buffer(&gss_status, &gss_recv_token);
-    if(check_gss_err(data,gss_major_status,
-                     gss_minor_status,"gss_init_sec_context")) {
+    if(check_gss_err(data, gss_major_status,
+                     gss_minor_status, "gss_init_sec_context")) {
       gss_release_name(&gss_status, &server);
       gss_release_buffer(&gss_status, &gss_recv_token);
       gss_release_buffer(&gss_status, &gss_send_token);
@@ -203,10 +192,10 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
       socksreq[0] = 1;    /* GSS-API subnegotiation version */
       socksreq[1] = 1;    /* authentication message type */
       us_length = htons((short)gss_send_token.length);
-      memcpy(socksreq+2,&us_length,sizeof(short));
+      memcpy(socksreq+2, &us_length, sizeof(short));
 
       code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
-      if((code != CURLE_OK) || (4 != written)) {
+      if(code || (4 != written)) {
         failf(data, "Failed to send GSS-API authentication request.");
         gss_release_name(&gss_status, &server);
         gss_release_buffer(&gss_status, &gss_recv_token);
@@ -218,7 +207,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
       code = Curl_write_plain(conn, sock, (char *)gss_send_token.value,
                               gss_send_token.length, &written);
 
-      if((code != CURLE_OK) || ((ssize_t)gss_send_token.length != written)) {
+      if(code || ((ssize_t)gss_send_token.length != written)) {
         failf(data, "Failed to send GSS-API authentication token.");
         gss_release_name(&gss_status, &server);
         gss_release_buffer(&gss_status, &gss_recv_token);
@@ -244,7 +233,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
      */
 
     result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
-    if(result != CURLE_OK || actualread != 4) {
+    if(result || (actualread != 4)) {
       failf(data, "Failed to receive GSS-API authentication response.");
       gss_release_name(&gss_status, &server);
       gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -285,7 +274,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
                               gss_recv_token.length, &actualread);
 
-    if(result != CURLE_OK || actualread != us_length) {
+    if(result || (actualread != us_length)) {
       failf(data, "Failed to receive GSS-API authentication token.");
       gss_release_name(&gss_status, &server);
       gss_release_buffer(&gss_status, &gss_recv_token);
@@ -302,8 +291,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   gss_major_status = gss_inquire_context (&gss_minor_status, gss_context,
                                           &gss_client_name, NULL, NULL, NULL,
                                           NULL, NULL, NULL);
-  if(check_gss_err(data,gss_major_status,
-                   gss_minor_status,"gss_inquire_context")) {
+  if(check_gss_err(data, gss_major_status,
+                   gss_minor_status, "gss_inquire_context")) {
     gss_delete_sec_context(&gss_status, &gss_context, NULL);
     gss_release_name(&gss_status, &gss_client_name);
     failf(data, "Failed to determine user name.");
@@ -311,8 +300,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   }
   gss_major_status = gss_display_name(&gss_minor_status, gss_client_name,
                                       &gss_send_token, NULL);
-  if(check_gss_err(data,gss_major_status,
-                   gss_minor_status,"gss_display_name")) {
+  if(check_gss_err(data, gss_major_status,
+                   gss_minor_status, "gss_display_name")) {
     gss_delete_sec_context(&gss_status, &gss_context, NULL);
     gss_release_name(&gss_status, &gss_client_name);
     gss_release_buffer(&gss_status, &gss_send_token);
@@ -383,7 +372,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
    */
   if(data->set.socks5_gssapi_nec) {
     us_length = htons((short)1);
-    memcpy(socksreq+2,&us_length,sizeof(short));
+    memcpy(socksreq+2, &us_length, sizeof(short));
   }
   else {
     gss_send_token.length = 1;
@@ -398,7 +387,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
                                 GSS_C_QOP_DEFAULT, &gss_send_token,
                                 &gss_conf_state, &gss_w_token);
 
-    if(check_gss_err(data,gss_major_status,gss_minor_status,"gss_wrap")) {
+    if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_wrap")) {
       gss_release_buffer(&gss_status, &gss_send_token);
       gss_release_buffer(&gss_status, &gss_w_token);
       gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -408,11 +397,11 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     gss_release_buffer(&gss_status, &gss_send_token);
 
     us_length = htons((short)gss_w_token.length);
-    memcpy(socksreq+2,&us_length,sizeof(short));
+    memcpy(socksreq+2, &us_length, sizeof(short));
   }
 
   code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
-  if((code != CURLE_OK) || (4 != written)) {
+  if(code  || (4 != written)) {
     failf(data, "Failed to send GSS-API encryption request.");
     gss_release_buffer(&gss_status, &gss_w_token);
     gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -422,7 +411,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   if(data->set.socks5_gssapi_nec) {
     memcpy(socksreq, &gss_enc, 1);
     code = Curl_write_plain(conn, sock, socksreq, 1, &written);
-    if((code != CURLE_OK) || ( 1 != written)) {
+    if(code || ( 1 != written)) {
       failf(data, "Failed to send GSS-API encryption type.");
       gss_delete_sec_context(&gss_status, &gss_context, NULL);
       return CURLE_COULDNT_CONNECT;
@@ -431,7 +420,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   else {
     code = Curl_write_plain(conn, sock, (char *)gss_w_token.value,
                             gss_w_token.length, &written);
-    if((code != CURLE_OK) || ((ssize_t)gss_w_token.length != written)) {
+    if(code || ((ssize_t)gss_w_token.length != written)) {
       failf(data, "Failed to send GSS-API encryption type.");
       gss_release_buffer(&gss_status, &gss_w_token);
       gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -441,7 +430,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   }
 
   result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
-  if(result != CURLE_OK || actualread != 4) {
+  if(result || (actualread != 4)) {
     failf(data, "Failed to receive GSS-API encryption response.");
     gss_delete_sec_context(&gss_status, &gss_context, NULL);
     return CURLE_COULDNT_CONNECT;
@@ -474,7 +463,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
                             gss_recv_token.length, &actualread);
 
-  if(result != CURLE_OK || actualread != us_length) {
+  if(result || (actualread != us_length)) {
     failf(data, "Failed to receive GSS-API encryptrion type.");
     gss_release_buffer(&gss_status, &gss_recv_token);
     gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -486,7 +475,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
                                   &gss_recv_token, &gss_w_token,
                                   0, GSS_C_QOP_DEFAULT);
 
-    if(check_gss_err(data,gss_major_status,gss_minor_status,"gss_unwrap")) {
+    if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_unwrap")) {
       gss_release_buffer(&gss_status, &gss_recv_token);
       gss_release_buffer(&gss_status, &gss_w_token);
       gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -503,7 +492,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
       return CURLE_COULDNT_CONNECT;
     }
 
-    memcpy(socksreq,gss_w_token.value,gss_w_token.length);
+    memcpy(socksreq, gss_w_token.value, gss_w_token.length);
     gss_release_buffer(&gss_status, &gss_w_token);
   }
   else {
@@ -515,7 +504,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
       return CURLE_COULDNT_CONNECT;
     }
 
-    memcpy(socksreq,gss_recv_token.value,gss_recv_token.length);
+    memcpy(socksreq, gss_recv_token.value, gss_recv_token.length);
     gss_release_buffer(&gss_status, &gss_recv_token);
   }
 
@@ -529,6 +518,5 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
 
   return CURLE_OK;
 }
-#endif
 
-#endif /* CURL_DISABLE_PROXY */
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_PROXY */
diff --git a/Utilities/cmcurl/lib/socks_sspi.c b/Utilities/cmcurl/lib/socks_sspi.c
index 82684e0..a7708b2 100644
--- a/Utilities/cmcurl/lib/socks_sspi.c
+++ b/Utilities/cmcurl/lib/socks_sspi.c
@@ -5,8 +5,8 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller at compuserve.com>
- * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -34,10 +34,7 @@
 #include "curl_sspi.h"
 #include "curl_multibyte.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use the internal *printf() functions */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -107,8 +104,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     service_name = malloc(strlen(service) + strlen(conn->proxy.name) + 2);
     if(!service_name)
       return CURLE_OUT_OF_MEMORY;
-    snprintf(service_name,strlen(service) +strlen(conn->proxy.name)+2,"%s/%s",
-             service,conn->proxy.name);
+    snprintf(service_name, strlen(service) +strlen(conn->proxy.name)+2,
+             "%s/%s", service, conn->proxy.name);
   }
 
   input_desc.cBuffers = 1;
@@ -146,7 +143,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
 
   if(check_sspi_err(conn, status, "AcquireCredentialsHandle")) {
     failf(data, "Failed to acquire credentials.");
-    Curl_safefree(service_name);
+    free(service_name);
     s_pSecFn->FreeCredentialsHandle(&cred_handle);
     return CURLE_COULDNT_CONNECT;
   }
@@ -185,7 +182,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     }
 
     if(check_sspi_err(conn, status, "InitializeSecurityContext")) {
-      Curl_safefree(service_name);
+      free(service_name);
       s_pSecFn->FreeCredentialsHandle(&cred_handle);
       s_pSecFn->DeleteSecurityContext(&sspi_context);
       if(sspi_recv_token.pvBuffer)
@@ -201,9 +198,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
       memcpy(socksreq+2, &us_length, sizeof(short));
 
       code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
-      if((code != CURLE_OK) || (4 != written)) {
+      if(code || (4 != written)) {
         failf(data, "Failed to send SSPI authentication request.");
-        Curl_safefree(service_name);
+        free(service_name);
         if(sspi_send_token.pvBuffer)
           s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
         if(sspi_recv_token.pvBuffer)
@@ -215,9 +212,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
 
       code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
                               sspi_send_token.cbBuffer, &written);
-      if((code != CURLE_OK) || (sspi_send_token.cbBuffer != (size_t)written)) {
+      if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
         failf(data, "Failed to send SSPI authentication token.");
-        Curl_safefree(service_name);
+        free(service_name);
         if(sspi_send_token.pvBuffer)
           s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
         if(sspi_recv_token.pvBuffer)
@@ -255,9 +252,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
      */
 
     result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
-    if(result != CURLE_OK || actualread != 4) {
+    if(result || (actualread != 4)) {
       failf(data, "Failed to receive SSPI authentication response.");
-      Curl_safefree(service_name);
+      free(service_name);
       s_pSecFn->FreeCredentialsHandle(&cred_handle);
       s_pSecFn->DeleteSecurityContext(&sspi_context);
       return CURLE_COULDNT_CONNECT;
@@ -267,7 +264,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     if(socksreq[1] == 255) { /* status / message type */
       failf(data, "User was rejected by the SOCKS5 server (%u %u).",
             (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
-      Curl_safefree(service_name);
+      free(service_name);
       s_pSecFn->FreeCredentialsHandle(&cred_handle);
       s_pSecFn->DeleteSecurityContext(&sspi_context);
       return CURLE_COULDNT_CONNECT;
@@ -276,7 +273,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     if(socksreq[1] != 1) { /* status / messgae type */
       failf(data, "Invalid SSPI authentication response type (%u %u).",
             (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
-      Curl_safefree(service_name);
+      free(service_name);
       s_pSecFn->FreeCredentialsHandle(&cred_handle);
       s_pSecFn->DeleteSecurityContext(&sspi_context);
       return CURLE_COULDNT_CONNECT;
@@ -289,7 +286,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     sspi_recv_token.pvBuffer = malloc(us_length);
 
     if(!sspi_recv_token.pvBuffer) {
-      Curl_safefree(service_name);
+      free(service_name);
       s_pSecFn->FreeCredentialsHandle(&cred_handle);
       s_pSecFn->DeleteSecurityContext(&sspi_context);
       return CURLE_OUT_OF_MEMORY;
@@ -297,9 +294,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
                                 sspi_recv_token.cbBuffer, &actualread);
 
-    if(result != CURLE_OK || actualread != us_length) {
+    if(result || (actualread != us_length)) {
       failf(data, "Failed to receive SSPI authentication token.");
-      Curl_safefree(service_name);
+      free(service_name);
       if(sspi_recv_token.pvBuffer)
         s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
       s_pSecFn->FreeCredentialsHandle(&cred_handle);
@@ -310,7 +307,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     context_handle = &sspi_context;
   }
 
-  Curl_safefree(service_name);
+  free(service_name);
 
   /* Everything is good so far, user was authenticated! */
   status = s_pSecFn->QueryCredentialsAttributes(&cred_handle,
@@ -405,7 +402,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
       return CURLE_OUT_OF_MEMORY;
     }
 
-    memcpy(sspi_w_token[1].pvBuffer,&gss_enc,1);
+    memcpy(sspi_w_token[1].pvBuffer, &gss_enc, 1);
     sspi_w_token[2].BufferType = SECBUFFER_PADDING;
     sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize;
     sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize);
@@ -459,11 +456,11 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     sspi_w_token[2].cbBuffer = 0;
 
     us_length = htons((short)sspi_send_token.cbBuffer);
-    memcpy(socksreq+2,&us_length,sizeof(short));
+    memcpy(socksreq+2, &us_length, sizeof(short));
   }
 
   code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
-  if((code != CURLE_OK) || (4 != written)) {
+  if(code || (4 != written)) {
     failf(data, "Failed to send SSPI encryption request.");
     if(sspi_send_token.pvBuffer)
       s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
@@ -472,9 +469,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   }
 
   if(data->set.socks5_gssapi_nec) {
-    memcpy(socksreq,&gss_enc,1);
+    memcpy(socksreq, &gss_enc, 1);
     code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
-    if((code != CURLE_OK) || (1 != written)) {
+    if(code || (1 != written)) {
       failf(data, "Failed to send SSPI encryption type.");
       s_pSecFn->DeleteSecurityContext(&sspi_context);
       return CURLE_COULDNT_CONNECT;
@@ -483,7 +480,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   else {
     code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
                             sspi_send_token.cbBuffer, &written);
-    if((code != CURLE_OK) || (sspi_send_token.cbBuffer != (size_t)written)) {
+    if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
       failf(data, "Failed to send SSPI encryption type.");
       if(sspi_send_token.pvBuffer)
         s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
@@ -495,7 +492,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   }
 
   result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
-  if(result != CURLE_OK || actualread != 4) {
+  if(result || (actualread != 4)) {
     failf(data, "Failed to receive SSPI encryption response.");
     s_pSecFn->DeleteSecurityContext(&sspi_context);
     return CURLE_COULDNT_CONNECT;
@@ -529,7 +526,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   result = Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer,
                               sspi_w_token[0].cbBuffer, &actualread);
 
-  if(result != CURLE_OK || actualread != us_length) {
+  if(result || (actualread != us_length)) {
     failf(data, "Failed to receive SSPI encryption type.");
     s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
     s_pSecFn->DeleteSecurityContext(&sspi_context);
@@ -570,7 +567,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
       return CURLE_COULDNT_CONNECT;
     }
 
-    memcpy(socksreq,sspi_w_token[1].pvBuffer,sspi_w_token[1].cbBuffer);
+    memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
     s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
     s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
   }
@@ -582,7 +579,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
       s_pSecFn->DeleteSecurityContext(&sspi_context);
       return CURLE_COULDNT_CONNECT;
     }
-    memcpy(socksreq,sspi_w_token[0].pvBuffer,sspi_w_token[0].cbBuffer);
+    memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer);
     s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
   }
 
diff --git a/Utilities/cmcurl/lib/splay.c b/Utilities/cmcurl/lib/splay.c
index 5bb7065..b87b6cf 100644
--- a/Utilities/cmcurl/lib/splay.c
+++ b/Utilities/cmcurl/lib/splay.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1997 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1997 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -101,13 +101,13 @@ struct Curl_tree *Curl_splayinsert(struct timeval i,
                                    struct Curl_tree *t,
                                    struct Curl_tree *node)
 {
-  static const struct timeval KEY_NOTUSED = {-1,-1}; /* will *NEVER* appear */
+  static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */
 
   if(node == NULL)
     return t;
 
   if(t != NULL) {
-    t = Curl_splay(i,t);
+    t = Curl_splay(i, t);
     if(compare(i, t->key)==0) {
       /* There already exists a node in the tree with the very same key. Build
          a linked list of nodes. We make the new 'node' struct the new master
@@ -162,7 +162,7 @@ struct Curl_tree *Curl_splaygetbest(struct timeval i,
     return NULL;
   }
 
-  t = Curl_splay(i,t);
+  t = Curl_splay(i, t);
   if(compare(i, t->key) < 0) {
     /* too big node, try the smaller chain */
     if(t->smaller)
@@ -223,7 +223,7 @@ int Curl_splayremovebyaddr(struct Curl_tree *t,
                            struct Curl_tree *removenode,
                            struct Curl_tree **newroot)
 {
-  static const struct timeval KEY_NOTUSED = {-1,-1}; /* will *NEVER* appear */
+  static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */
   struct Curl_tree *x;
 
   if(!t || !removenode)
diff --git a/Utilities/cmcurl/lib/ssh.c b/Utilities/cmcurl/lib/ssh.c
index 887e10f..94195a7 100644
--- a/Utilities/cmcurl/lib/ssh.c
+++ b/Utilities/cmcurl/lib/ssh.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -83,10 +83,7 @@
 #include "multiif.h"
 #include "select.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -94,6 +91,9 @@
 #ifdef WIN32
 #  undef  PATH_MAX
 #  define PATH_MAX MAX_PATH
+#  ifndef R_OK
+#    define R_OK 4
+#  endif
 #endif
 
 #ifndef PATH_MAX
@@ -543,6 +543,17 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
       keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
         LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
 
+#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
+      keycheck = libssh2_knownhost_checkp(sshc->kh,
+                                          conn->host.name,
+                                          (conn->remote_port != PORT_SSH)?
+                                          conn->remote_port:-1,
+                                          remotekey, keylen,
+                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                          keybit,
+                                          &host);
+#else
       keycheck = libssh2_knownhost_check(sshc->kh,
                                          conn->host.name,
                                          remotekey, keylen,
@@ -550,6 +561,7 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
                                          keybit,
                                          &host);
+#endif
 
       infof(data, "SSH host check: %d, key: %s\n", keycheck,
             (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
@@ -588,8 +600,10 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
 
     switch(rc) {
     default: /* unknown return codes will equal reject */
+      /* FALLTHROUGH */
     case CURLKHSTAT_REJECT:
       state(conn, SSH_SESSION_FREE);
+      /* FALLTHROUGH */
     case CURLKHSTAT_DEFER:
       /* DEFER means bail out but keep the SSH_HOSTKEY state */
       result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
@@ -732,7 +746,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
        * whatever) is up to us.
        */
       result = ssh_check_fingerprint(conn);
-      if(result == CURLE_OK)
+      if(!result)
         state(conn, SSH_AUTHLIST);
       /* ssh_check_fingerprint sets state appropriately on error */
       break;
@@ -786,7 +800,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
          (strstr(sshc->authlist, "publickey") != NULL)) {
         char *home = NULL;
-        bool rsa_pub_empty_but_ok = FALSE;
+        bool out_of_memory = FALSE;
 
         sshc->rsa_pub = sshc->rsa = NULL;
 
@@ -794,34 +808,55 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
            HOME environment variable etc? */
         home = curl_getenv("HOME");
 
-        if(data->set.str[STRING_SSH_PUBLIC_KEY] &&
-           !*data->set.str[STRING_SSH_PUBLIC_KEY])
-           rsa_pub_empty_but_ok = true;
-        else if(data->set.str[STRING_SSH_PUBLIC_KEY])
-          sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
-        else if(home)
-          sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
-        else
-          /* as a final resort, try current dir! */
-          sshc->rsa_pub = strdup("id_dsa.pub");
-
-        if(!rsa_pub_empty_but_ok && (sshc->rsa_pub == NULL)) {
-          Curl_safefree(home);
-          state(conn, SSH_SESSION_FREE);
-          sshc->actualcode = CURLE_OUT_OF_MEMORY;
-          break;
+        if(data->set.str[STRING_SSH_PRIVATE_KEY])
+          sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
+        else {
+          /* If no private key file is specified, try some common paths. */
+          if(home) {
+            /* Try ~/.ssh first. */
+            sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
+            if(!sshc->rsa)
+              out_of_memory = TRUE;
+            else if(access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
+              if(!sshc->rsa)
+                out_of_memory = TRUE;
+              else if(access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+              }
+            }
+          }
+          if(!out_of_memory && !sshc->rsa) {
+            /* Nothing found; try the current dir. */
+            sshc->rsa = strdup("id_rsa");
+            if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = strdup("id_dsa");
+              if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+                /* Out of guesses. Set to the empty string to avoid
+                 * surprising info messages. */
+                sshc->rsa = strdup("");
+              }
+            }
+          }
         }
 
-        if(data->set.str[STRING_SSH_PRIVATE_KEY])
-          sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
-        else if(home)
-          sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
-        else
-          /* as a final resort, try current dir! */
-          sshc->rsa = strdup("id_dsa");
+        /*
+         * Unless the user explicitly specifies a public key file, let
+         * libssh2 extract the public key from the private key file.
+         * This is done by simply passing sshc->rsa_pub = NULL.
+         */
+        if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
+          sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
+          if(!sshc->rsa_pub)
+            out_of_memory = TRUE;
+        }
 
-        if(sshc->rsa == NULL) {
-          Curl_safefree(home);
+        if(out_of_memory || sshc->rsa == NULL) {
+          free(home);
+          Curl_safefree(sshc->rsa);
           Curl_safefree(sshc->rsa_pub);
           state(conn, SSH_SESSION_FREE);
           sshc->actualcode = CURLE_OUT_OF_MEMORY;
@@ -832,10 +867,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         if(!sshc->passphrase)
           sshc->passphrase = "";
 
-        Curl_safefree(home);
+        free(home);
 
-        infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
-        infof(data, "Using ssh private key file %s\n", sshc->rsa);
+        infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
+        infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
 
         state(conn, SSH_AUTH_PKEY);
       }
@@ -900,6 +935,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       }
       else {
         state(conn, SSH_AUTH_HOST_INIT);
+        rc = 0; /* clear rc and continue */
       }
       break;
 
@@ -984,11 +1020,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
                                     sshc->sshagent_identity);
 
         if(rc < 0) {
-          if(rc != LIBSSH2_ERROR_EAGAIN) {
+          if(rc != LIBSSH2_ERROR_EAGAIN)
             /* tried and failed? go to next identity */
             sshc->sshagent_prev_identity = sshc->sshagent_identity;
-          }
-          break;
+          else
+            break;
         }
       }
 
@@ -1002,8 +1038,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
         infof(data, "Agent based authentication successful\n");
         state(conn, SSH_AUTH_DONE);
       }
-      else
+      else {
         state(conn, SSH_AUTH_KEY_INIT);
+        rc = 0; /* clear rc and continue */
+      }
 #endif
       break;
 
@@ -1702,8 +1740,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
                 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
 
               size_t actuallyread =
-                conn->fread_func(data->state.buffer, 1, readthisamountnow,
-                                 conn->fread_in);
+                data->set.fread_func(data->state.buffer, 1, readthisamountnow,
+                                     data->set.in);
 
               passed += actuallyread;
               if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
@@ -1770,7 +1808,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       break;
 
     case SSH_SFTP_CREATE_DIRS:
-      if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
+      sshc->slash_pos = strchr(sshc->slash_pos, '/');
+      if(sshc->slash_pos) {
         *sshc->slash_pos = 0;
 
         infof(data, "Creating directory '%s'\n", sftp_scp->path);
@@ -1882,7 +1921,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           }
           result = Curl_client_write(conn, CLIENTWRITE_BODY,
                                      tmpLine, sshc->readdir_len+1);
-          Curl_safefree(tmpLine);
+          free(tmpLine);
 
           if(result) {
             state(conn, SSH_STOP);
@@ -1998,7 +2037,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
                                  sshc->readdir_line,
                                  sshc->readdir_currLen);
 
-      if(result == CURLE_OK) {
+      if(!result) {
 
         /* output debug output if that is requested */
         if(data->set.verbose) {
@@ -2068,10 +2107,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       if(rc == LIBSSH2_ERROR_EAGAIN) {
         break;
       }
-      else if(rc) {
+      else if(rc ||
+              !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
+              (attrs.filesize == 0)) {
         /*
          * libssh2_sftp_open() didn't return an error, so maybe the server
          * just doesn't support stat()
+         * OR the server doesn't return a file size with a stat()
+         * OR file size is 0
          */
         data->req.size = -1;
         data->req.maxdownload = -1;
@@ -2101,7 +2144,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
             /* from is relative to end of file */
             from += size;
           }
-          if(from >= size) {
+          if(from > size) {
             failf(data, "Offset (%"
                   CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
                   CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
@@ -2202,7 +2245,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       DEBUGF(infof(data, "SFTP DONE done\n"));
 
       /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
-         After nextstate is executed,the control should come back to
+         After nextstate is executed, the control should come back to
          SSH_SFTP_CLOSE to pass the correct result back  */
       if(sshc->nextstate != SSH_NO_STATE &&
          sshc->nextstate != SSH_SFTP_CLOSE) {
@@ -2691,7 +2734,7 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
     }
 
 #ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-    if((CURLE_OK == result) && block) {
+    if(!result && block) {
       int dir = libssh2_session_block_directions(sshc->ssh_session);
       curl_socket_t sock = conn->sock[FIRSTSOCKET];
       curl_socket_t fd_read = CURL_SOCKET_BAD;
@@ -2863,7 +2906,7 @@ static CURLcode scp_doing(struct connectdata *conn,
 
 static CURLcode ssh_do(struct connectdata *conn, bool *done)
 {
-  CURLcode res;
+  CURLcode result;
   bool connected = 0;
   struct SessionHandle *data = conn->data;
   struct ssh_conn *sshc = &conn->proto.sshc;
@@ -2882,11 +2925,11 @@ static CURLcode ssh_do(struct connectdata *conn, bool *done)
   Curl_pgrsSetDownloadSize(data, -1);
 
   if(conn->handler->protocol & CURLPROTO_SCP)
-    res = scp_perform(conn, &connected,  done);
+    result = scp_perform(conn, &connected,  done);
   else
-    res = sftp_perform(conn, &connected,  done);
+    result = sftp_perform(conn, &connected,  done);
 
-  return res;
+  return result;
 }
 
 /* BLOCKING, but the function is using the state machine so the only reason
@@ -2918,7 +2961,7 @@ static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
   CURLcode result = CURLE_OK;
   struct SSHPROTO *sftp_scp = conn->data->req.protop;
 
-  if(status == CURLE_OK) {
+  if(!status) {
     /* run the state-machine
 
        TODO: when the multi interface is used, this _really_ should be using
@@ -2946,7 +2989,7 @@ static CURLcode scp_done(struct connectdata *conn, CURLcode status,
 {
   (void)premature; /* not used */
 
-  if(status == CURLE_OK)
+  if(!status)
     state(conn, SSH_SCP_DONE);
 
   return ssh_done(conn, status);
@@ -3044,8 +3087,7 @@ CURLcode sftp_perform(struct connectdata *conn,
 static CURLcode sftp_doing(struct connectdata *conn,
                            bool *dophase_done)
 {
-  CURLcode result;
-  result = ssh_multi_statemach(conn, dophase_done);
+  CURLcode result = ssh_multi_statemach(conn, dophase_done);
 
   if(*dophase_done) {
     DEBUGF(infof(conn->data, "DO phase is complete\n"));
@@ -3082,7 +3124,7 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
 {
   struct ssh_conn *sshc = &conn->proto.sshc;
 
-  if(status == CURLE_OK) {
+  if(!status) {
     /* Post quote commands are executed after the SFTP_CLOSE state to avoid
        errors that could happen due to open file handles during POSTQUOTE
        operation */
@@ -3228,8 +3270,8 @@ get_pathname(const char **cpp, char **path)
   return CURLE_OK;
 
   fail:
-    Curl_safefree(*path);
-    return CURLE_QUOTE_ERROR;
+  Curl_safefree(*path);
+  return CURLE_QUOTE_ERROR;
 }
 
 
diff --git a/Utilities/cmcurl/lib/ssh.h b/Utilities/cmcurl/lib/ssh.h
index ff2e16b..b3cc54c 100644
--- a/Utilities/cmcurl/lib/ssh.h
+++ b/Utilities/cmcurl/lib/ssh.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -44,9 +44,9 @@ typedef enum {
   SSH_AUTH_PKEY,
   SSH_AUTH_PASS_INIT,
   SSH_AUTH_PASS,
-  SSH_AUTH_AGENT_INIT,/* initialize then wait for connection to agent */
-  SSH_AUTH_AGENT_LIST,/* ask for list then wait for entire list to come */
-  SSH_AUTH_AGENT,     /* attempt one key at a time */
+  SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */
+  SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */
+  SSH_AUTH_AGENT,      /* attempt one key at a time */
   SSH_AUTH_HOST_INIT,
   SSH_AUTH_HOST,
   SSH_AUTH_KEY_INIT,
@@ -158,22 +158,34 @@ struct ssh_conn {
 
 #ifdef USE_LIBSSH2
 
+/* Feature detection based on version numbers to better work with
+   non-configure platforms */
+
 #if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
 #  error "SCP/SFTP protocols require libssh2 0.16 or later"
 #endif
 
-#if defined(LIBSSH2_VERSION_NUM) && (LIBSSH2_VERSION_NUM >= 0x010000)
-#  define HAVE_LIBSSH2_SFTP_SEEK64 1
-#else
-#  undef HAVE_LIBSSH2_SFTP_SEEK64
+#if LIBSSH2_VERSION_NUM >= 0x010000
+#define HAVE_LIBSSH2_SFTP_SEEK64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010100
+#define HAVE_LIBSSH2_VERSION 1
 #endif
 
-#if defined(LIBSSH2_VERSION_NUM) && (LIBSSH2_VERSION_NUM >= 0x010206)
-#  define HAVE_LIBSSH2_SCP_SEND64 1
-#else
-#  undef HAVE_LIBSSH2_SCP_SEND64
+#if LIBSSH2_VERSION_NUM >= 0x010205
+#define HAVE_LIBSSH2_INIT 1
+#define HAVE_LIBSSH2_EXIT 1
 #endif
 
+#if LIBSSH2_VERSION_NUM >= 0x010206
+#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1
+#define HAVE_LIBSSH2_SCP_SEND64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010208
+#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1
+#endif
 
 extern const struct Curl_handler Curl_handler_scp;
 extern const struct Curl_handler Curl_handler_sftp;
diff --git a/Utilities/cmcurl/lib/strdup.c b/Utilities/cmcurl/lib/strdup.c
index 3b776b1..5685b81 100644
--- a/Utilities/cmcurl/lib/strdup.c
+++ b/Utilities/cmcurl/lib/strdup.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -19,12 +19,12 @@
  * KIND, either express or implied.
  *
  ***************************************************************************/
-/*
- * This file is 'mem-include-scan' clean. See test 1132.
- */
 #include "curl_setup.h"
-
 #include "strdup.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
 
 #ifndef HAVE_STRDUP
 char *curlx_strdup(const char *str)
@@ -44,9 +44,30 @@ char *curlx_strdup(const char *str)
   if(!newstr)
     return (char *)NULL;
 
-  memcpy(newstr,str,(len+1)*sizeof(char));
+  memcpy(newstr, str, (len+1)*sizeof(char));
 
   return newstr;
 
 }
 #endif
+
+/***************************************************************************
+ *
+ * Curl_memdup(source, length)
+ *
+ * Copies the 'source' data to a newly allocated buffer (that is
+ * returned). Copies 'length' bytes.
+ *
+ * Returns the new pointer or NULL on failure.
+ *
+ ***************************************************************************/
+char *Curl_memdup(const char *src, size_t length)
+{
+  char *buffer = malloc(length);
+  if(!buffer)
+    return NULL; /* fail */
+
+  memcpy(buffer, src, length);
+
+  return buffer;
+}
diff --git a/Utilities/cmcurl/lib/strdup.h b/Utilities/cmcurl/lib/strdup.h
index 49af911..23a71f8 100644
--- a/Utilities/cmcurl/lib/strdup.h
+++ b/Utilities/cmcurl/lib/strdup.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,5 +26,6 @@
 #ifndef HAVE_STRDUP
 extern char *curlx_strdup(const char *str);
 #endif
+char *Curl_memdup(const char *src, size_t buffer_length);
 
 #endif /* HEADER_CURL_STRDUP_H */
diff --git a/Utilities/cmcurl/lib/strerror.c b/Utilities/cmcurl/lib/strerror.c
index 66033f2..5657141 100644
--- a/Utilities/cmcurl/lib/strerror.c
+++ b/Utilities/cmcurl/lib/strerror.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2004 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2004 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -40,10 +40,7 @@
 #endif
 
 #include "strerror.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -298,6 +295,12 @@ curl_easy_strerror(CURLcode error)
   case CURLE_NO_CONNECTION_AVAILABLE:
     return "The max connection limit is reached";
 
+  case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
+    return "SSL public key does not match pinned public key";
+
+  case CURLE_SSL_INVALIDCERTSTATUS:
+    return "SSL server certificate status verification FAILED";
+
     /* error codes not used by current libcurl */
   case CURLE_OBSOLETE20:
   case CURLE_OBSOLETE24:
@@ -327,7 +330,7 @@ curl_easy_strerror(CURLcode error)
    */
   return "Unknown error";
 #else
-  if(error == CURLE_OK)
+  if(!error)
     return "No error";
   else
     return "Error";
@@ -594,7 +597,7 @@ get_winsock_error (int err, char *buf, size_t len)
     return NULL;
   }
 #else
-  if(err == CURLE_OK)
+  if(!err)
     return NULL;
   else
     p = "error";
@@ -638,7 +641,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
 
     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
                   LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
-    wcstombs(buf,wbuf,max);
+    wcstombs(buf, wbuf, max);
   }
 #else
   /* 'sys_nerr' is the maximum errno number, it is not widely portable */
@@ -705,9 +708,9 @@ const char *Curl_strerror(struct connectdata *conn, int err)
   buf[max] = '\0'; /* make sure the string is zero terminated */
 
   /* strip trailing '\r\n' or '\n'. */
-  if((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2)
+  if((p = strrchr(buf, '\n')) != NULL && (p - buf) >= 2)
      *p = '\0';
-  if((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1)
+  if((p = strrchr(buf, '\r')) != NULL && (p - buf) >= 1)
      *p = '\0';
 
   if(old_errno != ERRNO)
@@ -821,6 +824,9 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
     case SEC_E_OK:
       txt = "No error";
       break;
+    case CRYPT_E_REVOKED:
+      txt = "CRYPT_E_REVOKED";
+      break;
     case SEC_E_ALGORITHM_MISMATCH:
       txt = "SEC_E_ALGORITHM_MISMATCH";
       break;
@@ -1064,6 +1070,12 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
 
   if(err == SEC_E_OK)
     strncpy(outbuf, txt, outmax);
+  else if(err == SEC_E_ILLEGAL_MESSAGE)
+    snprintf(outbuf, outmax,
+             "SEC_E_ILLEGAL_MESSAGE (0x%04X%04X) - This error usually occurs "
+             "when a fatal SSL/TLS alert is received (e.g. handshake failed). "
+             "More detail may be available in the Windows System event log.",
+             (err >> 16) & 0xffff, err & 0xffff);
   else {
     str = txtbuf;
     snprintf(txtbuf, sizeof(txtbuf), "%s (0x%04X%04X)",
@@ -1079,7 +1091,7 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
                        FORMAT_MESSAGE_IGNORE_INSERTS,
                        NULL, err, LANG_NEUTRAL,
                        wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
-        wcstombs(msgbuf,wbuf,sizeof(msgbuf)-1);
+        wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1);
         msg_formatted = TRUE;
       }
     }
@@ -1094,9 +1106,9 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
     if(msg_formatted) {
       msgbuf[sizeof(msgbuf)-1] = '\0';
       /* strip trailing '\r\n' or '\n' */
-      if((p = strrchr(msgbuf,'\n')) != NULL && (p - msgbuf) >= 2)
+      if((p = strrchr(msgbuf, '\n')) != NULL && (p - msgbuf) >= 2)
          *p = '\0';
-      if((p = strrchr(msgbuf,'\r')) != NULL && (p - msgbuf) >= 1)
+      if((p = strrchr(msgbuf, '\r')) != NULL && (p - msgbuf) >= 1)
          *p = '\0';
       msg = msgbuf;
     }
diff --git a/Utilities/cmcurl/lib/strtoofft.h b/Utilities/cmcurl/lib/strtoofft.h
index b812a67..75c73d4 100644
--- a/Utilities/cmcurl/lib/strtoofft.h
+++ b/Utilities/cmcurl/lib/strtoofft.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -45,7 +45,14 @@
 #    define curlx_strtoofft strtoll
 #  else
 #    if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64)
-       _CRTIMP __int64 __cdecl _strtoi64(const char *, char **, int);
+#      if defined(_SAL_VERSION)
+         _Check_return_ _CRTIMP __int64 __cdecl _strtoi64(
+             _In_z_ const char *_String,
+             _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix);
+#      else
+         _CRTIMP __int64 __cdecl _strtoi64(const char *_String,
+                                           char **_EndPtr, int _Radix);
+#      endif
 #      define curlx_strtoofft _strtoi64
 #    else
        curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base);
diff --git a/Utilities/cmcurl/lib/telnet.c b/Utilities/cmcurl/lib/telnet.c
index 1f03a00..aabf99d 100644
--- a/Utilities/cmcurl/lib/telnet.c
+++ b/Utilities/cmcurl/lib/telnet.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -51,21 +51,19 @@
 #include "telnet.h"
 #include "connect.h"
 #include "progress.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #define  TELOPTS
 #define  TELCMDS
 
 #include "arpa_telnet.h"
-#include "curl_memory.h"
 #include "select.h"
 #include "strequal.h"
 #include "rawstr.h"
 #include "warnless.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #define SUBBUFSIZE 512
@@ -228,9 +226,9 @@ check_wsock2 ( struct SessionHandle *data )
   if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
       HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
       /* Our version isn't supported */
-      failf(data,"insufficient winsock version to support "
-            "telnet");
-      return CURLE_FAILED_INIT;
+    failf(data, "insufficient winsock version to support "
+          "telnet");
+    return CURLE_FAILED_INIT;
   }
 
   /* Our version is supported */
@@ -710,7 +708,6 @@ static void printsub(struct SessionHandle *data,
                      size_t length)             /* length of suboption data */
 {
   unsigned int i = 0;
-  unsigned short *pval;
 
   if(data->set.verbose) {
     if(direction) {
@@ -763,9 +760,9 @@ static void printsub(struct SessionHandle *data,
 
     switch(pointer[0]) {
     case CURL_TELOPT_NAWS:
-      pval = (unsigned short*)(pointer+1);
-      infof(data, "Width: %hu ; Height: %hu",
-            ntohs(pval[0]), ntohs(pval[1]));
+      if(length > 4)
+        infof(data, "Width: %hu ; Height: %hu", (pointer[1]<<8) | pointer[2],
+              (pointer[3]<<8) | pointer[4]);
       break;
     default:
       switch(pointer[1]) {
@@ -1076,7 +1073,7 @@ CURLcode telrcv(struct connectdata *conn,
                                CLIENTWRITE_BODY,              \
                                (char *)&inbuf[startwrite],    \
                                in-startwrite);                \
-    if(result != CURLE_OK)                                    \
+    if(result)                                                \
       return result;                                          \
   }                                                           \
   startwrite = -1
@@ -1177,7 +1174,7 @@ CURLcode telrcv(struct connectdata *conn,
         if(c == CURL_IAC)
           tn->telrcv_state = CURL_TS_SE;
         else
-          CURL_SB_ACCUM(tn,c);
+          CURL_SB_ACCUM(tn, c);
         break;
 
       case CURL_TS_SE:
@@ -1202,7 +1199,7 @@ CURLcode telrcv(struct connectdata *conn,
             tn->telrcv_state = CURL_TS_IAC;
             goto process_iac;
           }
-          CURL_SB_ACCUM(tn,c);
+          CURL_SB_ACCUM(tn, c);
           tn->telrcv_state = CURL_TS_SB;
         }
         else
@@ -1230,9 +1227,9 @@ static CURLcode send_telnet_data(struct connectdata *conn,
   unsigned char outbuf[2];
   ssize_t bytes_written, total_written;
   int out_count;
-  CURLcode rc = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
-  while(rc == CURLE_OK && nread--) {
+  while(!result && nread--) {
     outbuf[0] = *buffer++;
     out_count = 1;
     if(outbuf[0] == CURL_IAC)
@@ -1247,19 +1244,20 @@ static CURLcode send_telnet_data(struct connectdata *conn,
       switch (Curl_poll(pfd, 1, -1)) {
         case -1:                    /* error, abort writing */
         case 0:                     /* timeout (will never happen) */
-          rc = CURLE_SEND_ERROR;
+          result = CURLE_SEND_ERROR;
           break;
         default:                    /* write! */
           bytes_written = 0;
-          rc = Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf+total_written,
-                          out_count-total_written, &bytes_written);
+          result = Curl_write(conn, conn->sock[FIRSTSOCKET],
+                              outbuf+total_written, out_count-total_written,
+                              &bytes_written);
           total_written += bytes_written;
           break;
       }
-    /* handle partial write */
-    } while(rc == CURLE_OK && total_written < out_count);
+      /* handle partial write */
+    } while(!result && total_written < out_count);
   }
-  return rc;
+  return result;
 }
 
 static CURLcode telnet_done(struct connectdata *conn,
@@ -1282,7 +1280,7 @@ static CURLcode telnet_done(struct connectdata *conn,
 
 static CURLcode telnet_do(struct connectdata *conn, bool *done)
 {
-  CURLcode code;
+  CURLcode result;
   struct SessionHandle *data = conn->data;
   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
 #ifdef USE_WINSOCK
@@ -1315,65 +1313,61 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
 
   *done = TRUE; /* unconditionally */
 
-  code = init_telnet(conn);
-  if(code)
-    return code;
+  result = init_telnet(conn);
+  if(result)
+    return result;
 
   tn = (struct TELNET *)data->req.protop;
 
-  code = check_telnet_options(conn);
-  if(code)
-    return code;
+  result = check_telnet_options(conn);
+  if(result)
+    return result;
 
 #ifdef USE_WINSOCK
   /*
   ** This functionality only works with WinSock >= 2.0.  So,
   ** make sure have it.
   */
-  code = check_wsock2(data);
-  if(code)
-    return code;
+  result = check_wsock2(data);
+  if(result)
+    return result;
 
   /* OK, so we have WinSock 2.0.  We need to dynamically */
   /* load ws2_32.dll and get the function pointers we need. */
   wsock2 = LoadLibrary(TEXT("WS2_32.DLL"));
   if(wsock2 == NULL) {
-    failf(data,"failed to load WS2_32.DLL (%d)", ERRNO);
+    failf(data, "failed to load WS2_32.DLL (%d)", ERRNO);
     return CURLE_FAILED_INIT;
   }
 
   /* Grab a pointer to WSACreateEvent */
-  create_event_func = GetProcAddress(wsock2,"WSACreateEvent");
+  create_event_func = GetProcAddress(wsock2, "WSACreateEvent");
   if(create_event_func == NULL) {
-    failf(data,"failed to find WSACreateEvent function (%d)",
-          ERRNO);
+    failf(data, "failed to find WSACreateEvent function (%d)", ERRNO);
     FreeLibrary(wsock2);
     return CURLE_FAILED_INIT;
   }
 
   /* And WSACloseEvent */
-  close_event_func = GetProcAddress(wsock2,"WSACloseEvent");
+  close_event_func = GetProcAddress(wsock2, "WSACloseEvent");
   if(close_event_func == NULL) {
-    failf(data,"failed to find WSACloseEvent function (%d)",
-          ERRNO);
+    failf(data, "failed to find WSACloseEvent function (%d)", ERRNO);
     FreeLibrary(wsock2);
     return CURLE_FAILED_INIT;
   }
 
   /* And WSAEventSelect */
-  event_select_func = GetProcAddress(wsock2,"WSAEventSelect");
+  event_select_func = GetProcAddress(wsock2, "WSAEventSelect");
   if(event_select_func == NULL) {
-    failf(data,"failed to find WSAEventSelect function (%d)",
-          ERRNO);
+    failf(data, "failed to find WSAEventSelect function (%d)", ERRNO);
     FreeLibrary(wsock2);
     return CURLE_FAILED_INIT;
   }
 
   /* And WSAEnumNetworkEvents */
-  enum_netevents_func = GetProcAddress(wsock2,"WSAEnumNetworkEvents");
+  enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents");
   if(enum_netevents_func == NULL) {
-    failf(data,"failed to find WSAEnumNetworkEvents function (%d)",
-          ERRNO);
+    failf(data, "failed to find WSAEnumNetworkEvents function (%d)", ERRNO);
     FreeLibrary(wsock2);
     return CURLE_FAILED_INIT;
   }
@@ -1386,7 +1380,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
   /* First, create a sockets event object */
   event_handle = (WSAEVENT)create_event_func();
   if(event_handle == WSA_INVALID_EVENT) {
-    failf(data,"WSACreateEvent failed (%d)", SOCKERRNO);
+    failf(data, "WSACreateEvent failed (%d)", SOCKERRNO);
     FreeLibrary(wsock2);
     return CURLE_FAILED_INIT;
   }
@@ -1427,29 +1421,30 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
     case WAIT_TIMEOUT:
     {
       for(;;) {
-        if(obj_count == 1) {
+        if(data->set.is_fread_set) {
           /* read from user-supplied method */
-          code = (int)conn->fread_func(buf, 1, BUFSIZE - 1, conn->fread_in);
-          if(code == CURL_READFUNC_ABORT) {
+          result = (int)data->set.fread_func(buf, 1, BUFSIZE - 1,
+                                             data->set.in);
+          if(result == CURL_READFUNC_ABORT) {
             keepon = FALSE;
-            code = CURLE_READ_ERROR;
+            result = CURLE_READ_ERROR;
             break;
           }
 
-          if(code == CURL_READFUNC_PAUSE)
+          if(result == CURL_READFUNC_PAUSE)
             break;
 
-          if(code == 0)                        /* no bytes */
+          if(result == 0)                        /* no bytes */
             break;
 
-          readfile_read = code; /* fall thru with number of bytes read */
+          readfile_read = result; /* fall thru with number of bytes read */
         }
         else {
           /* read from stdin */
           if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL,
                             &readfile_read, NULL)) {
             keepon = FALSE;
-            code = CURLE_READ_ERROR;
+            result = CURLE_READ_ERROR;
             break;
           }
 
@@ -1459,13 +1454,13 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
           if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
                        &readfile_read, NULL)) {
             keepon = FALSE;
-            code = CURLE_READ_ERROR;
+            result = CURLE_READ_ERROR;
             break;
           }
         }
 
-        code = send_telnet_data(conn, buf, readfile_read);
-        if(code) {
+        result = send_telnet_data(conn, buf, readfile_read);
+        if(result) {
           keepon = FALSE;
           break;
         }
@@ -1478,12 +1473,12 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
       if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
                    &readfile_read, NULL)) {
         keepon = FALSE;
-        code = CURLE_READ_ERROR;
+        result = CURLE_READ_ERROR;
         break;
       }
 
-      code = send_telnet_data(conn, buf, readfile_read);
-      if(code) {
+      result = send_telnet_data(conn, buf, readfile_read);
+      if(result) {
         keepon = FALSE;
         break;
       }
@@ -1495,20 +1490,20 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
       events.lNetworkEvents = 0;
       if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) {
         if((err = SOCKERRNO) != EINPROGRESS) {
-          infof(data,"WSAEnumNetworkEvents failed (%d)", err);
+          infof(data, "WSAEnumNetworkEvents failed (%d)", err);
           keepon = FALSE;
-          code = CURLE_READ_ERROR;
+          result = CURLE_READ_ERROR;
         }
         break;
       }
       if(events.lNetworkEvents & FD_READ) {
         /* read data from network */
-        code = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
+        result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
         /* read would've blocked. Loop again */
-        if(code == CURLE_AGAIN)
+        if(result == CURLE_AGAIN)
           break;
         /* returned not-zero, this an error */
-        else if(code) {
+        else if(result) {
           keepon = FALSE;
           break;
         }
@@ -1519,8 +1514,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
           break;
         }
 
-        code = telrcv(conn, (unsigned char *)buf, nread);
-        if(code) {
+        result = telrcv(conn, (unsigned char *) buf, nread);
+        if(result) {
           keepon = FALSE;
           break;
         }
@@ -1544,7 +1539,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
       now = Curl_tvnow();
       if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
         failf(data, "Time-out");
-        code = CURLE_OPERATION_TIMEDOUT;
+        result = CURLE_OPERATION_TIMEDOUT;
         keepon = FALSE;
       }
     }
@@ -1552,7 +1547,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
 
   /* We called WSACreateEvent, so call WSACloseEvent */
   if(!close_event_func(event_handle)) {
-    infof(data,"WSACloseEvent failed (%d)", SOCKERRNO);
+    infof(data, "WSACloseEvent failed (%d)", SOCKERRNO);
   }
 
   /* "Forget" pointers into the library we're about to free */
@@ -1563,18 +1558,18 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
 
   /* We called LoadLibrary, so call FreeLibrary */
   if(!FreeLibrary(wsock2))
-    infof(data,"FreeLibrary(wsock2) failed (%d)", ERRNO);
+    infof(data, "FreeLibrary(wsock2) failed (%d)", ERRNO);
 #else
   pfd[0].fd = sockfd;
   pfd[0].events = POLLIN;
 
-  if(conn->fread_func != (curl_read_callback)fread) {
+  if(data->set.fread_func != (curl_read_callback)fread) {
     poll_cnt = 1;
     interval_ms = 100; /* poll user-supplied read function */
   }
   else {
     /* really using fread, so infile is a FILE* */
-    pfd[1].fd = fileno((FILE *)conn->fread_in);
+    pfd[1].fd = fileno((FILE *)data->set.in);
     pfd[1].events = POLLIN;
     poll_cnt = 2;
     interval_ms = 1 * 1000;
@@ -1592,12 +1587,12 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
     default:                    /* read! */
       if(pfd[0].revents & POLLIN) {
         /* read data from network */
-        code = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
+        result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
         /* read would've blocked. Loop again */
-        if(code == CURLE_AGAIN)
+        if(result == CURLE_AGAIN)
           break;
         /* returned not-zero, this an error */
-        else if(code) {
+        else if(result) {
           keepon = FALSE;
           break;
         }
@@ -1610,8 +1605,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
 
         total_dl += nread;
         Curl_pgrsSetDownloadCounter(data, total_dl);
-        code = telrcv(conn, (unsigned char *)buf, nread);
-        if(code) {
+        result = telrcv(conn, (unsigned char *)buf, nread);
+        if(result) {
           keepon = FALSE;
           break;
         }
@@ -1633,7 +1628,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
       }
       else {
         /* read from user-supplied method */
-        nread = (int)conn->fread_func(buf, 1, BUFSIZE - 1, conn->fread_in);
+        nread = (int)data->set.fread_func(buf, 1, BUFSIZE - 1, data->set.in);
         if(nread == CURL_READFUNC_ABORT) {
           keepon = FALSE;
           break;
@@ -1643,8 +1638,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
       }
 
       if(nread > 0) {
-        code = send_telnet_data(conn, buf, nread);
-        if(code) {
+        result = send_telnet_data(conn, buf, nread);
+        if(result) {
           keepon = FALSE;
           break;
         }
@@ -1661,13 +1656,13 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
       now = Curl_tvnow();
       if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
         failf(data, "Time-out");
-        code = CURLE_OPERATION_TIMEDOUT;
+        result = CURLE_OPERATION_TIMEDOUT;
         keepon = FALSE;
       }
     }
 
     if(Curl_pgrsUpdate(conn)) {
-      code = CURLE_ABORTED_BY_CALLBACK;
+      result = CURLE_ABORTED_BY_CALLBACK;
       break;
     }
   }
@@ -1675,6 +1670,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
   /* mark this as "no further transfer wanted" */
   Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
 
-  return code;
+  return result;
 }
 #endif
diff --git a/Utilities/cmcurl/lib/tftp.c b/Utilities/cmcurl/lib/tftp.c
index e499c45..4c5796f 100644
--- a/Utilities/cmcurl/lib/tftp.c
+++ b/Utilities/cmcurl/lib/tftp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -57,14 +57,11 @@
 #include "url.h"
 #include "rawstr.h"
 #include "speedcheck.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#include "curl_memory.h"
+#include "curl_printf.h"
 #include "select.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /* RFC2348 allows the block size to be negotiated */
@@ -148,8 +145,8 @@ typedef struct tftp_state_data {
 
 
 /* Forward declarations */
-static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) ;
-static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) ;
+static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event);
+static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event);
 static CURLcode tftp_connect(struct connectdata *conn, bool *done);
 static CURLcode tftp_disconnect(struct connectdata *conn,
                                 bool dead_connection);
@@ -221,7 +218,7 @@ static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
     state->max_time = state->start_time+maxtime;
 
     /* Set per-block timeout to total */
-    timeout = maxtime ;
+    timeout = maxtime;
 
     /* Average restart after 5 seconds */
     state->retry_max = (int)timeout/5;
@@ -411,38 +408,38 @@ static size_t tftp_option_add(tftp_state_data_t *state, size_t csize,
   if(( strlen(option) + csize + 1 ) > (size_t)state->blksize)
     return 0;
   strcpy(buf, option);
-  return( strlen(option) + 1 );
+  return strlen(option) + 1;
 }
 
 static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
                                     tftp_event_t event)
 {
-  CURLcode res;
+  CURLcode result;
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
   struct SessionHandle *data = state->conn->data;
 
   infof(data, "%s\n", "Connected for transmit");
 #endif
   state->state = TFTP_STATE_TX;
-  res = tftp_set_timeouts(state);
-  if(res != CURLE_OK)
-    return(res);
+  result = tftp_set_timeouts(state);
+  if(result)
+    return result;
   return tftp_tx(state, event);
 }
 
 static CURLcode tftp_connect_for_rx(tftp_state_data_t *state,
                                     tftp_event_t event)
 {
-  CURLcode res;
+  CURLcode result;
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
   struct SessionHandle *data = state->conn->data;
 
   infof(data, "%s\n", "Connected for receive");
 #endif
   state->state = TFTP_STATE_RX;
-  res = tftp_set_timeouts(state);
-  if(res != CURLE_OK)
-    return(res);
+  result = tftp_set_timeouts(state);
+  if(result)
+    return result;
   return tftp_rx(state, event);
 }
 
@@ -454,7 +451,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
   char *filename;
   char buf[64];
   struct SessionHandle *data = state->conn->data;
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   /* Set ascii mode if -B flag was used */
   if(data->set.prefer_ascii)
@@ -469,7 +466,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
     if(state->retries>state->retry_max) {
       state->error = TFTP_ERR_NORESPONSE;
       state->state = TFTP_STATE_FIN;
-      return res;
+      return result;
     }
 
     if(data->set.upload) {
@@ -534,24 +531,24 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
     if(senddata != (ssize_t)sbytes) {
       failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
     }
-    Curl_safefree(filename);
+    free(filename);
     break;
 
   case TFTP_EVENT_OACK:
     if(data->set.upload) {
-      res = tftp_connect_for_tx(state, event);
+      result = tftp_connect_for_tx(state, event);
     }
     else {
-      res = tftp_connect_for_rx(state, event);
+      result = tftp_connect_for_rx(state, event);
     }
     break;
 
   case TFTP_EVENT_ACK: /* Connected for transmit */
-    res = tftp_connect_for_tx(state, event);
+    result = tftp_connect_for_tx(state, event);
     break;
 
   case TFTP_EVENT_DATA: /* Connected for receive */
-    res = tftp_connect_for_rx(state, event);
+    result = tftp_connect_for_rx(state, event);
     break;
 
   case TFTP_EVENT_ERROR:
@@ -562,7 +559,8 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
     failf(state->conn->data, "tftp_send_first: internal error");
     break;
   }
-  return res;
+
+  return result;
 }
 
 /* the next blocknum is x + 1 but it needs to wrap at an unsigned 16bit
@@ -702,7 +700,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
   struct SessionHandle *data = state->conn->data;
   ssize_t sbytes;
   int rblock;
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
   struct SingleRequest *k = &data->req;
 
   switch(event) {
@@ -728,7 +726,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
         if(state->retries>state->retry_max) {
           failf(data, "tftp_tx: giving up waiting for block %d ack",
                 state->block);
-          res = CURLE_SEND_ERROR;
+          result = CURLE_SEND_ERROR;
         }
         else {
           /* Re-send the data packet */
@@ -739,10 +737,11 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
           /* Check all sbytes were sent */
           if(sbytes<0) {
             failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
-            res = CURLE_SEND_ERROR;
+            result = CURLE_SEND_ERROR;
           }
         }
-        return res;
+
+        return result;
       }
       /* This is the expected packet.  Reset the counters and send the next
          block */
@@ -759,11 +758,13 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
       state->state = TFTP_STATE_FIN;
       return CURLE_OK;
     }
-    res = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes);
-    if(res)
-      return res;
-    sbytes = sendto(state->sockfd, (void *)state->spacket.data,
-                    4+state->sbytes, SEND_4TH_ARG,
+
+    result = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes);
+    if(result)
+      return result;
+
+    sbytes = sendto(state->sockfd, (void *) state->spacket.data,
+                    4 + state->sbytes, SEND_4TH_ARG,
                     (struct sockaddr *)&state->remote_addr,
                     state->remote_addrlen);
     /* Check all sbytes were sent */
@@ -819,7 +820,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
     break;
   }
 
-  return res;
+  return result;
 }
 
 /**********************************************************
@@ -831,48 +832,47 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
  **********************************************************/
 static CURLcode tftp_translate_code(tftp_error_t error)
 {
-  CURLcode code = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   if(error != TFTP_ERR_NONE) {
     switch(error) {
     case TFTP_ERR_NOTFOUND:
-      code = CURLE_TFTP_NOTFOUND;
+      result = CURLE_TFTP_NOTFOUND;
       break;
     case TFTP_ERR_PERM:
-      code = CURLE_TFTP_PERM;
+      result = CURLE_TFTP_PERM;
       break;
     case TFTP_ERR_DISKFULL:
-      code = CURLE_REMOTE_DISK_FULL;
+      result = CURLE_REMOTE_DISK_FULL;
       break;
     case TFTP_ERR_UNDEF:
     case TFTP_ERR_ILLEGAL:
-      code = CURLE_TFTP_ILLEGAL;
+      result = CURLE_TFTP_ILLEGAL;
       break;
     case TFTP_ERR_UNKNOWNID:
-      code = CURLE_TFTP_UNKNOWNID;
+      result = CURLE_TFTP_UNKNOWNID;
       break;
     case TFTP_ERR_EXISTS:
-      code = CURLE_REMOTE_FILE_EXISTS;
+      result = CURLE_REMOTE_FILE_EXISTS;
       break;
     case TFTP_ERR_NOSUCHUSER:
-      code = CURLE_TFTP_NOSUCHUSER;
+      result = CURLE_TFTP_NOSUCHUSER;
       break;
     case TFTP_ERR_TIMEOUT:
-      code = CURLE_OPERATION_TIMEDOUT;
+      result = CURLE_OPERATION_TIMEDOUT;
       break;
     case TFTP_ERR_NORESPONSE:
-      code = CURLE_COULDNT_CONNECT;
+      result = CURLE_COULDNT_CONNECT;
       break;
     default:
-      code= CURLE_ABORTED_BY_CALLBACK;
+      result = CURLE_ABORTED_BY_CALLBACK;
       break;
     }
   }
-  else {
-    code = CURLE_OK;
-  }
+  else
+    result = CURLE_OK;
 
-  return(code);
+  return result;
 }
 
 /**********************************************************
@@ -885,20 +885,21 @@ static CURLcode tftp_translate_code(tftp_error_t error)
 static CURLcode tftp_state_machine(tftp_state_data_t *state,
                                    tftp_event_t event)
 {
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
   struct SessionHandle *data = state->conn->data;
+
   switch(state->state) {
   case TFTP_STATE_START:
     DEBUGF(infof(data, "TFTP_STATE_START\n"));
-    res = tftp_send_first(state, event);
+    result = tftp_send_first(state, event);
     break;
   case TFTP_STATE_RX:
     DEBUGF(infof(data, "TFTP_STATE_RX\n"));
-    res = tftp_rx(state, event);
+    result = tftp_rx(state, event);
     break;
   case TFTP_STATE_TX:
     DEBUGF(infof(data, "TFTP_STATE_TX\n"));
-    res = tftp_tx(state, event);
+    result = tftp_tx(state, event);
     break;
   case TFTP_STATE_FIN:
     infof(data, "%s\n", "TFTP finished");
@@ -906,10 +907,11 @@ static CURLcode tftp_state_machine(tftp_state_data_t *state,
   default:
     DEBUGF(infof(data, "STATE: %d\n", state->state));
     failf(data, "%s", "Internal state machine error");
-    res = CURLE_TFTP_ILLEGAL;
+    result = CURLE_TFTP_ILLEGAL;
     break;
   }
-  return res;
+
+  return result;
 }
 
 /**********************************************************
@@ -943,7 +945,6 @@ static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
  **********************************************************/
 static CURLcode tftp_connect(struct connectdata *conn, bool *done)
 {
-  CURLcode code;
   tftp_state_data_t *state;
   int blksize, rc;
 
@@ -1017,8 +1018,8 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
   Curl_pgrsStartNow(conn->data);
 
   *done = TRUE;
-  code = CURLE_OK;
-  return(code);
+
+  return CURLE_OK;
 }
 
 /**********************************************************
@@ -1031,7 +1032,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
 static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
                           bool premature)
 {
-  CURLcode code = CURLE_OK;
+  CURLcode result = CURLE_OK;
   tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
 
   (void)status; /* unused */
@@ -1042,9 +1043,9 @@ static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
 
   /* If we have encountered an error */
   if(state)
-    code = tftp_translate_code(state->error);
+    result = tftp_translate_code(state->error);
 
-  return code;
+  return result;
 }
 
 /**********************************************************
@@ -1208,8 +1209,8 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
   }
   else if(event != TFTP_EVENT_NONE) {
     result = tftp_state_machine(state, event);
-    if(result != CURLE_OK)
-      return(result);
+    if(result)
+      return result;
     *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
     if(*done)
       /* Tell curl we're done */
@@ -1227,11 +1228,11 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
     }
     else if(rc != 0) {
       result = tftp_receive_packet(conn);
-      if(result != CURLE_OK)
-        return(result);
+      if(result)
+        return result;
       result = tftp_state_machine(state, state->event);
-      if(result != CURLE_OK)
-        return(result);
+      if(result)
+        return result;
       *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
       if(*done)
         /* Tell curl we're done */
@@ -1286,8 +1287,8 @@ static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
 
   result = tftp_state_machine(state, TFTP_EVENT_INIT);
 
-  if(state->state == TFTP_STATE_FIN || result != CURLE_OK)
-    return(result);
+  if((state->state == TFTP_STATE_FIN) || result)
+    return result;
 
   tftp_multi_statemach(conn, dophase_done);
 
@@ -1310,30 +1311,30 @@ static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
 
 static CURLcode tftp_do(struct connectdata *conn, bool *done)
 {
-  tftp_state_data_t     *state;
-  CURLcode              code;
+  tftp_state_data_t *state;
+  CURLcode result;
 
   *done = FALSE;
 
   if(!conn->proto.tftpc) {
-    code = tftp_connect(conn, done);
-    if(code)
-      return code;
+    result = tftp_connect(conn, done);
+    if(result)
+      return result;
   }
 
   state = (tftp_state_data_t *)conn->proto.tftpc;
   if(!state)
     return CURLE_BAD_CALLING_ORDER;
 
-  code = tftp_perform(conn, done);
+  result = tftp_perform(conn, done);
 
   /* If tftp_perform() returned an error, use that for return code. If it
      was OK, see if tftp_translate_code() has an error. */
-  if(code == CURLE_OK)
+  if(!result)
     /* If we have encountered an internal tftp error, translate it. */
-    code = tftp_translate_code(state->error);
+    result = tftp_translate_code(state->error);
 
-  return code;
+  return result;
 }
 
 static CURLcode tftp_setup_connection(struct connectdata * conn)
diff --git a/Utilities/cmcurl/lib/timeval.c b/Utilities/cmcurl/lib/timeval.c
index 2fd7201..45731ac 100644
--- a/Utilities/cmcurl/lib/timeval.c
+++ b/Utilities/cmcurl/lib/timeval.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,9 +32,17 @@ struct timeval curlx_tvnow(void)
   ** increases monotonically and wraps once 49.7 days have elapsed.
   */
   struct timeval now;
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+    (_WIN32_WINNT < _WIN32_WINNT_VISTA)
   DWORD milliseconds = GetTickCount();
   now.tv_sec = milliseconds / 1000;
   now.tv_usec = (milliseconds % 1000) * 1000;
+#else
+  ULONGLONG milliseconds = GetTickCount64();
+  now.tv_sec = (long) (milliseconds / 1000);
+  now.tv_usec = (long) (milliseconds % 1000) * 1000;
+#endif
+
   return now;
 }
 
@@ -110,7 +118,7 @@ struct timeval curlx_tvnow(void)
 long curlx_tvdiff(struct timeval newer, struct timeval older)
 {
   return (newer.tv_sec-older.tv_sec)*1000+
-    (newer.tv_usec-older.tv_usec)/1000;
+    (long)(newer.tv_usec-older.tv_usec)/1000;
 }
 
 /*
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c
index dc817a6..718139b 100644
--- a/Utilities/cmcurl/lib/transfer.c
+++ b/Utilities/cmcurl/lib/transfer.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -75,16 +75,14 @@
 #include "curl_ntlm.h"
 #include "http_negotiate.h"
 #include "share.h"
-#include "curl_memory.h"
 #include "select.h"
 #include "multiif.h"
 #include "connect.h"
 #include "non-ascii.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /*
@@ -117,8 +115,8 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
 
   /* this function returns a size_t, so we typecast to int to prevent warnings
      with picky compilers */
-  nread = (int)conn->fread_func(data->req.upload_fromhere, 1,
-                                buffersize, conn->fread_in);
+  nread = (int)data->set.fread_func(data->req.upload_fromhere, 1,
+                                    buffersize, data->set.in);
 
   if(nread == CURL_READFUNC_ABORT) {
     failf(data, "operation aborted by callback");
@@ -203,7 +201,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
            strlen(endofline_network));
 
 #ifdef CURL_DOES_CONVERSIONS
-    CURLcode res;
+    CURLcode result;
     int length;
     if(data->set.prefer_ascii) {
       /* translate the protocol and data */
@@ -213,10 +211,10 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
       /* just translate the protocol portion */
       length = strlen(hexbuffer);
     }
-    res = Curl_convert_to_network(data, data->req.upload_fromhere, length);
+    result = Curl_convert_to_network(data, data->req.upload_fromhere, length);
     /* Curl_convert_to_network calls failf if unsuccessful */
-    if(res)
-      return(res);
+    if(result)
+      return result;
 #endif /* CURL_DOES_CONVERSIONS */
 
     if((nread - hexlen) == 0)
@@ -227,11 +225,11 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
   }
 #ifdef CURL_DOES_CONVERSIONS
   else if((data->set.prefer_ascii) && (!sending_http_headers)) {
-    CURLcode res;
-    res = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
+    CURLcode result;
+    result = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
     /* Curl_convert_to_network calls failf if unsuccessful */
-    if(res != CURLE_OK)
-      return(res);
+    if(result)
+      return result;
   }
 #endif /* CURL_DOES_CONVERSIONS */
 
@@ -319,8 +317,7 @@ static int data_pending(const struct connectdata *conn)
        TRUE. The thing is if we read everything, then http2_recv won't
        be called and we cannot signal the HTTP/2 stream has closed. As
        a workaround, we return nonzero here to call http2_recv. */
-    ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20 &&
-     conn->proto.httpc.closed);
+    ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20);
 #else
     Curl_ssl_data_pending(conn, FIRSTSOCKET);
 #endif
@@ -435,6 +432,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
     else {
       /* read nothing but since we wanted nothing we consider this an OK
          situation to proceed from */
+      DEBUGF(infof(data, "readwrite_data: we're done!\n"));
       nread = 0;
     }
 
@@ -496,7 +494,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
         /* We've stopped dealing with input, get out of the do-while loop */
 
         if(nread > 0) {
-          if(Curl_multi_pipeline_enabled(conn->data->multi)) {
+          if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
             infof(data,
                   "Rewinding stream by : %zd"
                   " bytes on url %s (zero-length body)\n",
@@ -547,6 +545,18 @@ static CURLcode readwrite_data(struct SessionHandle *data,
           if(data->state.resume_from && !k->content_range &&
              (data->set.httpreq==HTTPREQ_GET) &&
              !k->ignorebody) {
+
+            if(k->size == data->state.resume_from) {
+              /* The resume point is at the end of file, consider this fine
+                 even if it doesn't allow resume from here. */
+              infof(data, "The entire document is already downloaded");
+              connclose(conn, "already downloaded");
+              /* Abort download */
+              k->keepon &= ~KEEP_RECV;
+              *done = TRUE;
+              return CURLE_OK;
+            }
+
             /* we wanted to resume a download, although the server doesn't
              * seem to support this and we did this with a GET (if it
              * wasn't a GET we did a POST or PUT resume) */
@@ -629,7 +639,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
           if(dataleft != 0) {
             infof(conn->data, "Leftovers after chunking: %zu bytes\n",
                   dataleft);
-            if(Curl_multi_pipeline_enabled(conn->data->multi)) {
+            if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
               /* only attempt the rewind if we truly are pipelining */
               infof(conn->data, "Rewinding %zu bytes\n",dataleft);
               read_rewind(conn, dataleft);
@@ -652,7 +662,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
 
         excess = (size_t)(k->bytecount + nread - k->maxdownload);
         if(excess > 0 && !k->ignorebody) {
-          if(Curl_multi_pipeline_enabled(conn->data->multi)) {
+          if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
             /* The 'excess' amount below can't be more than BUFSIZE which
                always will fit in a size_t */
             infof(data,
@@ -746,7 +756,6 @@ static CURLcode readwrite_data(struct SessionHandle *data,
               result = Curl_unencode_gzip_write(conn, k, nread);
             break;
 
-          case COMPRESS:
           default:
             failf (data, "Unrecognized content encoding type. "
                    "libcurl understands `identity', `deflate' and `gzip' "
@@ -818,13 +827,6 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
 
   *didwhat |= KEEP_SEND;
 
-  /*
-   * We loop here to do the READ and SEND loop until we run out of
-   * data to send or until we get EWOULDBLOCK back
-   *
-   * FIXME: above comment is misleading. Currently no looping is
-   * actually done in do-while loop below.
-   */
   do {
 
     /* only read more data if there's no upload data already
@@ -891,15 +893,6 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
       /* store number of bytes available for upload */
       data->req.upload_present = nread;
 
-#ifndef CURL_DISABLE_SMTP
-      if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
-        result = Curl_smtp_escape_eob(conn, nread);
-        if(result)
-          return result;
-      }
-      else
-#endif /* CURL_DISABLE_SMTP */
-
       /* convert LF to CRLF if so asked */
       if((!sending_http_headers) && (
 #ifdef CURL_DO_LINEEND_CONV
@@ -907,12 +900,16 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
          (data->set.prefer_ascii) ||
 #endif
          (data->set.crlf))) {
-        if(data->state.scratch == NULL)
-          data->state.scratch = malloc(2*BUFSIZE);
-        if(data->state.scratch == NULL) {
-          failf (data, "Failed to alloc scratch buffer!");
-          return CURLE_OUT_OF_MEMORY;
+        /* Do we need to allocate a scratch buffer? */
+        if(!data->state.scratch) {
+          data->state.scratch = malloc(2 * BUFSIZE);
+          if(!data->state.scratch) {
+            failf(data, "Failed to alloc scratch buffer!");
+
+            return CURLE_OUT_OF_MEMORY;
+          }
         }
+
         /*
          * ASCII/EBCDIC Note: This is presumably a text (not binary)
          * transfer so the data should already be in ASCII.
@@ -932,6 +929,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
           else
             data->state.scratch[si] = data->req.upload_fromhere[i];
         }
+
         if(si != nread) {
           /* only perform the special operation if we really did replace
              anything */
@@ -944,6 +942,14 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
           data->req.upload_present = nread;
         }
       }
+
+#ifndef CURL_DISABLE_SMTP
+      if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
+        result = Curl_smtp_escape_eob(conn, nread);
+        if(result)
+          return result;
+      }
+#endif /* CURL_DISABLE_SMTP */
     } /* if 0 == data->req.upload_present */
     else {
       /* We have a partial buffer left from a previous "round". Use
@@ -1006,9 +1012,9 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
  * be read and written to/from the connection.
  */
 CURLcode Curl_readwrite(struct connectdata *conn,
+                        struct SessionHandle *data,
                         bool *done)
 {
-  struct SessionHandle *data = conn->data;
   struct SingleRequest *k = &data->req;
   CURLcode result;
   int didwhat=0;
@@ -1032,6 +1038,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
   else
     fd_write = CURL_SOCKET_BAD;
 
+  if(conn->data->state.drain) {
+    select_res |= CURL_CSELECT_IN;
+    DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n"));
+  }
+
   if(!select_res) /* Call for select()/poll() only, if read/write/error
                      status is not known. */
     select_res = Curl_socket_ready(fd_read, fd_write, 0);
@@ -1202,10 +1213,10 @@ int Curl_single_getsock(const struct connectdata *conn,
   if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) {
 
     if((conn->sockfd != conn->writesockfd) ||
-       !(data->req.keepon & KEEP_RECV)) {
-      /* only if they are not the same socket or we didn't have a readable
+       bitmap == GETSOCK_BLANK) {
+      /* only if they are not the same socket and we have a readable
          one, we increase index */
-      if(data->req.keepon & KEEP_RECV)
+      if(bitmap != GETSOCK_BLANK)
         sockindex++; /* increase index if we need two entries */
 
       DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD);
@@ -1256,7 +1267,7 @@ long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
    * the next packet at the adjusted rate.  We should wait
    * longer when using larger packets, for instance.
    */
-  rv = ((curl_off_t)((pkt_size * 8) * 1000) / rate_bps);
+  rv = ((curl_off_t)(pkt_size * 1000) / rate_bps);
 
   /* Catch rounding errors and always slow down at least 1ms if
    * we are running too fast.
@@ -1278,7 +1289,7 @@ long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
  */
 CURLcode Curl_pretransfer(struct SessionHandle *data)
 {
-  CURLcode res;
+  CURLcode result;
   if(!data->change.url) {
     /* we can't do anything without URL */
     failf(data, "No URL set!");
@@ -1288,32 +1299,35 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
   /* Init the SSL session ID cache here. We do it here since we want to do it
      after the *_setopt() calls (that could specify the size of the cache) but
      before any transfer takes place. */
-  res = Curl_ssl_initsessions(data, data->set.ssl.max_ssl_sessions);
-  if(res)
-    return res;
+  result = Curl_ssl_initsessions(data, data->set.ssl.max_ssl_sessions);
+  if(result)
+    return result;
 
   data->set.followlocation=0; /* reset the location-follow counter */
   data->state.this_is_a_follow = FALSE; /* reset this */
   data->state.errorbuf = FALSE; /* no error has occurred */
   data->state.httpversion = 0; /* don't assume any particular server version */
 
-  data->state.ssl_connect_retry = FALSE;
-
   data->state.authproblem = FALSE;
   data->state.authhost.want = data->set.httpauth;
   data->state.authproxy.want = data->set.proxyauth;
   Curl_safefree(data->info.wouldredirect);
   data->info.wouldredirect = NULL;
 
+  if(data->set.httpreq == HTTPREQ_PUT)
+    data->state.infilesize = data->set.filesize;
+  else
+    data->state.infilesize = data->set.postfieldsize;
+
   /* If there is a list of cookie files to read, do it now! */
   if(data->change.cookielist)
     Curl_cookie_loadfiles(data);
 
   /* If there is a list of host pairs to deal with */
   if(data->change.resolve)
-    res = Curl_loadhostpairs(data);
+    result = Curl_loadhostpairs(data);
 
-  if(!res) {
+  if(!result) {
     /* Allow data->set.use_port to set which port to use. This needs to be
      * disabled for example when we follow Location: headers to URLs using
      * different ports! */
@@ -1328,6 +1342,7 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
 #endif
 
     Curl_initinfo(data); /* reset session-specific information "variables" */
+    Curl_pgrsResetTimesSizes(data);
     Curl_pgrsStartNow(data);
 
     if(data->set.timeout)
@@ -1343,7 +1358,7 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
     data->state.authproxy.picked &= data->state.authproxy.want;
   }
 
-  return res;
+  return result;
 }
 
 /*
@@ -1619,7 +1634,7 @@ CURLcode Curl_follow(struct SessionHandle *data,
   if(type == FOLLOW_REDIR) {
     if((data->set.maxredirs != -1) &&
         (data->set.followlocation >= data->set.maxredirs)) {
-      failf(data,"Maximum (%ld) redirects followed", data->set.maxredirs);
+      failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
       return CURLE_TOO_MANY_REDIRECTS;
     }
 
@@ -1828,13 +1843,13 @@ Curl_reconnect_request(struct connectdata **connp)
    * (again). Slight Lack of feedback in the report, but I don't think this
    * extra check can do much harm.
    */
-  if((CURLE_OK == result) || (CURLE_SEND_ERROR == result)) {
+  if(!result || (CURLE_SEND_ERROR == result)) {
     bool async;
     bool protocol_done = TRUE;
 
     /* Now, redo the connect and get a new connection */
     result = Curl_connect(data, connp, &async, &protocol_done);
-    if(CURLE_OK == result) {
+    if(!result) {
       /* We have connected or sent away a name resolve query fine */
 
       conn = *connp; /* setup conn to again point to something nice */
@@ -1872,12 +1887,10 @@ CURLcode Curl_retry_request(struct connectdata *conn,
      !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
     return CURLE_OK;
 
-  if(/* workaround for broken TLS servers */ data->state.ssl_connect_retry ||
-      ((data->req.bytecount +
-        data->req.headerbytecount == 0) &&
-        conn->bits.reuse &&
-        !data->set.opt_no_body &&
-       data->set.rtspreq != RTSPREQ_RECEIVE)) {
+  if((data->req.bytecount + data->req.headerbytecount == 0) &&
+      conn->bits.reuse &&
+      !data->set.opt_no_body &&
+      (data->set.rtspreq != RTSPREQ_RECEIVE)) {
     /* We got no data, we attempted to re-use a connection and yet we want a
        "body". This might happen if the connection was left alive when we were
        done using it before, but that was closed when we wanted to read from
diff --git a/Utilities/cmcurl/lib/transfer.h b/Utilities/cmcurl/lib/transfer.h
index ad4a3ac..316aeae 100644
--- a/Utilities/cmcurl/lib/transfer.h
+++ b/Utilities/cmcurl/lib/transfer.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -40,7 +40,8 @@ CURLcode Curl_follow(struct SessionHandle *data, char *newurl,
                      followtype type);
 
 
-CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
+CURLcode Curl_readwrite(struct connectdata *conn,
+                        struct SessionHandle *data, bool *done);
 int Curl_single_getsock(const struct connectdata *conn,
                         curl_socket_t *socks,
                         int numsocks);
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
index 67126ab..406c1f0 100644
--- a/Utilities/cmcurl/lib/url.c
+++ b/Utilities/cmcurl/lib/url.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -47,6 +47,10 @@
 #include <inet.h>
 #endif
 
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
 #ifndef HAVE_SOCKET
 #error "We can't compile without socket() support!"
 #endif
@@ -120,15 +124,12 @@ int curl_win32_idn_to_ascii(const char *in, char **out);
 #include "curl_rtmp.h"
 #include "gopher.h"
 #include "http_proxy.h"
-#include "bundles.h"
 #include "conncache.h"
 #include "multihandle.h"
 #include "pipeline.h"
 #include "dotdot.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "strdup.h"
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -141,7 +142,6 @@ find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
                                       struct connectbundle *bundle);
 static void conn_free(struct connectdata *conn);
 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
-static CURLcode do_init(struct connectdata *conn);
 static CURLcode parse_url_login(struct SessionHandle *data,
                                 struct connectdata *conn,
                                 char **userptr, char **passwdptr,
@@ -215,6 +215,15 @@ static const struct Curl_handler * const protocols[] = {
 #endif
 #endif
 
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+   (CURL_SIZEOF_CURL_OFF_T > 4) && \
+   (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+  &Curl_handler_smb,
+#ifdef USE_SSL
+  &Curl_handler_smbs,
+#endif
+#endif
+
 #ifndef CURL_DISABLE_SMTP
   &Curl_handler_smtp,
 #ifdef USE_SSL
@@ -270,8 +279,9 @@ void Curl_freeset(struct SessionHandle *data)
 {
   /* Free all dynamic strings stored in the data->set substructure. */
   enum dupstring i;
-  for(i=(enum dupstring)0; i < STRING_LAST; i++)
+  for(i=(enum dupstring)0; i < STRING_LAST; i++) {
     Curl_safefree(data->set.str[i]);
+  }
 
   if(data->change.referer_alloc) {
     Curl_safefree(data->change.referer);
@@ -345,7 +355,7 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
 
 CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
 {
-  CURLcode r = CURLE_OK;
+  CURLcode result = CURLE_OK;
   enum dupstring i;
 
   /* Copy src->set into dst->set first, then deal with the strings
@@ -356,14 +366,25 @@ CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
   memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
 
   /* duplicate all strings */
-  for(i=(enum dupstring)0; i< STRING_LAST; i++) {
-    r = setstropt(&dst->set.str[i], src->set.str[i]);
-    if(r != CURLE_OK)
-      break;
+  for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
+    result = setstropt(&dst->set.str[i], src->set.str[i]);
+    if(result)
+      return result;
+  }
+
+  /* duplicate memory areas pointed to */
+  i = STRING_COPYPOSTFIELDS;
+  if(src->set.postfieldsize && src->set.str[i]) {
+    /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
+    dst->set.str[i] = Curl_memdup(src->set.str[i],
+                                  curlx_sotouz(src->set.postfieldsize));
+    if(!dst->set.str[i])
+      return CURLE_OUT_OF_MEMORY;
+    /* point to the new copy */
+    dst->set.postfields = dst->set.str[i];
   }
 
-  /* If a failure occurred, freeing has to be performed externally. */
-  return r;
+  return CURLE_OK;
 }
 
 /*
@@ -425,10 +446,8 @@ CURLcode Curl_close(struct SessionHandle *data)
   Curl_ssl_free_certinfo(data);
 
   /* Cleanup possible redirect junk */
-  if(data->req.newurl) {
-    free(data->req.newurl);
-    data->req.newurl = NULL;
-  }
+  free(data->req.newurl);
+  data->req.newurl = NULL;
 
   if(data->change.referer_alloc) {
     Curl_safefree(data->change.referer);
@@ -474,7 +493,7 @@ CURLcode Curl_close(struct SessionHandle *data)
  */
 CURLcode Curl_init_userdefined(struct UserDefined *set)
 {
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   set->out = stdout; /* default output to stdout */
   set->in  = stdin;  /* default input from stdin */
@@ -540,8 +559,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
      define since we internally only use the lower 16 bits for the passed
      in bitmask to not conflict with the private bits */
   set->allowed_protocols = CURLPROTO_ALL;
-  set->redir_protocols =
-    CURLPROTO_ALL & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
+  set->redir_protocols = CURLPROTO_ALL &  /* All except FILE, SCP and SMB */
+                          ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
+                            CURLPROTO_SMBS);
 
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
   /*
@@ -550,17 +570,34 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
    */
   set->socks5_gssapi_nec = FALSE;
   /* set default GSS-API service name */
-  res = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
-                  (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
-  if(res != CURLE_OK)
-    return res;
+  result = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
+                     (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
+  if(result)
+    return result;
+
+  /* set default negotiate proxy service name */
+  result = setstropt(&set->str[STRING_PROXY_SERVICE_NAME],
+                     (char *) CURL_DEFAULT_PROXY_SERVICE_NAME);
+  if(result)
+    return result;
+
+  /* set default negotiate service name */
+  result = setstropt(&set->str[STRING_SERVICE_NAME],
+                     (char *) CURL_DEFAULT_SERVICE_NAME);
+  if(result)
+    return result;
 #endif
 
   /* This is our preferred CA cert bundle/path since install time */
 #if defined(CURL_CA_BUNDLE)
-  res = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
-#elif defined(CURL_CA_PATH)
-  res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
+  result = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
+  if(result)
+    return result;
+#endif
+#if defined(CURL_CA_PATH)
+  result = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
+  if(result)
+    return result;
 #endif
 
   set->wildcardmatch  = FALSE;
@@ -578,7 +615,8 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
   set->ssl_enable_alpn = TRUE;
 
   set->expect_100_timeout = 1000L; /* Wait for a second by default. */
-  return res;
+  set->sep_headers = TRUE; /* separated header lists by default */
+  return result;
 }
 
 /**
@@ -591,9 +629,8 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
 
 CURLcode Curl_open(struct SessionHandle **curl)
 {
-  CURLcode res = CURLE_OK;
+  CURLcode result;
   struct SessionHandle *data;
-  CURLcode status;
 
   /* Very simple start-up: alloc the struct, init it with zeroes and return */
   data = calloc(1, sizeof(struct SessionHandle));
@@ -605,11 +642,11 @@ CURLcode Curl_open(struct SessionHandle **curl)
 
   data->magic = CURLEASY_MAGIC_NUMBER;
 
-  status = Curl_resolver_init(&data->state.resolver);
-  if(status) {
+  result = Curl_resolver_init(&data->state.resolver);
+  if(result) {
     DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
     free(data);
-    return status;
+    return result;
   }
 
   /* We do some initial setup here, all those fields that can't be just 0 */
@@ -617,10 +654,10 @@ CURLcode Curl_open(struct SessionHandle **curl)
   data->state.headerbuff = malloc(HEADERSIZE);
   if(!data->state.headerbuff) {
     DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
-    res = CURLE_OUT_OF_MEMORY;
+    result = CURLE_OUT_OF_MEMORY;
   }
   else {
-    res = Curl_init_userdefined(&data->set);
+    result = Curl_init_userdefined(&data->set);
 
     data->state.headersize=HEADERSIZE;
 
@@ -638,10 +675,9 @@ CURLcode Curl_open(struct SessionHandle **curl)
     data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
   }
 
-  if(res) {
+  if(result) {
     Curl_resolver_cleanup(data->state.resolver);
-    if(data->state.headerbuff)
-      free(data->state.headerbuff);
+    free(data->state.headerbuff);
     Curl_freeset(data);
     free(data);
     data = NULL;
@@ -649,7 +685,7 @@ CURLcode Curl_open(struct SessionHandle **curl)
   else
     *curl = data;
 
-  return res;
+  return result;
 }
 
 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
@@ -744,7 +780,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
     break;
   case CURLOPT_FAILONERROR:
     /*
-     * Don't output the >=300 error code HTML-page, but instead only
+     * Don't output the >=400 error code HTML-page, but instead only
      * return error.
      */
     data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE;
@@ -867,7 +903,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
      * Set explicit SSL version to try to connect with, as some SSL
      * implementations are lame.
      */
+#ifdef USE_SSL
     data->set.ssl.version = va_arg(param, long);
+#else
+    result = CURLE_UNKNOWN_OPTION;
+#endif
     break;
 
 #ifndef CURL_DISABLE_HTTP
@@ -1139,6 +1179,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
     /*
      * Set cookie file name to dump all cookies to when we're done.
      */
+  {
+    struct CookieInfo *newcookies;
     result = setstropt(&data->set.str[STRING_COOKIEJAR],
                        va_arg(param, char *));
 
@@ -1146,8 +1188,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
      * Activate the cookie parser. This may or may not already
      * have been made.
      */
-    data->cookies = Curl_cookie_init(data, NULL, data->cookies,
-                                     data->set.cookiesession);
+    newcookies = Curl_cookie_init(data, NULL, data->cookies,
+                                  data->set.cookiesession);
+    if(!newcookies)
+      result = CURLE_OUT_OF_MEMORY;
+    data->cookies = newcookies;
+  }
     break;
 
   case CURLOPT_COOKIESESSION:
@@ -1191,14 +1237,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
       /* flush cookies to file, takes care of the locking */
       Curl_flush_cookies(data, 0);
     }
+    else if(Curl_raw_equal(argptr, "RELOAD")) {
+      /* reload cookies from file */
+      Curl_cookie_loadfiles(data);
+      break;
+    }
     else {
       if(!data->cookies)
         /* if cookie engine was not running, activate it */
         data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
 
       argptr = strdup(argptr);
-      if(!argptr) {
+      if(!argptr || !data->cookies) {
         result = CURLE_OUT_OF_MEMORY;
+        free(argptr);
       }
       else {
         Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
@@ -1431,12 +1483,29 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
                        va_arg(param, char *));
     break;
 
+  case CURLOPT_PROXY_SERVICE_NAME:
+    /*
+     * Set negotiate proxy service name
+     */
+    result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
+                       va_arg(param, char *));
+    break;
+
   case CURLOPT_SOCKS5_GSSAPI_NEC:
     /*
      * set flag for nec socks5 support
      */
     data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE;
     break;
+
+  case CURLOPT_SERVICE_NAME:
+    /*
+     * Set negotiate service identity
+     */
+    result = setstropt(&data->set.str[STRING_SERVICE_NAME],
+                       va_arg(param, char *));
+    break;
+
 #endif
 
   case CURLOPT_HEADERDATA:
@@ -1959,30 +2028,63 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
 
     data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE;
     break;
-#ifdef USE_SSLEAY
-    /* since these two options are only possible to use on an OpenSSL-
-       powered libcurl we #ifdef them on this condition so that libcurls
-       built against other SSL libs will return a proper error when trying
-       to set this option! */
+  case CURLOPT_SSL_VERIFYSTATUS:
+    /*
+     * Enable certificate status verifying.
+     */
+    if(!Curl_ssl_cert_status_request()) {
+      result = CURLE_NOT_BUILT_IN;
+      break;
+    }
+
+    data->set.ssl.verifystatus = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
   case CURLOPT_SSL_CTX_FUNCTION:
+#ifdef have_curlssl_ssl_ctx
     /*
      * Set a SSL_CTX callback
      */
     data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
+#else
+    result = CURLE_NOT_BUILT_IN;
+#endif
     break;
   case CURLOPT_SSL_CTX_DATA:
+#ifdef have_curlssl_ssl_ctx
     /*
      * Set a SSL_CTX callback parameter pointer
      */
     data->set.ssl.fsslctxp = va_arg(param, void *);
-    break;
+#else
+    result = CURLE_NOT_BUILT_IN;
 #endif
-#if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT) || \
-    defined(USE_NSS)
+    break;
+  case CURLOPT_SSL_FALSESTART:
+    /*
+     * Enable TLS false start.
+     */
+    if(!Curl_ssl_false_start()) {
+      result = CURLE_NOT_BUILT_IN;
+      break;
+    }
+
+    data->set.ssl.falsestart = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
   case CURLOPT_CERTINFO:
+#ifdef have_curlssl_certinfo
     data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
-    break;
+#else
+    result = CURLE_NOT_BUILT_IN;
 #endif
+    break;
+  case CURLOPT_PINNEDPUBLICKEY:
+    /*
+     * Set pinned public key for SSL connection.
+     * Specify file name of the public key in DER format.
+     */
+    result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+                       va_arg(param, char *));
+    break;
   case CURLOPT_CAINFO:
     /*
      * Set CA info for SSL connection. Specify file name of the CA certificate
@@ -1991,6 +2093,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
                        va_arg(param, char *));
     break;
   case CURLOPT_CAPATH:
+#ifdef have_curlssl_ca_path /* not supported by all backends */
     /*
      * Set CA path info for SSL connection. Specify directory name of the CA
      * certificates which have been prepared using openssl c_rehash utility.
@@ -1998,6 +2101,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
     /* This does not work on windows. */
     result = setstropt(&data->set.str[STRING_SSL_CAPATH],
                        va_arg(param, char *));
+#else
+    result = CURLE_NOT_BUILT_IN;
+#endif
     break;
   case CURLOPT_CRLFILE:
     /*
@@ -2079,16 +2185,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
 
       data->share->dirty++;
 
-      if(data->share->hostcache) {
+      if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
         /* use shared host cache */
-        data->dns.hostcache = data->share->hostcache;
+        data->dns.hostcache = &data->share->hostcache;
         data->dns.hostcachetype = HCACHE_SHARED;
       }
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
       if(data->share->cookies) {
         /* use shared cookie list, first free own one if any */
-        if(data->cookies)
-          Curl_cookie_cleanup(data->cookies);
+        Curl_cookie_cleanup(data->cookies);
         /* enable cookies since we now use a share that uses cookies! */
         data->cookies = data->share->cookies;
       }
@@ -2129,7 +2234,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
 
   case CURLOPT_SSL_OPTIONS:
     arg = va_arg(param, long);
-    data->set.ssl_enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
+    data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
+    data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
     break;
 
 #endif
@@ -2316,7 +2422,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
      * know that an unsigned int will always hold the value so we blindly
      * typecast to this type
      */
-    data->set.scope = curlx_sltoui(va_arg(param, long));
+    data->set.scope_id = curlx_sltoui(va_arg(param, long));
     break;
 
   case CURLOPT_PROTOCOLS:
@@ -2533,6 +2639,19 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
     data->set.ssl_enable_alpn = (0 != va_arg(param, long))?TRUE:FALSE;
     break;
 
+#ifdef USE_UNIX_SOCKETS
+  case CURLOPT_UNIX_SOCKET_PATH:
+    result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
+                       va_arg(param, char *));
+    break;
+#endif
+
+  case CURLOPT_PATH_AS_IS:
+    data->set.path_as_is = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_PIPEWAIT:
+    data->set.pipewait = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
   default:
     /* unknown tag and its companion, just ignore: */
     result = CURLE_UNKNOWN_OPTION;
@@ -2565,7 +2684,8 @@ static void conn_free(struct connectdata *conn)
   if(CURL_SOCKET_BAD != conn->tempsock[1])
     Curl_closesocket(conn, conn->tempsock[1]);
 
-#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
   Curl_ntlm_wb_cleanup(conn);
 #endif
 
@@ -2631,8 +2751,10 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
 
   Curl_hostcache_prune(data); /* kill old DNS cache entries */
 
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
   /* Cleanup NTLM connection-related data */
   Curl_http_ntlm_cleanup(conn);
+#endif
 
   if(conn->handler->disconnect)
     /* This is set if protocol-specific cleanups should be made */
@@ -2655,16 +2777,15 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
   free(conn->host.encalloc); /* encoded host name buffer, must be freed with
                                 idn_free() since this was allocated by
                                 curl_win32_idn_to_ascii */
-  if(conn->proxy.encalloc)
-    free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed
-                                   with idn_free() since this was allocated by
-                                   curl_win32_idn_to_ascii */
+  free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed
+                                 with idn_free() since this was allocated by
+                                 curl_win32_idn_to_ascii */
 #endif
 
   Curl_ssl_close(conn, FIRSTSOCKET);
 
   /* Indicate to all handles on the pipe that we're dead */
-  if(Curl_multi_pipeline_enabled(data->multi)) {
+  if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
     signalPipeClose(conn->send_pipe, TRUE);
     signalPipeClose(conn->recv_pipe, TRUE);
   }
@@ -2692,32 +2813,31 @@ static bool SocketIsDead(curl_socket_t sock)
   return ret_val;
 }
 
+/*
+ * IsPipeliningPossible() returns TRUE if the options set would allow
+ * pipelining/multiplexing and the connection is using a HTTP protocol.
+ */
 static bool IsPipeliningPossible(const struct SessionHandle *handle,
                                  const struct connectdata *conn)
 {
-  if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
-     Curl_multi_pipeline_enabled(handle->multi) &&
-     (handle->set.httpreq == HTTPREQ_GET ||
-      handle->set.httpreq == HTTPREQ_HEAD) &&
-     handle->set.httpversion != CURL_HTTP_VERSION_1_0)
-    return TRUE;
+  /* If a HTTP protocol and pipelining is enabled */
+  if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+
+    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
+       (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
+       (handle->set.httpreq == HTTPREQ_GET ||
+        handle->set.httpreq == HTTPREQ_HEAD))
+      /* didn't ask for HTTP/1.0 and a GET or HEAD */
+      return TRUE;
 
+    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
+       (handle->set.httpversion == CURL_HTTP_VERSION_2_0))
+      /* allows HTTP/2 */
+      return TRUE;
+  }
   return FALSE;
 }
 
-bool Curl_isPipeliningEnabled(const struct SessionHandle *handle)
-{
-  return Curl_multi_pipeline_enabled(handle->multi);
-}
-
-CURLcode Curl_addHandleToPipeline(struct SessionHandle *data,
-                                  struct curl_llist *pipeline)
-{
-  if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
-    return CURLE_OUT_OF_MEMORY;
-  return CURLE_OK;
-}
-
 int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
                                   struct curl_llist *pipeline)
 {
@@ -2765,15 +2885,14 @@ void Curl_getoff_all_pipelines(struct SessionHandle *data,
                                struct connectdata *conn)
 {
   bool recv_head = (conn->readchannel_inuse &&
-    (gethandleathead(conn->recv_pipe) == data)) ? TRUE : FALSE;
-
+                    Curl_recvpipe_head(data, conn));
   bool send_head = (conn->writechannel_inuse &&
-    (gethandleathead(conn->send_pipe) == data)) ? TRUE : FALSE;
+                    Curl_sendpipe_head(data, conn));
 
   if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
-    conn->readchannel_inuse = FALSE;
+    Curl_pipeline_leave_read(conn);
   if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
-    conn->writechannel_inuse = FALSE;
+    Curl_pipeline_leave_write(conn);
 }
 
 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
@@ -2825,7 +2944,7 @@ find_oldest_idle_connection(struct SessionHandle *data)
 
   now = Curl_tvnow();
 
-  Curl_hash_start_iterate(bc->hash, &iter);
+  Curl_hash_start_iterate(&bc->hash, &iter);
 
   he = Curl_hash_next_element(&iter);
   while(he) {
@@ -2959,6 +3078,13 @@ static void prune_dead_connections(struct SessionHandle *data)
   }
 }
 
+
+static size_t max_pipeline_length(struct Curl_multi *multi)
+{
+  return multi ? multi->max_pipeline_length : 0;
+}
+
+
 /*
  * Given one filled in connection struct (named needle), this function should
  * detect if there already is one that has all the significant details
@@ -2975,17 +3101,21 @@ static bool
 ConnectionExists(struct SessionHandle *data,
                  struct connectdata *needle,
                  struct connectdata **usethis,
-                 bool *force_reuse)
+                 bool *force_reuse,
+                 bool *waitpipe)
 {
   struct connectdata *check;
   struct connectdata *chosen = 0;
   bool canPipeline = IsPipeliningPossible(data, needle);
+#ifdef USE_NTLM
   bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
                        (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
     (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
+#endif
   struct connectbundle *bundle;
 
   *force_reuse = FALSE;
+  *waitpipe = FALSE;
 
   /* We can't pipe if the site is blacklisted */
   if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
@@ -2994,10 +3124,11 @@ ConnectionExists(struct SessionHandle *data,
 
   /* Look up the bundle with all the connections to this
      particular host */
-  bundle = Curl_conncache_find_bundle(data->state.conn_cache,
-                                      needle->host.name);
+  bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
   if(bundle) {
-    size_t max_pipe_len = Curl_multi_max_pipeline_length(data->multi);
+    /* Max pipe length is zero (unlimited) for multiplexed connections */
+    size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
+      max_pipeline_length(data->multi):0;
     size_t best_pipe_len = max_pipe_len;
     struct curl_llist_element *curr;
 
@@ -3005,15 +3136,25 @@ ConnectionExists(struct SessionHandle *data,
           needle->host.name, (void *)bundle);
 
     /* We can't pipe if we don't know anything about the server */
-    if(canPipeline && !bundle->server_supports_pipelining) {
-      infof(data, "Server doesn't support pipelining\n");
-      canPipeline = FALSE;
+    if(canPipeline) {
+      if(bundle->multiuse <= BUNDLE_UNKNOWN) {
+        if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
+          infof(data, "Server doesn't support multi-use yet, wait\n");
+          *waitpipe = TRUE;
+          return FALSE; /* no re-use */
+        }
+
+        infof(data, "Server doesn't support multi-use (yet)\n");
+        canPipeline = FALSE;
+      }
     }
 
     curr = bundle->conn_list->head;
     while(curr) {
       bool match = FALSE;
+#if defined(USE_NTLM)
       bool credentialsMatch = FALSE;
+#endif
       size_t pipeLen;
 
       /*
@@ -3029,16 +3170,19 @@ ConnectionExists(struct SessionHandle *data,
       pipeLen = check->send_pipe->size + check->recv_pipe->size;
 
       if(canPipeline) {
-        /* Make sure the pipe has only GET requests */
-        struct SessionHandle* sh = gethandleathead(check->send_pipe);
-        struct SessionHandle* rh = gethandleathead(check->recv_pipe);
-        if(sh) {
-          if(!IsPipeliningPossible(sh, check))
-            continue;
-        }
-        else if(rh) {
-          if(!IsPipeliningPossible(rh, check))
-            continue;
+
+        if(!check->bits.multiplex) {
+          /* If not multiplexing, make sure the pipe has only GET requests */
+          struct SessionHandle* sh = gethandleathead(check->send_pipe);
+          struct SessionHandle* rh = gethandleathead(check->recv_pipe);
+          if(sh) {
+            if(!IsPipeliningPossible(sh, check))
+              continue;
+          }
+          else if(rh) {
+            if(!IsPipeliningPossible(rh, check))
+              continue;
+          }
         }
       }
       else {
@@ -3118,8 +3262,11 @@ ConnectionExists(struct SessionHandle *data,
           continue;
       }
 
-      if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) ||
-         wantNTLMhttp) {
+      if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST))
+#ifdef USE_NTLM
+         || (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)
+#endif
+        ) {
         /* This protocol requires credentials per connection or is HTTP+NTLM,
            so verify that we're using the same name and password as well */
         if(!strequal(needle->user, check->user) ||
@@ -3127,7 +3274,9 @@ ConnectionExists(struct SessionHandle *data,
           /* one of them was different */
           continue;
         }
+#if defined(USE_NTLM)
         credentialsMatch = TRUE;
+#endif
       }
 
       if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
@@ -3179,6 +3328,7 @@ ConnectionExists(struct SessionHandle *data,
       }
 
       if(match) {
+#if defined(USE_NTLM)
         /* If we are looking for an HTTP+NTLM connection, check if this is
            already authenticating with the right credentials. If not, keep
            looking so that we can reuse NTLM connections if
@@ -3197,6 +3347,7 @@ ConnectionExists(struct SessionHandle *data,
             chosen = check;
           continue;
         }
+#endif
 
         if(canPipeline) {
           /* We can pipeline if we want to. Let's continue looking for
@@ -3210,19 +3361,42 @@ ConnectionExists(struct SessionHandle *data,
           }
 
           /* We can't use the connection if the pipe is full */
-          if(pipeLen >= max_pipe_len)
+          if(max_pipe_len && (pipeLen >= max_pipe_len)) {
+            infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
             continue;
-
+          }
+#ifdef USE_NGHTTP2
+          /* If multiplexed, make sure we don't go over concurrency limit */
+          if(check->bits.multiplex) {
+            /* Multiplexed connections can only be HTTP/2 for now */
+            struct http_conn *httpc = &check->proto.httpc;
+            if(pipeLen >= httpc->settings.max_concurrent_streams) {
+              infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
+                    pipeLen);
+              continue;
+            }
+          }
+#endif
           /* We can't use the connection if the pipe is penalized */
-          if(Curl_pipeline_penalized(data, check))
+          if(Curl_pipeline_penalized(data, check)) {
+            infof(data, "Penalized, skip\n");
             continue;
+          }
 
-          if(pipeLen < best_pipe_len) {
-            /* This connection has a shorter pipe so far. We'll pick this
-               and continue searching */
+          if(max_pipe_len) {
+            if(pipeLen < best_pipe_len) {
+              /* This connection has a shorter pipe so far. We'll pick this
+                 and continue searching */
+              chosen = check;
+              best_pipe_len = pipeLen;
+              continue;
+            }
+          }
+          else {
+            /* When not pipelining (== multiplexed), we have a match here! */
             chosen = check;
-            best_pipe_len = pipeLen;
-            continue;
+            infof(data, "Multiplexed connection found!\n");
+            break;
           }
         }
         else {
@@ -3274,20 +3448,6 @@ ConnectionDone(struct SessionHandle *data, struct connectdata *conn)
   return (conn_candidate == conn) ? FALSE : TRUE;
 }
 
-/*
- * The given input connection struct pointer is to be stored in the connection
- * cache. If the cache is already full, least interesting existing connection
- * (if any) gets closed.
- *
- * The given connection should be unique. That must've been checked prior to
- * this call.
- */
-static CURLcode ConnectionStore(struct SessionHandle *data,
-                                struct connectdata *conn)
-{
-  return Curl_conncache_add_conn(data->state.conn_cache, conn);
-}
-
 /* after a TCP connection to the proxy has been verified, this function does
    the next magic step.
 
@@ -3533,7 +3693,7 @@ static void fix_hostname(struct SessionHandle *data,
   host->dispname = host->name;
 
   len = strlen(host->name);
-  if(host->name[len-1] == '.')
+  if(len && (host->name[len-1] == '.'))
     /* strip off a single trailing dot if present, primarily for SNI but
        there's no use for it */
     host->name[len-1]=0;
@@ -3550,7 +3710,7 @@ static void fix_hostname(struct SessionHandle *data,
            stringprep_locale_charset ());
     if(rc != IDNA_SUCCESS)
       infof(data, "Failed to convert %s to ACE; %s\n",
-            host->name, Curl_idn_strerror(conn,rc));
+            host->name, Curl_idn_strerror(conn, rc));
     else {
       /* tld_check_name() displays a warning if the host name contains
          "illegal" characters for this TLD */
@@ -3655,16 +3815,17 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
 
   conn->ip_version = data->set.ipver;
 
-#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
   conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
   conn->ntlm_auth_hlpr_pid = 0;
   conn->challenge_header = NULL;
   conn->response_header = NULL;
 #endif
 
-  if(Curl_multi_pipeline_enabled(data->multi) &&
-      !conn->master_buffer) {
-    /* Allocate master_buffer to be used for pipelining */
+  if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
+     !conn->master_buffer) {
+    /* Allocate master_buffer to be used for HTTP/1 pipelining */
     conn->master_buffer = calloc(BUFSIZE, sizeof (char));
     if(!conn->master_buffer)
       goto error;
@@ -3703,9 +3864,9 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
   conn->send_pipe = NULL;
   conn->recv_pipe = NULL;
 
-  Curl_safefree(conn->master_buffer);
-  Curl_safefree(conn->localdev);
-  Curl_safefree(conn);
+  free(conn->master_buffer);
+  free(conn->localdev);
+  free(conn);
   return NULL;
 }
 
@@ -3772,6 +3933,13 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
 
   *prot_missing = FALSE;
 
+  /* We might pass the entire URL into the request so we need to make sure
+   * there are no bad characters in there.*/
+  if(strpbrk(data->change.url, "\r\n")) {
+    failf(data, "Illegal characters found in URL");
+    return CURLE_URL_MALFORMAT;
+  }
+
   /*************************************************************
    * Parse the URL.
    *
@@ -3941,7 +4109,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
     path[0] = '/';
     rebuild_url = TRUE;
   }
-  else {
+  else if(!data->set.path_as_is) {
     /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
     char *newp = Curl_dedotdotify(path);
     if(!newp)
@@ -4003,7 +4171,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
    * the host name
    */
   result = parse_url_login(data, conn, userp, passwdp, optionsp);
-  if(result != CURLE_OK)
+  if(result)
     return result;
 
   if(conn->host.name[0] == '[') {
@@ -4024,7 +4192,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
         /* The address scope was well formed.  Knock it out of the
            hostname. */
         memmove(percent, endp, strlen(endp)+1);
-        conn->scope = (unsigned int)scope;
+        conn->scope_id = (unsigned int)scope;
       }
       else {
         /* Zone identifier is not numeric */
@@ -4046,11 +4214,11 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
           }
         }
         if(scopeidx > 0) {
+          char *p = percent + identifier_offset + strlen(ifname);
+
           /* Remove zone identifier from hostname */
-          memmove(percent,
-                  percent + identifier_offset + strlen(ifname),
-                  identifier_offset + strlen(ifname));
-          conn->scope = scopeidx;
+          memmove(percent, p, strlen(p) + 1);
+          conn->scope_id = scopeidx;
         }
         else
 #endif /* HAVE_NET_IF_H && IFNAMSIZ */
@@ -4059,9 +4227,9 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
     }
   }
 
-  if(data->set.scope)
+  if(data->set.scope_id)
     /* Override any scope that was set above.  */
-    conn->scope = data->set.scope;
+    conn->scope_id = data->set.scope_id;
 
   /* Remove the fragment part of the path. Per RFC 2396, this is always the
      last part of the URI. We are looking for the first '#' so that we deal
@@ -4153,7 +4321,7 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
   if(p->setup_connection) {
     result = (*p->setup_connection)(conn);
 
-    if(result != CURLE_OK)
+    if(result)
       return result;
 
     p = conn->handler;              /* May have changed. */
@@ -4327,9 +4495,8 @@ static char *detect_proxy(struct connectdata *conn)
       prox=curl_getenv(proxy_env);
     }
 
-    if(prox && *prox) { /* don't count "" strings */
+    if(prox)
       proxy = prox; /* use this */
-    }
     else {
       proxy = curl_getenv("all_proxy"); /* default proxy to use */
       if(!proxy)
@@ -4337,8 +4504,7 @@ static char *detect_proxy(struct connectdata *conn)
     }
   } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
        non-proxy */
-  if(no_proxy)
-    free(no_proxy);
+  free(no_proxy);
 
 #else /* !CURL_DISABLE_HTTP */
 
@@ -4352,7 +4518,6 @@ static char *detect_proxy(struct connectdata *conn)
  * If this is supposed to use a proxy, we need to figure out the proxy
  * host name, so that we can re-use an existing connection
  * that may exist registered to the same proxy host.
- * proxy will be freed before this function returns.
  */
 static CURLcode parse_proxy(struct SessionHandle *data,
                             struct connectdata *conn, char *proxy)
@@ -4389,13 +4554,12 @@ static CURLcode parse_proxy(struct SessionHandle *data,
   /* Is there a username and password given in this proxy url? */
   atsign = strchr(proxyptr, '@');
   if(atsign) {
-    CURLcode res = CURLE_OK;
     char *proxyuser = NULL;
     char *proxypasswd = NULL;
-
-    res = parse_login_details(proxyptr, atsign - proxyptr,
-                              &proxyuser, &proxypasswd, NULL);
-    if(!res) {
+    CURLcode result =
+      parse_login_details(proxyptr, atsign - proxyptr,
+                          &proxyuser, &proxypasswd, NULL);
+    if(!result) {
       /* found user and password, rip them out.  note that we are
          unescaping them, as there is otherwise no way to have a
          username or password with reserved characters like ':' in
@@ -4407,7 +4571,7 @@ static CURLcode parse_proxy(struct SessionHandle *data,
         conn->proxyuser = strdup("");
 
       if(!conn->proxyuser)
-        res = CURLE_OUT_OF_MEMORY;
+        result = CURLE_OUT_OF_MEMORY;
       else {
         Curl_safefree(conn->proxypasswd);
         if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
@@ -4416,25 +4580,22 @@ static CURLcode parse_proxy(struct SessionHandle *data,
           conn->proxypasswd = strdup("");
 
         if(!conn->proxypasswd)
-          res = CURLE_OUT_OF_MEMORY;
+          result = CURLE_OUT_OF_MEMORY;
       }
 
-      if(!res) {
+      if(!result) {
         conn->bits.proxy_user_passwd = TRUE; /* enable it */
         atsign++; /* the right side of the @-letter */
 
-        if(atsign)
-          proxyptr = atsign; /* now use this instead */
-        else
-          res = CURLE_OUT_OF_MEMORY;
+        proxyptr = atsign; /* now use this instead */
       }
     }
 
-    Curl_safefree(proxyuser);
-    Curl_safefree(proxypasswd);
+    free(proxyuser);
+    free(proxypasswd);
 
-    if(res)
-      return res;
+    if(result)
+      return result;
   }
 
   /* start scanning for port number at this point */
@@ -4595,7 +4756,7 @@ static CURLcode parse_url_login(struct SessionHandle *data,
   /* We could use the login information in the URL so extract it */
   result = parse_login_details(login, ptr - login - 1,
                                &userp, &passwdp, &optionsp);
-  if(result != CURLE_OK)
+  if(result)
     goto out;
 
   if(userp) {
@@ -4643,9 +4804,9 @@ static CURLcode parse_url_login(struct SessionHandle *data,
 
   out:
 
-  Curl_safefree(userp);
-  Curl_safefree(passwdp);
-  Curl_safefree(optionsp);
+  free(userp);
+  free(passwdp);
+  free(optionsp);
 
   return result;
 }
@@ -4733,7 +4894,7 @@ static CURLcode parse_login_details(const char *login, const size_t len,
   if(!result && passwdp && plen) {
     pbuf = malloc(plen + 1);
     if(!pbuf) {
-      Curl_safefree(ubuf);
+      free(ubuf);
       result = CURLE_OUT_OF_MEMORY;
     }
   }
@@ -4742,8 +4903,8 @@ static CURLcode parse_login_details(const char *login, const size_t len,
   if(!result && optionsp && olen) {
     obuf = malloc(olen + 1);
     if(!obuf) {
-      Curl_safefree(pbuf);
-      Curl_safefree(ubuf);
+      free(pbuf);
+      free(ubuf);
       result = CURLE_OUT_OF_MEMORY;
     }
   }
@@ -5022,6 +5183,32 @@ static CURLcode resolve_server(struct SessionHandle *data,
     /* set a pointer to the hostname we display */
     fix_hostname(data, conn, &conn->host);
 
+#ifdef USE_UNIX_SOCKETS
+    if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
+      /* Unix domain sockets are local. The host gets ignored, just use the
+       * specified domain socket address. Do not cache "DNS entries". There is
+       * no DNS involved and we already have the filesystem path available */
+      const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
+
+      hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
+      if(!hostaddr)
+        result = CURLE_OUT_OF_MEMORY;
+      else if((hostaddr->addr = Curl_unix2addr(path)) != NULL)
+        hostaddr->inuse++;
+      else {
+        /* Long paths are not supported for now */
+        if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
+          failf(data, "Unix socket path too long: '%s'", path);
+          result = CURLE_COULDNT_RESOLVE_HOST;
+        }
+        else
+          result = CURLE_OUT_OF_MEMORY;
+        free(hostaddr);
+        hostaddr = NULL;
+      }
+    }
+    else
+#endif
     if(!conn->proxy.name || !*conn->proxy.name) {
       /* If not connecting via a proxy, extract the port from the URL, if it is
        * there, thus overriding any defaults that might have been set above. */
@@ -5079,8 +5266,7 @@ static CURLcode resolve_server(struct SessionHandle *data,
 static void reuse_conn(struct connectdata *old_conn,
                        struct connectdata *conn)
 {
-  if(old_conn->proxy.rawalloc)
-    free(old_conn->proxy.rawalloc);
+  free(old_conn->proxy.rawalloc);
 
   /* free the SSL config struct from this connection struct as this was
      allocated in vain and is targeted for destruction */
@@ -5168,8 +5354,9 @@ static CURLcode create_conn(struct SessionHandle *data,
   bool reuse;
   char *proxy = NULL;
   bool prot_missing = FALSE;
-  bool no_connections_available = FALSE;
+  bool connections_available = TRUE;
   bool force_reuse = FALSE;
+  bool waitpipe = FALSE;
   size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
   size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
 
@@ -5250,7 +5437,7 @@ static CURLcode create_conn(struct SessionHandle *data,
 
   result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
                                &options);
-  if(result != CURLE_OK)
+  if(result)
     goto out;
 
   /*************************************************************
@@ -5310,7 +5497,7 @@ static CURLcode create_conn(struct SessionHandle *data,
    *************************************************************/
   if(conn->bits.proxy_user_passwd) {
     result = parse_proxy_auth(data, conn);
-    if(result != CURLE_OK)
+    if(result)
       goto out;
   }
 
@@ -5329,14 +5516,19 @@ static CURLcode create_conn(struct SessionHandle *data,
 
   if(data->set.str[STRING_NOPROXY] &&
      check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
-    if(proxy) {
-      free(proxy);  /* proxy is in exception list */
-      proxy = NULL;
-    }
+    free(proxy);  /* proxy is in exception list */
+    proxy = NULL;
   }
   else if(!proxy)
     proxy = detect_proxy(conn);
 
+#ifdef USE_UNIX_SOCKETS
+  if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
+    free(proxy);  /* Unix domain sockets cannot be proxied, so disable it */
+    proxy = NULL;
+  }
+#endif
+
   if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
     free(proxy);  /* Don't bother with an empty proxy string or if the
                      protocol doesn't work with network */
@@ -5351,7 +5543,8 @@ static CURLcode create_conn(struct SessionHandle *data,
   if(proxy) {
     result = parse_proxy(data, conn, proxy);
 
-    Curl_safefree(proxy); /* parse_proxy copies the proxy string */
+    free(proxy); /* parse_proxy copies the proxy string */
+    proxy = NULL;
 
     if(result)
       goto out;
@@ -5372,8 +5565,10 @@ static CURLcode create_conn(struct SessionHandle *data,
       conn->bits.httpproxy = TRUE;
 #endif
     }
-    else
+    else {
       conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
+      conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
+    }
     conn->bits.proxy = TRUE;
   }
   else {
@@ -5397,16 +5592,16 @@ static CURLcode create_conn(struct SessionHandle *data,
    * Figure out the remote port number and fix it in the URL
    *************************************************************/
   result = parse_remote_port(data, conn);
-  if(result != CURLE_OK)
+  if(result)
     goto out;
 
   /* Check for overridden login details and set them accordingly so they
      they are known when protocol->setup_connection is called! */
   result = override_login(data, conn, &user, &passwd, &options);
-  if(result != CURLE_OK)
+  if(result)
     goto out;
   result = set_login(conn, user, passwd, options);
-  if(result != CURLE_OK)
+  if(result)
     goto out;
 
   /*************************************************************
@@ -5414,7 +5609,7 @@ static CURLcode create_conn(struct SessionHandle *data,
    * we figured out what/if proxy to use.
    *************************************************************/
   result = setup_connection_internals(conn);
-  if(result != CURLE_OK)
+  if(result)
     goto out;
 
   conn->recv[FIRSTSOCKET] = Curl_recv_plain;
@@ -5434,11 +5629,11 @@ static CURLcode create_conn(struct SessionHandle *data,
     result = conn->handler->connect_it(conn, &done);
 
     /* Setup a "faked" transfer that'll do nothing */
-    if(CURLE_OK == result) {
+    if(!result) {
       conn->data = data;
       conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
 
-      ConnectionStore(data, conn);
+      Curl_conncache_add_conn(data->state.conn_cache, conn);
 
       /*
        * Setup whatever necessary for a resumed transfer
@@ -5456,7 +5651,7 @@ static CURLcode create_conn(struct SessionHandle *data,
     }
 
     /* since we skip do_init() */
-    do_init(conn);
+    Curl_init_do(data, conn);
 
     goto out;
   }
@@ -5503,7 +5698,7 @@ static CURLcode create_conn(struct SessionHandle *data,
   if(data->set.reuse_fresh && !data->state.this_is_a_follow)
     reuse = FALSE;
   else
-    reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse);
+    reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
 
   /* If we found a reusable connection, we may still want to
      open a new connection if we are pipelining. */
@@ -5540,18 +5735,24 @@ static CURLcode create_conn(struct SessionHandle *data,
     /* set a pointer to the hostname we display */
     fix_hostname(data, conn, &conn->host);
 
-    infof(data, "Re-using existing connection! (#%ld) with host %s\n",
+    infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
           conn->connection_id,
+          conn->bits.proxy?"proxy":"host",
           conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
   }
   else {
     /* We have decided that we want a new connection. However, we may not
        be able to do that if we have reached the limit of how many
        connections we are allowed to open. */
-    struct connectbundle *bundle;
+    struct connectbundle *bundle = NULL;
+
+    if(waitpipe)
+      /* There is a connection that *might* become usable for pipelining
+         "soon", and we wait for that */
+      connections_available = FALSE;
+    else
+      bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
 
-    bundle = Curl_conncache_find_bundle(data->state.conn_cache,
-                                        conn->host.name);
     if(max_host_connections > 0 && bundle &&
        (bundle->num_connections >= max_host_connections)) {
       struct connectdata *conn_candidate;
@@ -5564,11 +5765,15 @@ static CURLcode create_conn(struct SessionHandle *data,
         conn_candidate->data = data;
         (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
       }
-      else
-        no_connections_available = TRUE;
+      else {
+        infof(data, "No more connections allowed to host: %d\n",
+              max_host_connections);
+        connections_available = FALSE;
+      }
     }
 
-    if(max_total_connections > 0 &&
+    if(connections_available &&
+       (max_total_connections > 0) &&
        (data->state.conn_cache->num_connections >= max_total_connections)) {
       struct connectdata *conn_candidate;
 
@@ -5580,12 +5785,13 @@ static CURLcode create_conn(struct SessionHandle *data,
         conn_candidate->data = data;
         (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
       }
-      else
-        no_connections_available = TRUE;
+      else {
+        infof(data, "No connections available in cache\n");
+        connections_available = FALSE;
+      }
     }
 
-
-    if(no_connections_available) {
+    if(!connections_available) {
       infof(data, "No connections available.\n");
 
       conn_free(conn);
@@ -5599,9 +5805,10 @@ static CURLcode create_conn(struct SessionHandle *data,
        * This is a brand new connection, so let's store it in the connection
        * cache of ours!
        */
-      ConnectionStore(data, conn);
+      Curl_conncache_add_conn(data->state.conn_cache, conn);
     }
 
+#if defined(USE_NTLM)
     /* If NTLM is requested in a part of this connection, make sure we don't
        assume the state is fine as this is a fresh connection and NTLM is
        connection based. */
@@ -5610,19 +5817,20 @@ static CURLcode create_conn(struct SessionHandle *data,
       infof(data, "NTLM picked AND auth done set, clear picked!\n");
       data->state.authhost.picked = CURLAUTH_NONE;
     }
+
     if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
        data->state.authproxy.done) {
       infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
       data->state.authproxy.picked = CURLAUTH_NONE;
     }
-
+#endif
   }
 
   /* Mark the connection as used */
   conn->inuse = TRUE;
 
   /* Setup and init stuff before DO starts, in preparing for the transfer. */
-  do_init(conn);
+  Curl_init_do(data, conn);
 
   /*
    * Setup whatever necessary for a resumed transfer
@@ -5637,8 +5845,6 @@ static CURLcode create_conn(struct SessionHandle *data,
    * Inherit the proper values from the urldata struct AFTER we have arranged
    * the persistent connection stuff
    */
-  conn->fread_func = data->set.fread_func;
-  conn->fread_in = data->set.in;
   conn->seek_func = data->set.seek_func;
   conn->seek_client = data->set.seek_client;
 
@@ -5649,10 +5855,10 @@ static CURLcode create_conn(struct SessionHandle *data,
 
   out:
 
-  Curl_safefree(options);
-  Curl_safefree(passwd);
-  Curl_safefree(user);
-  Curl_safefree(proxy);
+  free(options);
+  free(passwd);
+  free(user);
+  free(proxy);
   return result;
 }
 
@@ -5747,14 +5953,14 @@ CURLcode Curl_connect(struct SessionHandle *data,
                       bool *asyncp,
                       bool *protocol_done)
 {
-  CURLcode code;
+  CURLcode result;
 
   *asyncp = FALSE; /* assume synchronous resolves by default */
 
   /* call the stuff that needs to be called */
-  code = create_conn(data, in_connect, asyncp);
+  result = create_conn(data, in_connect, asyncp);
 
-  if(CURLE_OK == code) {
+  if(!result) {
     /* no error */
     if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
       /* pipelining */
@@ -5763,23 +5969,23 @@ CURLcode Curl_connect(struct SessionHandle *data,
       /* DNS resolution is done: that's either because this is a reused
          connection, in which case DNS was unnecessary, or because DNS
          really did finish already (synch resolver/fast async resolve) */
-      code = Curl_setup_conn(*in_connect, protocol_done);
+      result = Curl_setup_conn(*in_connect, protocol_done);
     }
   }
 
-  if(code == CURLE_NO_CONNECTION_AVAILABLE) {
+  if(result == CURLE_NO_CONNECTION_AVAILABLE) {
     *in_connect = NULL;
-    return code;
+    return result;
   }
 
-  if(code && *in_connect) {
+  if(result && *in_connect) {
     /* We're not allowed to return failure with memory left allocated
        in the connectdata struct, free those here */
     Curl_disconnect(*in_connect, FALSE); /* close the connection */
     *in_connect = NULL;           /* return a NULL */
   }
 
-  return code;
+  return result;
 }
 
 CURLcode Curl_done(struct connectdata **connp,
@@ -5796,37 +6002,19 @@ CURLcode Curl_done(struct connectdata **connp,
   conn = *connp;
   data = conn->data;
 
-  if(conn->bits.done)
+  DEBUGF(infof(data, "Curl_done\n"));
+
+  if(data->state.done)
     /* Stop if Curl_done() has already been called */
     return CURLE_OK;
 
   Curl_getoff_all_pipelines(data, conn);
 
-  if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
-      !data->set.reuse_forbid &&
-      !conn->bits.close))
-    /* Stop if pipeline is not empty and we do not have to close
-       connection. */
-    return CURLE_OK;
-
-  conn->bits.done = TRUE; /* called just now! */
-
   /* Cleanup possible redirect junk */
-  if(data->req.newurl) {
-    free(data->req.newurl);
-    data->req.newurl = NULL;
-  }
-  if(data->req.location) {
-    free(data->req.location);
-    data->req.location = NULL;
-  }
-
-  Curl_resolver_cancel(conn);
-
-  if(conn->dns_entry) {
-    Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
-    conn->dns_entry = NULL;
-  }
+  free(data->req.newurl);
+  data->req.newurl = NULL;
+  free(data->req.location);
+  data->req.location = NULL;
 
   switch(status) {
   case CURLE_ABORTED_BY_CALLBACK:
@@ -5850,12 +6038,27 @@ CURLcode Curl_done(struct connectdata **connp,
   if(!result && Curl_pgrsDone(conn))
     result = CURLE_ABORTED_BY_CALLBACK;
 
+  if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
+      !data->set.reuse_forbid &&
+      !conn->bits.close)) {
+    /* Stop if pipeline is not empty and we do not have to close
+       connection. */
+    DEBUGF(infof(data, "Connection still in use, no more Curl_done now!\n"));
+    return CURLE_OK;
+  }
+
+  data->state.done = TRUE; /* called just now! */
+  Curl_resolver_cancel(conn);
+
+  if(conn->dns_entry) {
+    Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
+    conn->dns_entry = NULL;
+  }
+
   /* if the transfer was completed in a paused state there can be buffered
      data left to write and then kill */
-  if(data->state.tempwrite) {
-    free(data->state.tempwrite);
-    data->state.tempwrite = NULL;
-  }
+  free(data->state.tempwrite);
+  data->state.tempwrite = NULL;
 
   /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
      forced us to close this connection. This is ignored for requests taking
@@ -5872,9 +6075,12 @@ CURLcode Curl_done(struct connectdata **connp,
      but currently we have no such detail knowledge.
   */
 
-  if((data->set.reuse_forbid && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
-                                  conn->proxyntlm.state == NTLMSTATE_TYPE2))
-     || conn->bits.close || premature) {
+  if((data->set.reuse_forbid
+#if defined(USE_NTLM)
+      && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
+           conn->proxyntlm.state == NTLMSTATE_TYPE2)
+#endif
+     ) || conn->bits.close || premature) {
     CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
 
     /* If we had an error already, make sure we return that one. But
@@ -5906,20 +6112,24 @@ CURLcode Curl_done(struct connectdata **connp,
 }
 
 /*
- * do_init() inits the readwrite session. This is inited each time (in the DO
- * function before the protocol-specific DO functions are invoked) for a
- * transfer, sometimes multiple times on the same SessionHandle. Make sure
+ * Curl_init_do() inits the readwrite session. This is inited each time (in
+ * the DO function before the protocol-specific DO functions are invoked) for
+ * a transfer, sometimes multiple times on the same SessionHandle. Make sure
  * nothing in here depends on stuff that are setup dynamically for the
  * transfer.
+ *
+ * Allow this function to get called with 'conn' set to NULL.
  */
 
-static CURLcode do_init(struct connectdata *conn)
+CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn)
 {
-  struct SessionHandle *data = conn->data;
   struct SingleRequest *k = &data->req;
 
-  conn->bits.done = FALSE; /* Curl_done() is not called yet */
-  conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
+  if(conn)
+    conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
+                                 * use */
+
+  data->state.done = FALSE; /* Curl_done() is not called yet */
   data->state.expect100header = FALSE;
 
   if(data->set.opt_no_body)
@@ -5986,7 +6196,7 @@ CURLcode Curl_do(struct connectdata **connp, bool *done)
       if(!data->multi) {
         result = Curl_reconnect_request(connp);
 
-        if(result == CURLE_OK) {
+        if(!result) {
           /* ... finally back to actually retry the DO phase */
           conn = *connp; /* re-assign conn since Curl_reconnect_request
                             creates a new connection */
@@ -5997,7 +6207,7 @@ CURLcode Curl_do(struct connectdata **connp, bool *done)
         return result;
     }
 
-    if((result == CURLE_OK) && *done)
+    if(!result && *done)
       /* do_complete must be called after the protocol-specific DO function */
       do_complete(conn);
   }
diff --git a/Utilities/cmcurl/lib/url.h b/Utilities/cmcurl/lib/url.h
index cd46a92..f9667cb 100644
--- a/Utilities/cmcurl/lib/url.h
+++ b/Utilities/cmcurl/lib/url.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,6 +27,7 @@
  * Prototypes for library-wide functions provided by url.c
  */
 
+CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn);
 CURLcode Curl_open(struct SessionHandle **curl);
 CURLcode Curl_init_userdefined(struct UserDefined *set);
 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
@@ -69,6 +70,9 @@ void Curl_close_connections(struct SessionHandle *data);
 #define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
 #define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi
                                                      service */
+#define CURL_DEFAULT_PROXY_SERVICE_NAME "HTTP" /* default negotiate proxy
+                                                  service */
+#define CURL_DEFAULT_SERVICE_NAME "HTTP"  /* default negotiate service */
 
 CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
 
diff --git a/Utilities/cmcurl/lib/urldata.h b/Utilities/cmcurl/lib/urldata.h
index 8594c2f..b1c2056 100644
--- a/Utilities/cmcurl/lib/urldata.h
+++ b/Utilities/cmcurl/lib/urldata.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -40,6 +40,8 @@
 #define PORT_IMAPS 993
 #define PORT_POP3 110
 #define PORT_POP3S 995
+#define PORT_SMB 445
+#define PORT_SMBS 445
 #define PORT_SMTP 25
 #define PORT_SMTPS 465 /* sometimes called SSMTP */
 #define PORT_RTSP 554
@@ -64,6 +66,7 @@
 #define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS)
 #define PROTO_FAMILY_FTP  (CURLPROTO_FTP|CURLPROTO_FTPS)
 #define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S)
+#define PROTO_FAMILY_SMB  (CURLPROTO_SMB|CURLPROTO_SMBS)
 #define PROTO_FAMILY_SMTP (CURLPROTO_SMTP|CURLPROTO_SMTPS)
 
 #define DEFAULT_CONNCACHE_SIZE 5
@@ -79,38 +82,12 @@
 #include "cookie.h"
 #include "formdata.h"
 
-#ifdef USE_SSLEAY
 #ifdef USE_OPENSSL
-#include <openssl/rsa.h>
-#include <openssl/crypto.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
 #include <openssl/ssl.h>
-#include <openssl/err.h>
 #ifdef HAVE_OPENSSL_ENGINE_H
 #include <openssl/engine.h>
 #endif
-#ifdef HAVE_OPENSSL_PKCS12_H
-#include <openssl/pkcs12.h>
-#endif
-#else /* SSLeay-style includes */
-#include <rsa.h>
-#include <crypto.h>
-#include <x509.h>
-#include <pem.h>
-#include <ssl.h>
-#include <err.h>
-#ifdef HAVE_OPENSSL_ENGINE_H
-#include <engine.h>
-#endif
-#ifdef HAVE_OPENSSL_PKCS12_H
-#include <pkcs12.h>
-#endif
 #endif /* USE_OPENSSL */
-#ifdef USE_GNUTLS
-#error Configuration error; cannot use GnuTLS *and* OpenSSL.
-#endif
-#endif /* USE_SSLEAY */
 
 #ifdef USE_GNUTLS
 #include <gnutls/gnutls.h>
@@ -138,15 +115,12 @@
 #include <pk11pub.h>
 #endif
 
-#ifdef USE_QSOSSL
-#include <qsossl.h>
-#endif
-
 #ifdef USE_GSKIT
 #include <gskssl.h>
 #endif
 
 #ifdef USE_AXTLS
+#include <axTLS/config.h>
 #include <axTLS/ssl.h>
 #undef malloc
 #undef calloc
@@ -195,6 +169,7 @@
 #include "ssh.h"
 #include "http.h"
 #include "rtsp.h"
+#include "smb.h"
 #include "wildcard.h"
 #include "multihandle.h"
 
@@ -223,6 +198,8 @@
 #define HEADERSIZE 256
 
 #define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
+#define GOOD_EASY_HANDLE(x) \
+  ((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
 
 /* Some convenience macros to get the larger/smaller value out of two given.
    We prefix with CURL to prevent name collisions. */
@@ -288,13 +265,13 @@ struct ssl_connect_data {
      current state of the connection. */
   bool use;
   ssl_connection_state state;
-#ifdef USE_SSLEAY
+#ifdef USE_OPENSSL
   /* these ones requires specific SSL-types */
   SSL_CTX* ctx;
   SSL*     handle;
   X509*    server_cert;
   ssl_connect_state connecting_state;
-#endif /* USE_SSLEAY */
+#endif /* USE_OPENSSL */
 #ifdef USE_GNUTLS
   gnutls_session_t session;
   gnutls_certificate_credentials_t cred;
@@ -328,9 +305,6 @@ struct ssl_connect_data {
   PK11GenericObject *obj_clicert;
   ssl_connect_state connecting_state;
 #endif /* USE_NSS */
-#ifdef USE_QSOSSL
-  SSLHandle *handle;
-#endif /* USE_QSOSSL */
 #ifdef USE_GSKIT
   gsk_handle handle;
   int iocport;
@@ -350,6 +324,9 @@ struct ssl_connect_data {
   size_t encdata_offset, decdata_offset;
   unsigned char *encdata_buffer, *decdata_buffer;
   unsigned long req_flags, ret_flags;
+  CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
+  bool recv_sspi_close_notify; /* true if connection closed by close_notify */
+  bool recv_connection_closed; /* true if connection closed, regardless how */
 #endif /* USE_SCHANNEL */
 #ifdef USE_DARWINSSL
   SSLContextRef ssl_ctx;
@@ -366,6 +343,7 @@ struct ssl_config_data {
 
   bool verifypeer;       /* set TRUE if this is desired */
   bool verifyhost;       /* set TRUE if CN/SAN must match hostname */
+  bool verifystatus;     /* set TRUE if certificate status must be checked */
   char *CApath;          /* certificate dir (doesn't work on windows) */
   char *CAfile;          /* certificate to verify peer against */
   const char *CRLfile;   /* CRL to check certificate revocation */
@@ -378,6 +356,7 @@ struct ssl_config_data {
   void *fsslctxp;        /* parameter for call back */
   bool sessionid;        /* cache session IDs or not */
   bool certinfo;         /* gather lots of certificate info */
+  bool falsestart;
 
 #ifdef USE_TLS_SRP
   char *username; /* TLS username (for, e.g., SRP) */
@@ -398,6 +377,10 @@ struct curl_ssl_session {
 
 /* Struct used for Digest challenge-response authentication */
 struct digestdata {
+#if defined(USE_WINDOWS_SSPI)
+  BYTE *input_token;
+  size_t input_token_len;
+#else
   char *nonce;
   char *cnonce;
   char *realm;
@@ -407,6 +390,7 @@ struct digestdata {
   char *qop;
   char *algorithm;
   int nc; /* nounce count */
+#endif
 };
 
 typedef enum {
@@ -426,8 +410,9 @@ typedef enum {
 #endif
 
 /* Struct used for GSSAPI (Kerberos V5) authentication */
-#if defined(USE_WINDOWS_SSPI)
+#if defined(USE_KERBEROS5)
 struct kerberos5data {
+#if defined(USE_WINDOWS_SSPI)
   CredHandle *credentials;
   CtxtHandle *context;
   TCHAR *spn;
@@ -435,22 +420,26 @@ struct kerberos5data {
   SEC_WINNT_AUTH_IDENTITY *p_identity;
   size_t token_max;
   BYTE *output_token;
+#else
+  gss_ctx_id_t context;
+  gss_name_t spn;
+#endif
 };
 #endif
 
 /* Struct used for NTLM challenge-response authentication */
+#if defined(USE_NTLM)
 struct ntlmdata {
   curlntlm state;
 #ifdef USE_WINDOWS_SSPI
-  CredHandle handle;
-  CtxtHandle c_handle;
+  CredHandle *credentials;
+  CtxtHandle *context;
   SEC_WINNT_AUTH_IDENTITY identity;
   SEC_WINNT_AUTH_IDENTITY *p_identity;
-  size_t max_token_length;
+  size_t token_max;
   BYTE *output_token;
-  int has_handles;
-  void *type_2;
-  unsigned long n_type_2;
+  BYTE *input_token;
+  size_t input_token_len;
 #else
   unsigned int flags;
   unsigned char nonce[8];
@@ -458,6 +447,7 @@ struct ntlmdata {
   unsigned int target_info_len;
 #endif
 };
+#endif
 
 #ifdef USE_SPNEGO
 struct negotiatedata {
@@ -472,12 +462,12 @@ struct negotiatedata {
 #else
 #ifdef USE_WINDOWS_SSPI
   DWORD status;
-  CtxtHandle *context;
   CredHandle *credentials;
+  CtxtHandle *context;
   SEC_WINNT_AUTH_IDENTITY identity;
   SEC_WINNT_AUTH_IDENTITY *p_identity;
   TCHAR *server_name;
-  size_t max_token_length;
+  size_t token_max;
   BYTE *output_token;
   size_t output_token_length;
 #endif
@@ -531,11 +521,6 @@ struct ConnectBits {
                          requests */
   bool netrc;         /* name+password provided by netrc */
   bool userpwd_in_url; /* name+password found in url */
-
-  bool done;          /* set to FALSE when Curl_do() is called and set to TRUE
-                         when Curl_done() is called, to prevent Curl_done() to
-                         get invoked twice when the multi interface is
-                         used. */
   bool stream_was_rewound; /* Indicates that the stream was rewound after a
                               request read past the end of its response byte
                               boundary */
@@ -545,6 +530,7 @@ struct ConnectBits {
   bool bound; /* set true if bind() has already been done on this socket/
                  connection */
   bool type_set;  /* type= was used in the URL */
+  bool multiplex; /* connection is multiplexed */
 };
 
 struct hostname {
@@ -617,12 +603,6 @@ enum upgrade101 {
   UPGR101_WORKING             /* talking upgraded protocol */
 };
 
-enum negotiatenpn {
-  NPN_INIT,                   /* default state */
-  NPN_HTTP1_1,                /* HTTP/1.1 negotiated */
-  NPN_HTTP2                   /* HTTP2 (draft-xx) negotiated */
-};
-
 /*
  * Request specific data in the easy handle (SessionHandle).  Previously,
  * these members were on the connectdata struct but since a conn struct may
@@ -680,7 +660,6 @@ struct SingleRequest {
 #define IDENTITY 0              /* No encoding */
 #define DEFLATE 1               /* zlib deflate [RFC 1950 & 1951] */
 #define GZIP 2                  /* gzip algorithm [RFC 1952] */
-#define COMPRESS 3              /* Not handled, added for completeness */
 
 #ifdef HAVE_LIBZ
   zlibInitState zlib_init;      /* possible zlib init state;
@@ -883,7 +862,7 @@ struct connectdata {
      the ip_addr itself. */
   char ip_addr_str[MAX_IPADR_LEN];
 
-  unsigned int scope;    /* address scope for IPv6 */
+  unsigned int scope_id;  /* Scope id for IPv6 */
 
   int socktype;  /* SOCK_STREAM or SOCK_DGRAM */
 
@@ -974,8 +953,8 @@ struct connectdata {
     char *te; /* TE: request header */
   } allocptr;
 
-  int sec_complete; /* if kerberos is enabled for this connection */
 #ifdef HAVE_GSSAPI
+  int sec_complete; /* if Kerberos is enabled for this connection */
   enum protection_level command_prot;
   enum protection_level data_prot;
   enum protection_level request_data_prot;
@@ -986,7 +965,7 @@ struct connectdata {
   struct sockaddr_in local_addr;
 #endif
 
-#if defined(USE_WINDOWS_SSPI) /* Consider moving some of the above GSS-API */
+#if defined(USE_KERBEROS5)    /* Consider moving some of the above GSS-API */
   struct kerberos5data krb5;  /* variables into the structure definition, */
 #endif                        /* however, some of them are ftp specific. */
 
@@ -1013,22 +992,20 @@ struct connectdata {
 
   /*************** Request - specific items ************/
 
-  /* previously this was in the urldata struct */
-  curl_read_callback fread_func; /* function that reads the input */
-  void *fread_in;           /* pointer to pass to the fread() above */
-
+#if defined(USE_NTLM)
   struct ntlmdata ntlm;     /* NTLM differs from other authentication schemes
                                because it authenticates connections, not
                                single requests! */
   struct ntlmdata proxyntlm; /* NTLM data for proxy */
 
-#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+#if defined(NTLM_WB_ENABLED)
   /* used for communication with Samba's winbind daemon helper ntlm_auth */
   curl_socket_t ntlm_auth_hlpr_socket;
   pid_t ntlm_auth_hlpr_pid;
   char* challenge_header;
   char* response_header;
 #endif
+#endif
 
   char syserr_buf [256]; /* buffer for Curl_strerror() */
 
@@ -1051,6 +1028,7 @@ struct connectdata {
     struct pop3_conn pop3c;
     struct smtp_conn smtpc;
     struct rtsp_conn rtspc;
+    struct smb_conn smbc;
     void *generic; /* RTMP and LDAP use this */
   } proto;
 
@@ -1081,7 +1059,7 @@ struct connectdata {
   } tunnel_state[2]; /* two separate ones to allow FTP */
   struct connectbundle *bundle; /* The bundle we are member of */
 
-  enum negotiatenpn negnpn;
+  int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */
 };
 
 /* The end of connectdata. */
@@ -1279,9 +1257,9 @@ struct UrlState {
   void *resolver; /* resolver state, if it is used in the URL state -
                      ares_channel f.e. */
 
-#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
   ENGINE *engine;
-#endif /* USE_SSLEAY */
+#endif /* USE_OPENSSL */
   struct timeval expiretime; /* set this with Curl_expire() only */
   struct Curl_tree timenode; /* for the splay stuff */
   struct curl_llist *timeoutlist; /* list of pending timeouts */
@@ -1325,10 +1303,15 @@ struct UrlState {
   long rtsp_next_server_CSeq; /* the session's next server CSeq */
   long rtsp_CSeq_recv; /* most recent CSeq received */
 
-  /* if true, force SSL connection retry (workaround for certain servers) */
-  bool ssl_connect_retry;
   curl_off_t infilesize; /* size of file to upload, -1 means unknown.
                             Copied from set.filesize at start of operation */
+
+  int drain; /* Increased when this stream has data to read, even if its
+                socket not necessarily is readable. Decreased when
+                checked. */
+  bool done; /* set to FALSE when Curl_do() is called and set to TRUE when
+                Curl_done() is called, to prevent Curl_done() to get invoked
+                twice when the multi interface is used. */
 };
 
 
@@ -1378,13 +1361,13 @@ enum dupstring {
   STRING_KRB_LEVEL,       /* krb security level */
   STRING_NETRC_FILE,      /* if not NULL, use this instead of trying to find
                              $HOME/.netrc */
-  STRING_COPYPOSTFIELDS,  /* if POST, set the fields' values here */
   STRING_PROXY,           /* proxy to use */
   STRING_SET_RANGE,       /* range, if used */
   STRING_SET_REFERER,     /* custom string for the HTTP referer field */
   STRING_SET_URL,         /* what original URL to work on */
   STRING_SSL_CAPATH,      /* CA directory name (doesn't work on windows) */
   STRING_SSL_CAFILE,      /* certificate file to verify peer against */
+  STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */
   STRING_SSL_CIPHER_LIST, /* list of ciphers to use */
   STRING_SSL_EGDSOCKET,   /* path to file containing the EGD daemon socket */
   STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
@@ -1408,19 +1391,31 @@ enum dupstring {
   STRING_SSH_KNOWNHOSTS,  /* file name of knownhosts file */
 #endif
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
-  STRING_SOCKS5_GSSAPI_SERVICE,  /* GSSAPI service name */
+  STRING_SOCKS5_GSSAPI_SERVICE, /* GSSAPI service name */
+  STRING_PROXY_SERVICE_NAME, /* Proxy service name */
+  STRING_SERVICE_NAME,    /* Service name */
 #endif
   STRING_MAIL_FROM,
   STRING_MAIL_AUTH,
 
 #ifdef USE_TLS_SRP
-  STRING_TLSAUTH_USERNAME,     /* TLS auth <username> */
-  STRING_TLSAUTH_PASSWORD,     /* TLS auth <password> */
+  STRING_TLSAUTH_USERNAME,      /* TLS auth <username> */
+  STRING_TLSAUTH_PASSWORD,      /* TLS auth <password> */
 #endif
+  STRING_BEARER,                /* <bearer>, if used */
+#ifdef USE_UNIX_SOCKETS
+  STRING_UNIX_SOCKET_PATH,      /* path to Unix socket, if used */
+#endif
+
+  /* -- end of zero-terminated strings -- */
 
-  STRING_BEARER,          /* <bearer>, if used */
+  STRING_LASTZEROTERMINATED,
+
+  /* -- below this are pointers to binary data that cannot be strdup'ed.
+     Each such pointer must be added manually to Curl_dupset() --- */
+
+  STRING_COPYPOSTFIELDS,  /* if POST, set the fields' values here */
 
-  /* -- end of strings -- */
   STRING_LAST /* not used, just an end-of-list marker */
 };
 
@@ -1431,8 +1426,8 @@ struct UserDefined {
   long proxyport; /* If non-zero, use this port number by default. If the
                      proxy string features a ":[port]" that one will override
                      this. */
-  void *out;         /* the fetched file goes here */
-  void *in;          /* the uploaded file is read from here */
+  void *out;         /* CURLOPT_WRITEDATA */
+  void *in;          /* CURLOPT_READDATA */
   void *writeheader; /* write the header to this if non-NULL */
   void *rtp_out;     /* write RTP to this if non-NULL */
   long use_port;     /* which port to use (when not using default) */
@@ -1553,7 +1548,7 @@ struct UserDefined {
   bool ftp_list_only;    /* switch FTP command for listing directories */
   bool ftp_use_port;     /* use the FTP PORT command */
   bool hide_progress;    /* don't use the progress meter */
-  bool http_fail_on_error;  /* fail on HTTP error codes >= 300 */
+  bool http_fail_on_error;  /* fail on HTTP error codes >= 400 */
   bool http_follow_location; /* follow HTTP redirects */
   bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
   bool http_disable_hostname_check_before_authentication;
@@ -1566,7 +1561,7 @@ struct UserDefined {
   enum CURL_NETRC_OPTION
        use_netrc;        /* defined in include/curl.h */
   bool verbose;          /* output verbosity */
-  bool krb;              /* kerberos connection requested */
+  bool krb;              /* Kerberos connection requested */
   bool reuse_forbid;     /* forbidden to be reused, close after use */
   bool reuse_fresh;      /* do not re-use an existing connection  */
   bool ftp_use_epsv;     /* if EPSV is to be attempted or not */
@@ -1586,6 +1581,7 @@ struct UserDefined {
   bool connect_only;     /* make connection, let application use the socket */
   bool ssl_enable_beast; /* especially allow this flaw for interoperability's
                             sake*/
+  bool ssl_no_revoke;    /* disable SSL certificate revocation checks */
   long ssh_auth_types;   /* allowed SSH auth types */
   bool http_te_skip;     /* pass the raw body data to the user, even when
                             transfer-encoded (chunked, compressed) */
@@ -1596,7 +1592,7 @@ struct UserDefined {
   bool proxy_transfer_mode; /* set transfer mode (;type=<a|i>) when doing FTP
                                via an HTTP proxy */
   char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
-  unsigned int scope;    /* address scope for IPv6 */
+  unsigned int scope_id;  /* Scope id for IPv6 */
   long allowed_protocols;
   long redir_protocols;
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
@@ -1627,7 +1623,9 @@ struct UserDefined {
 
   bool ssl_enable_npn;  /* TLS NPN extension? */
   bool ssl_enable_alpn; /* TLS ALPN extension? */
-
+  bool path_as_is;      /* allow dotdots? */
+  bool pipewait;        /* wait for pipe/multiplex status before starting a
+                           new connection */
   long expect_100_timeout; /* in milliseconds */
 };
 
diff --git a/Utilities/cmcurl/lib/version.c b/Utilities/cmcurl/lib/version.c
index 788f3e9..1727c5a 100644
--- a/Utilities/cmcurl/lib/version.c
+++ b/Utilities/cmcurl/lib/version.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,9 +26,7 @@
 #include "urldata.h"
 #include "vtls/vtls.h"
 #include "http2.h"
-
-#define _MPRINTF_REPLACE /* use the internal *printf() functions */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #ifdef USE_ARES
 #  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
@@ -216,6 +214,14 @@ static const char * const protocols[] = {
 #ifdef USE_LIBSSH2
   "sftp",
 #endif
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+   (CURL_SIZEOF_CURL_OFF_T > 4) && \
+   (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+  "smb",
+#  ifdef USE_SSL
+  "smbs",
+#  endif
+#endif
 #ifndef CURL_DISABLE_SMTP
   "smtp",
 #endif
@@ -247,12 +253,16 @@ static curl_version_info_data version_info = {
 #ifdef USE_NTLM
   | CURL_VERSION_NTLM
 #endif
-#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+  defined(NTLM_WB_ENABLED)
   | CURL_VERSION_NTLM_WB
 #endif
 #ifdef USE_SPNEGO
   | CURL_VERSION_SPNEGO
 #endif
+#ifdef USE_KERBEROS5
+  | CURL_VERSION_KERBEROS5
+#endif
 #ifdef HAVE_GSSAPI
   | CURL_VERSION_GSSAPI
 #endif
@@ -284,6 +294,9 @@ static curl_version_info_data version_info = {
 #if defined(USE_NGHTTP2)
   | CURL_VERSION_HTTP2
 #endif
+#if defined(USE_UNIX_SOCKETS)
+  | CURL_VERSION_UNIX_SOCKETS
+#endif
   ,
   NULL, /* ssl_version */
   0,    /* ssl_version_num, this is kept at zero */
diff --git a/Utilities/cmcurl/lib/vtls/axtls.c b/Utilities/cmcurl/lib/vtls/axtls.c
index 1b577b1..1038432 100644
--- a/Utilities/cmcurl/lib/vtls/axtls.c
+++ b/Utilities/cmcurl/lib/vtls/axtls.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu at directv.com>.
- * Copyright (C) 2010 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -29,6 +29,7 @@
 #include "curl_setup.h"
 
 #ifdef USE_AXTLS
+#include <axTLS/config.h>
 #include <axTLS/ssl.h>
 #include "axtls.h"
 
@@ -38,13 +39,13 @@
 #include "parsedate.h"
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-#include "curl_memory.h"
+#include "curl_printf.h"
+#include "hostcheck.h"
 #include <unistd.h>
-/* The last #include file should be: */
+
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
-#include "hostcheck.h"
 
 
 /* Global axTLS init, called from Curl_ssl_init() */
@@ -463,9 +464,11 @@ Curl_axtls_connect(struct connectdata *conn,
                   int sockindex)
 
 {
+  struct SessionHandle *data = conn->data;
   CURLcode conn_step = connect_prep(conn, sockindex);
   int ssl_fcn_return;
   SSL *ssl = conn->ssl[sockindex].ssl;
+  long timeout_ms;
 
   if(conn_step != CURLE_OK) {
     Curl_axtls_close(conn, sockindex);
@@ -474,14 +477,23 @@ Curl_axtls_connect(struct connectdata *conn,
 
   /* Check to make sure handshake was ok. */
   while(ssl_handshake_status(ssl) != SSL_OK) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
     ssl_fcn_return = ssl_read(ssl, NULL);
     if(ssl_fcn_return < 0) {
       Curl_axtls_close(conn, sockindex);
       ssl_display_error(ssl_fcn_return); /* goes to stdout. */
       return map_error_to_curl(ssl_fcn_return);
     }
+    /* TODO: avoid polling */
     usleep(10000);
-    /* TODO: check for timeout as this could hang indefinitely otherwise */
   }
   infof (conn->data, "handshake completed successfully\n");
 
@@ -515,12 +527,6 @@ static ssize_t axtls_send(struct connectdata *conn,
   return rc;
 }
 
-void Curl_axtls_close_all(struct SessionHandle *data)
-{
-  (void)data;
-  infof(data, "  Curl_axtls_close_all\n");
-}
-
 void Curl_axtls_close(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
@@ -677,7 +683,7 @@ int Curl_axtls_random(struct SessionHandle *data,
      * race condition is that some global resources will leak. */
     RNG_initialize();
   }
-  get_random(length, entropy);
+  get_random((int)length, entropy);
   return 0;
 }
 
diff --git a/Utilities/cmcurl/lib/vtls/axtls.h b/Utilities/cmcurl/lib/vtls/axtls.h
index 0459cf2..223ecb8 100644
--- a/Utilities/cmcurl/lib/vtls/axtls.h
+++ b/Utilities/cmcurl/lib/vtls/axtls.h
@@ -7,8 +7,8 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010, DirecTV
- * contact: Eric Hu <ehu at directv.com>
+ * Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu at directv.com>
+ * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,10 +35,6 @@ CURLcode Curl_axtls_connect_nonblocking(
     int sockindex,
     bool *done);
 
-/* tell axTLS to close down all open information regarding connections (and
-   thus session ID caching etc) */
-void Curl_axtls_close_all(struct SessionHandle *data);
-
  /* close a SSL connection */
 void Curl_axtls_close(struct connectdata *conn, int sockindex);
 
@@ -50,23 +46,26 @@ int Curl_axtls_random(struct SessionHandle *data,
                       unsigned char *entropy,
                       size_t length);
 
+/* Set the API backend definition to axTLS */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_AXTLS
+
 /* API setup for axTLS */
 #define curlssl_init Curl_axtls_init
 #define curlssl_cleanup Curl_axtls_cleanup
 #define curlssl_connect Curl_axtls_connect
 #define curlssl_connect_nonblocking Curl_axtls_connect_nonblocking
 #define curlssl_session_free(x)  Curl_axtls_session_free(x)
-#define curlssl_close_all Curl_axtls_close_all
+#define curlssl_close_all(x) ((void)x)
 #define curlssl_close Curl_axtls_close
 #define curlssl_shutdown(x,y) Curl_axtls_shutdown(x,y)
-#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN)
-#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN)
-#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
 #define curlssl_version Curl_axtls_version
 #define curlssl_check_cxn(x) Curl_axtls_check_cxn(x)
-#define curlssl_data_pending(x,y) (x=x, y=y, 0)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
 #define curlssl_random(x,y,z) Curl_axtls_random(x,y,z)
-#define CURL_SSL_BACKEND CURLSSLBACKEND_AXTLS
+
 #endif /* USE_AXTLS */
 #endif /* HEADER_CURL_AXTLS_H */
 
diff --git a/Utilities/cmcurl/lib/vtls/curl_darwinssl.c b/Utilities/cmcurl/lib/vtls/curl_darwinssl.c
deleted file mode 100644
index f229c6f..0000000
--- a/Utilities/cmcurl/lib/vtls/curl_darwinssl.c
+++ /dev/null
@@ -1,2485 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman at gmail.com>.
- * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-/*
- * Source file for all iOS and Mac OS X SecureTransport-specific code for the
- * TLS/SSL layer. No code but vtls.c should ever call or use these functions.
- */
-
-#include "curl_setup.h"
-
-#include "urldata.h" /* for the SessionHandle definition */
-#include "curl_base64.h"
-#include "strtok.h"
-
-#ifdef USE_DARWINSSL
-
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-
-#include <Security/Security.h>
-#include <Security/SecureTransport.h>
-#include <CoreFoundation/CoreFoundation.h>
-#include <CommonCrypto/CommonDigest.h>
-
-/* The Security framework has changed greatly between iOS and different OS X
-   versions, and we will try to support as many of them as we can (back to
-   Leopard and iOS 5) by using macros and weak-linking.
-
-   IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
-   you must build this project against the 10.8 SDK or later. */
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
-#error "The darwinssl back-end requires Leopard or later."
-#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
-
-#define CURL_BUILD_IOS 0
-#define CURL_BUILD_IOS_7 0
-#define CURL_BUILD_MAC 1
-/* This is the maximum API level we are allowed to use when building: */
-#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
-#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
-#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
-#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
-#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
-/* These macros mean "the following code is present to allow runtime backward
-   compatibility with at least this cat or earlier":
-   (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
-   environmental variable.) */
-#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
-#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
-#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
-#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
-#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
-
-#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
-#define CURL_BUILD_IOS 1
-#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
-#define CURL_BUILD_MAC 0
-#define CURL_BUILD_MAC_10_5 0
-#define CURL_BUILD_MAC_10_6 0
-#define CURL_BUILD_MAC_10_7 0
-#define CURL_BUILD_MAC_10_8 0
-#define CURL_SUPPORT_MAC_10_5 0
-#define CURL_SUPPORT_MAC_10_6 0
-#define CURL_SUPPORT_MAC_10_7 0
-#define CURL_SUPPORT_MAC_10_8 0
-
-#else
-#error "The darwinssl back-end requires iOS or OS X."
-#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
-
-#if CURL_BUILD_MAC
-#include <sys/sysctl.h>
-#endif /* CURL_BUILD_MAC */
-
-#include "urldata.h"
-#include "sendf.h"
-#include "inet_pton.h"
-#include "connect.h"
-#include "select.h"
-#include "vtls.h"
-#include "curl_darwinssl.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* From MacTypes.h (which we can't include because it isn't present in iOS: */
-#define ioErr -36
-#define paramErr -50
-
-/* The following two functions were ripped from Apple sample code,
- * with some modifications: */
-static OSStatus SocketRead(SSLConnectionRef connection,
-                           void *data,          /* owned by
-                                                 * caller, data
-                                                 * RETURNED */
-                           size_t *dataLength)  /* IN/OUT */
-{
-  size_t bytesToGo = *dataLength;
-  size_t initLen = bytesToGo;
-  UInt8 *currData = (UInt8 *)data;
-  /*int sock = *(int *)connection;*/
-  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
-  int sock = connssl->ssl_sockfd;
-  OSStatus rtn = noErr;
-  size_t bytesRead;
-  ssize_t rrtn;
-  int theErr;
-
-  *dataLength = 0;
-
-  for(;;) {
-    bytesRead = 0;
-    rrtn = read(sock, currData, bytesToGo);
-    if(rrtn <= 0) {
-      /* this is guesswork... */
-      theErr = errno;
-      if(rrtn == 0) { /* EOF = server hung up */
-        /* the framework will turn this into errSSLClosedNoNotify */
-        rtn = errSSLClosedGraceful;
-      }
-      else /* do the switch */
-        switch(theErr) {
-          case ENOENT:
-            /* connection closed */
-            rtn = errSSLClosedGraceful;
-            break;
-          case ECONNRESET:
-            rtn = errSSLClosedAbort;
-            break;
-          case EAGAIN:
-            rtn = errSSLWouldBlock;
-            connssl->ssl_direction = false;
-            break;
-          default:
-            rtn = ioErr;
-            break;
-        }
-      break;
-    }
-    else {
-      bytesRead = rrtn;
-    }
-    bytesToGo -= bytesRead;
-    currData  += bytesRead;
-
-    if(bytesToGo == 0) {
-      /* filled buffer with incoming data, done */
-      break;
-    }
-  }
-  *dataLength = initLen - bytesToGo;
-
-  return rtn;
-}
-
-static OSStatus SocketWrite(SSLConnectionRef connection,
-                            const void *data,
-                            size_t *dataLength)  /* IN/OUT */
-{
-  size_t bytesSent = 0;
-  /*int sock = *(int *)connection;*/
-  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
-  int sock = connssl->ssl_sockfd;
-  ssize_t length;
-  size_t dataLen = *dataLength;
-  const UInt8 *dataPtr = (UInt8 *)data;
-  OSStatus ortn;
-  int theErr;
-
-  *dataLength = 0;
-
-  do {
-    length = write(sock,
-                   (char*)dataPtr + bytesSent,
-                   dataLen - bytesSent);
-  } while((length > 0) &&
-           ( (bytesSent += length) < dataLen) );
-
-  if(length <= 0) {
-    theErr = errno;
-    if(theErr == EAGAIN) {
-      ortn = errSSLWouldBlock;
-      connssl->ssl_direction = true;
-    }
-    else {
-      ortn = ioErr;
-    }
-  }
-  else {
-    ortn = noErr;
-  }
-  *dataLength = bytesSent;
-  return ortn;
-}
-
-CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
-  switch (cipher) {
-    /* SSL version 3.0 */
-    case SSL_RSA_WITH_NULL_MD5:
-      return "SSL_RSA_WITH_NULL_MD5";
-      break;
-    case SSL_RSA_WITH_NULL_SHA:
-      return "SSL_RSA_WITH_NULL_SHA";
-      break;
-    case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
-      return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
-      break;
-    case SSL_RSA_WITH_RC4_128_MD5:
-      return "SSL_RSA_WITH_RC4_128_MD5";
-      break;
-    case SSL_RSA_WITH_RC4_128_SHA:
-      return "SSL_RSA_WITH_RC4_128_SHA";
-      break;
-    case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
-      return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
-      break;
-    case SSL_RSA_WITH_IDEA_CBC_SHA:
-      return "SSL_RSA_WITH_IDEA_CBC_SHA";
-      break;
-    case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
-      return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
-      break;
-    case SSL_RSA_WITH_DES_CBC_SHA:
-      return "SSL_RSA_WITH_DES_CBC_SHA";
-      break;
-    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
-      return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
-      return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
-      break;
-    case SSL_DH_DSS_WITH_DES_CBC_SHA:
-      return "SSL_DH_DSS_WITH_DES_CBC_SHA";
-      break;
-    case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
-      return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
-      return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
-      break;
-    case SSL_DH_RSA_WITH_DES_CBC_SHA:
-      return "SSL_DH_RSA_WITH_DES_CBC_SHA";
-      break;
-    case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
-      return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
-      return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
-      break;
-    case SSL_DHE_DSS_WITH_DES_CBC_SHA:
-      return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
-      break;
-    case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
-      return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
-      return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
-      break;
-    case SSL_DHE_RSA_WITH_DES_CBC_SHA:
-      return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
-      break;
-    case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
-      return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
-      return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
-      break;
-    case SSL_DH_anon_WITH_RC4_128_MD5:
-      return "SSL_DH_anon_WITH_RC4_128_MD5";
-      break;
-    case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
-      return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
-      break;
-    case SSL_DH_anon_WITH_DES_CBC_SHA:
-      return "SSL_DH_anon_WITH_DES_CBC_SHA";
-      break;
-    case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
-      return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
-      return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
-      break;
-    case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
-      return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
-      break;
-    /* TLS 1.0 with AES (RFC 3268)
-       (Apparently these are used in SSLv3 implementations as well.) */
-    case TLS_RSA_WITH_AES_128_CBC_SHA:
-      return "TLS_RSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
-      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
-      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
-      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
-      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
-      return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_RSA_WITH_AES_256_CBC_SHA:
-      return "TLS_RSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
-      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
-      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
-      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
-      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
-      return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
-      break;
-    /* SSL version 2.0 */
-    case SSL_RSA_WITH_RC2_CBC_MD5:
-      return "SSL_RSA_WITH_RC2_CBC_MD5";
-      break;
-    case SSL_RSA_WITH_IDEA_CBC_MD5:
-      return "SSL_RSA_WITH_IDEA_CBC_MD5";
-      break;
-    case SSL_RSA_WITH_DES_CBC_MD5:
-      return "SSL_RSA_WITH_DES_CBC_MD5";
-      break;
-    case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
-      return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
-      break;
-  }
-  return "SSL_NULL_WITH_NULL_NULL";
-}
-
-CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
-  switch(cipher) {
-    /* TLS 1.0 with AES (RFC 3268) */
-    case TLS_RSA_WITH_AES_128_CBC_SHA:
-      return "TLS_RSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
-      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
-      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
-      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
-      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
-      return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_RSA_WITH_AES_256_CBC_SHA:
-      return "TLS_RSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
-      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
-      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
-      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
-      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
-      return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
-      break;
-#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
-    /* TLS 1.0 with ECDSA (RFC 4492) */
-    case TLS_ECDH_ECDSA_WITH_NULL_SHA:
-      return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
-      break;
-    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
-      return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
-      break;
-    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
-      return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
-      return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
-      return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
-      break;
-    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
-      return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
-      break;
-    case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
-      return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
-      return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_ECDH_RSA_WITH_NULL_SHA:
-      return "TLS_ECDH_RSA_WITH_NULL_SHA";
-      break;
-    case TLS_ECDH_RSA_WITH_RC4_128_SHA:
-      return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
-      break;
-    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
-      return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
-      return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_ECDHE_RSA_WITH_NULL_SHA:
-      return "TLS_ECDHE_RSA_WITH_NULL_SHA";
-      break;
-    case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
-      return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
-      break;
-    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
-      return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
-      return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_ECDH_anon_WITH_NULL_SHA:
-      return "TLS_ECDH_anon_WITH_NULL_SHA";
-      break;
-    case TLS_ECDH_anon_WITH_RC4_128_SHA:
-      return "TLS_ECDH_anon_WITH_RC4_128_SHA";
-      break;
-    case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
-      return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
-      return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
-      break;
-#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
-#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-    /* TLS 1.2 (RFC 5246) */
-    case TLS_RSA_WITH_NULL_MD5:
-      return "TLS_RSA_WITH_NULL_MD5";
-      break;
-    case TLS_RSA_WITH_NULL_SHA:
-      return "TLS_RSA_WITH_NULL_SHA";
-      break;
-    case TLS_RSA_WITH_RC4_128_MD5:
-      return "TLS_RSA_WITH_RC4_128_MD5";
-      break;
-    case TLS_RSA_WITH_RC4_128_SHA:
-      return "TLS_RSA_WITH_RC4_128_SHA";
-      break;
-    case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_RSA_WITH_NULL_SHA256:
-      return "TLS_RSA_WITH_NULL_SHA256";
-      break;
-    case TLS_RSA_WITH_AES_128_CBC_SHA256:
-      return "TLS_RSA_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_RSA_WITH_AES_256_CBC_SHA256:
-      return "TLS_RSA_WITH_AES_256_CBC_SHA256";
-      break;
-    case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
-      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
-      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
-      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
-      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
-      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
-      break;
-    case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
-      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
-      break;
-    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
-      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
-      break;
-    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
-      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
-      break;
-    case TLS_DH_anon_WITH_RC4_128_MD5:
-      return "TLS_DH_anon_WITH_RC4_128_MD5";
-      break;
-    case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
-      return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
-      return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
-      break;
-    /* TLS 1.2 with AES GCM (RFC 5288) */
-    case TLS_RSA_WITH_AES_128_GCM_SHA256:
-      return "TLS_RSA_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_RSA_WITH_AES_256_GCM_SHA384:
-      return "TLS_RSA_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
-      return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
-      return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
-      return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
-      return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
-      return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
-      return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
-      return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
-      return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
-      return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
-      return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
-      break;
-    /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
-    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
-      return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
-      return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
-      break;
-    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
-      return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
-      return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
-      break;
-    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
-      return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
-      return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
-      break;
-    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
-      return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
-      return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
-      break;
-    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
-      return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
-      return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
-      return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
-      return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
-      return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
-      return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
-      return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
-      return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
-      return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
-      break;
-#else
-    case SSL_RSA_WITH_NULL_MD5:
-      return "TLS_RSA_WITH_NULL_MD5";
-      break;
-    case SSL_RSA_WITH_NULL_SHA:
-      return "TLS_RSA_WITH_NULL_SHA";
-      break;
-    case SSL_RSA_WITH_RC4_128_MD5:
-      return "TLS_RSA_WITH_RC4_128_MD5";
-      break;
-    case SSL_RSA_WITH_RC4_128_SHA:
-      return "TLS_RSA_WITH_RC4_128_SHA";
-      break;
-    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case SSL_DH_anon_WITH_RC4_128_MD5:
-      return "TLS_DH_anon_WITH_RC4_128_MD5";
-      break;
-    case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
-      break;
-#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
-#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
-    /* TLS PSK (RFC 4279): */
-    case TLS_PSK_WITH_RC4_128_SHA:
-      return "TLS_PSK_WITH_RC4_128_SHA";
-      break;
-    case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_PSK_WITH_AES_128_CBC_SHA:
-      return "TLS_PSK_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_PSK_WITH_AES_256_CBC_SHA:
-      return "TLS_PSK_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_DHE_PSK_WITH_RC4_128_SHA:
-      return "TLS_DHE_PSK_WITH_RC4_128_SHA";
-      break;
-    case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
-      return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
-      return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
-      break;
-    case TLS_RSA_PSK_WITH_RC4_128_SHA:
-      return "TLS_RSA_PSK_WITH_RC4_128_SHA";
-      break;
-    case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
-      return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
-      break;
-    case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
-      return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
-      break;
-    case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
-      return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
-      break;
-    /* More TLS PSK (RFC 4785): */
-    case TLS_PSK_WITH_NULL_SHA:
-      return "TLS_PSK_WITH_NULL_SHA";
-      break;
-    case TLS_DHE_PSK_WITH_NULL_SHA:
-      return "TLS_DHE_PSK_WITH_NULL_SHA";
-      break;
-    case TLS_RSA_PSK_WITH_NULL_SHA:
-      return "TLS_RSA_PSK_WITH_NULL_SHA";
-      break;
-    /* Even more TLS PSK (RFC 5487): */
-    case TLS_PSK_WITH_AES_128_GCM_SHA256:
-      return "TLS_PSK_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_PSK_WITH_AES_256_GCM_SHA384:
-      return "TLS_PSK_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
-      return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
-      return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
-      return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
-      break;
-    case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
-      return "TLS_PSK_WITH_AES_256_GCM_SHA384";
-      break;
-    case TLS_PSK_WITH_AES_128_CBC_SHA256:
-      return "TLS_PSK_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_PSK_WITH_AES_256_CBC_SHA384:
-      return "TLS_PSK_WITH_AES_256_CBC_SHA384";
-      break;
-    case TLS_PSK_WITH_NULL_SHA256:
-      return "TLS_PSK_WITH_NULL_SHA256";
-      break;
-    case TLS_PSK_WITH_NULL_SHA384:
-      return "TLS_PSK_WITH_NULL_SHA384";
-      break;
-    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
-      return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
-      return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
-      break;
-    case TLS_DHE_PSK_WITH_NULL_SHA256:
-      return "TLS_DHE_PSK_WITH_NULL_SHA256";
-      break;
-    case TLS_DHE_PSK_WITH_NULL_SHA384:
-      return "TLS_RSA_PSK_WITH_NULL_SHA384";
-      break;
-    case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
-      return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
-      break;
-    case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
-      return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
-      break;
-    case TLS_RSA_PSK_WITH_NULL_SHA256:
-      return "TLS_RSA_PSK_WITH_NULL_SHA256";
-      break;
-    case TLS_RSA_PSK_WITH_NULL_SHA384:
-      return "TLS_RSA_PSK_WITH_NULL_SHA384";
-      break;
-#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
-  }
-  return "TLS_NULL_WITH_NULL_NULL";
-}
-
-#if CURL_BUILD_MAC
-CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
-{
-  int mib[2];
-  char *os_version;
-  size_t os_version_len;
-  char *os_version_major, *os_version_minor/*, *os_version_point*/;
-  char *tok_buf;
-
-  /* Get the Darwin kernel version from the kernel using sysctl(): */
-  mib[0] = CTL_KERN;
-  mib[1] = KERN_OSRELEASE;
-  if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
-    return;
-  os_version = malloc(os_version_len*sizeof(char));
-  if(!os_version)
-    return;
-  if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
-    free(os_version);
-    return;
-  }
-
-  /* Parse the version: */
-  os_version_major = strtok_r(os_version, ".", &tok_buf);
-  os_version_minor = strtok_r(NULL, ".", &tok_buf);
-  /*os_version_point = strtok_r(NULL, ".", &tok_buf);*/
-  *major = atoi(os_version_major);
-  *minor = atoi(os_version_minor);
-  free(os_version);
-}
-#endif /* CURL_BUILD_MAC */
-
-/* Apple provides a myriad of ways of getting information about a certificate
-   into a string. Some aren't available under iOS or newer cats. So here's
-   a unified function for getting a string describing the certificate that
-   ought to work in all cats starting with Leopard. */
-CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
-{
-  CFStringRef server_cert_summary = CFSTR("(null)");
-
-#if CURL_BUILD_IOS
-  /* iOS: There's only one way to do this. */
-  server_cert_summary = SecCertificateCopySubjectSummary(cert);
-#else
-#if CURL_BUILD_MAC_10_7
-  /* Lion & later: Get the long description if we can. */
-  if(SecCertificateCopyLongDescription != NULL)
-    server_cert_summary =
-      SecCertificateCopyLongDescription(NULL, cert, NULL);
-  else
-#endif /* CURL_BUILD_MAC_10_7 */
-#if CURL_BUILD_MAC_10_6
-  /* Snow Leopard: Get the certificate summary. */
-  if(SecCertificateCopySubjectSummary != NULL)
-    server_cert_summary = SecCertificateCopySubjectSummary(cert);
-  else
-#endif /* CURL_BUILD_MAC_10_6 */
-  /* Leopard is as far back as we go... */
-  (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
-#endif /* CURL_BUILD_IOS */
-  return server_cert_summary;
-}
-
-#if CURL_SUPPORT_MAC_10_6
-/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
-   deprecation warnings, so let's not compile this unless it's necessary: */
-static OSStatus CopyIdentityWithLabelOldSchool(char *label,
-                                               SecIdentityRef *out_c_a_k)
-{
-  OSStatus status = errSecItemNotFound;
-  SecKeychainAttributeList attr_list;
-  SecKeychainAttribute attr;
-  SecKeychainSearchRef search = NULL;
-  SecCertificateRef cert = NULL;
-
-  /* Set up the attribute list: */
-  attr_list.count = 1L;
-  attr_list.attr = &attr;
-
-  /* Set up our lone search criterion: */
-  attr.tag = kSecLabelItemAttr;
-  attr.data = label;
-  attr.length = (UInt32)strlen(label);
-
-  /* Start searching: */
-  status = SecKeychainSearchCreateFromAttributes(NULL,
-                                                 kSecCertificateItemClass,
-                                                 &attr_list,
-                                                 &search);
-  if(status == noErr) {
-    status = SecKeychainSearchCopyNext(search,
-                                       (SecKeychainItemRef *)&cert);
-    if(status == noErr && cert) {
-      /* If we found a certificate, does it have a private key? */
-      status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
-      CFRelease(cert);
-    }
-  }
-
-  if(search)
-    CFRelease(search);
-  return status;
-}
-#endif /* CURL_SUPPORT_MAC_10_6 */
-
-static OSStatus CopyIdentityWithLabel(char *label,
-                                      SecIdentityRef *out_cert_and_key)
-{
-  OSStatus status = errSecItemNotFound;
-
-#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
-  /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
-     kSecClassIdentity was introduced in Lion. If both exist, let's use them
-     to find the certificate. */
-  if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
-    CFTypeRef keys[4];
-    CFTypeRef values[4];
-    CFDictionaryRef query_dict;
-    CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
-      kCFStringEncodingUTF8);
-
-    /* Set up our search criteria and expected results: */
-    values[0] = kSecClassIdentity; /* we want a certificate and a key */
-    keys[0] = kSecClass;
-    values[1] = kCFBooleanTrue;    /* we want a reference */
-    keys[1] = kSecReturnRef;
-    values[2] = kSecMatchLimitOne; /* one is enough, thanks */
-    keys[2] = kSecMatchLimit;
-    /* identity searches need a SecPolicyRef in order to work */
-    values[3] = SecPolicyCreateSSL(false, label_cf);
-    keys[3] = kSecMatchPolicy;
-    query_dict = CFDictionaryCreate(NULL, (const void **)keys,
-                                   (const void **)values, 4L,
-                                   &kCFCopyStringDictionaryKeyCallBacks,
-                                   &kCFTypeDictionaryValueCallBacks);
-    CFRelease(values[3]);
-    CFRelease(label_cf);
-
-    /* Do we have a match? */
-    status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
-    CFRelease(query_dict);
-  }
-  else {
-#if CURL_SUPPORT_MAC_10_6
-    /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
-    status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
-#endif /* CURL_SUPPORT_MAC_10_7 */
-  }
-#elif CURL_SUPPORT_MAC_10_6
-  /* For developers building on older cats, we have no choice but to fall back
-     to SecKeychainSearch. */
-  status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
-#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
-  return status;
-}
-
-static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
-                                           const char *cPassword,
-                                           SecIdentityRef *out_cert_and_key)
-{
-  OSStatus status = errSecItemNotFound;
-  CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
-    (const UInt8 *)cPath, strlen(cPath), false);
-  CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
-    cPassword, kCFStringEncodingUTF8) : NULL;
-  CFDataRef pkcs_data = NULL;
-
-  /* We can import P12 files on iOS or OS X 10.7 or later: */
-  /* These constants are documented as having first appeared in 10.6 but they
-     raise linker errors when used on that cat for some reason. */
-#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
-  if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
-    NULL, NULL, &status)) {
-    const void *cKeys[] = {kSecImportExportPassphrase};
-    const void *cValues[] = {password};
-    CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
-      password ? 1L : 0L, NULL, NULL);
-    CFArrayRef items = NULL;
-
-    /* Here we go: */
-    status = SecPKCS12Import(pkcs_data, options, &items);
-    if(status == noErr && items && CFArrayGetCount(items)) {
-      CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
-      const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
-        kSecImportItemIdentity);
-
-      /* Retain the identity; we don't care about any other data... */
-      CFRetain(temp_identity);
-      *out_cert_and_key = (SecIdentityRef)temp_identity;
-    }
-
-    if(items)
-      CFRelease(items);
-    CFRelease(options);
-    CFRelease(pkcs_data);
-  }
-#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
-  if(password)
-    CFRelease(password);
-  CFRelease(pkcs_url);
-  return status;
-}
-
-/* This code was borrowed from nss.c, with some modifications:
- * Determine whether the nickname passed in is a filename that needs to
- * be loaded as a PEM or a regular NSS nickname.
- *
- * returns 1 for a file
- * returns 0 for not a file
- */
-CF_INLINE bool is_file(const char *filename)
-{
-  struct_stat st;
-
-  if(filename == NULL)
-    return false;
-
-  if(stat(filename, &st) == 0)
-    return S_ISREG(st.st_mode);
-  return false;
-}
-
-static CURLcode darwinssl_connect_step1(struct connectdata *conn,
-                                        int sockindex)
-{
-  struct SessionHandle *data = conn->data;
-  curl_socket_t sockfd = conn->sock[sockindex];
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-#ifdef ENABLE_IPV6
-  struct in6_addr addr;
-#else
-  struct in_addr addr;
-#endif /* ENABLE_IPV6 */
-  size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
-  SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
-  char *ssl_sessionid;
-  size_t ssl_sessionid_len;
-  OSStatus err = noErr;
-#if CURL_BUILD_MAC
-  int darwinver_maj = 0, darwinver_min = 0;
-
-  GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
-#endif /* CURL_BUILD_MAC */
-
-#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-  if(SSLCreateContext != NULL) {  /* use the newer API if avaialble */
-    if(connssl->ssl_ctx)
-      CFRelease(connssl->ssl_ctx);
-    connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
-    if(!connssl->ssl_ctx) {
-      failf(data, "SSL: couldn't create a context!");
-      return CURLE_OUT_OF_MEMORY;
-    }
-  }
-  else {
-  /* The old ST API does not exist under iOS, so don't compile it: */
-#if CURL_SUPPORT_MAC_10_8
-    if(connssl->ssl_ctx)
-      (void)SSLDisposeContext(connssl->ssl_ctx);
-    err = SSLNewContext(false, &(connssl->ssl_ctx));
-    if(err != noErr) {
-      failf(data, "SSL: couldn't create a context: OSStatus %d", err);
-      return CURLE_OUT_OF_MEMORY;
-    }
-#endif /* CURL_SUPPORT_MAC_10_8 */
-  }
-#else
-  if(connssl->ssl_ctx)
-    (void)SSLDisposeContext(connssl->ssl_ctx);
-  err = SSLNewContext(false, &(connssl->ssl_ctx));
-  if(err != noErr) {
-    failf(data, "SSL: couldn't create a context: OSStatus %d", err);
-    return CURLE_OUT_OF_MEMORY;
-  }
-#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
-  connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
-
-  /* check to see if we've been told to use an explicit SSL/TLS version */
-#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-  if(SSLSetProtocolVersionMax != NULL) {
-    switch(data->set.ssl.version) {
-      case CURL_SSLVERSION_DEFAULT: default:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
-        break;
-      case CURL_SSLVERSION_TLSv1:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
-        break;
-      case CURL_SSLVERSION_TLSv1_0:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
-        break;
-      case CURL_SSLVERSION_TLSv1_1:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
-        break;
-      case CURL_SSLVERSION_TLSv1_2:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
-        break;
-      case CURL_SSLVERSION_SSLv3:
-        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
-        break;
-      case CURL_SSLVERSION_SSLv2:
-        err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
-        if(err != noErr) {
-          failf(data, "Your version of the OS does not support SSLv2");
-          return CURLE_SSL_CONNECT_ERROR;
-        }
-        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
-    }
-  }
-  else {
-#if CURL_SUPPORT_MAC_10_8
-    (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                       kSSLProtocolAll,
-                                       false);
-    switch (data->set.ssl.version) {
-      case CURL_SSLVERSION_DEFAULT: default:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kSSLProtocol3,
-                                           true);
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol1,
-                                           true);
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol11,
-                                           true);
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol12,
-                                           true);
-        break;
-      case CURL_SSLVERSION_TLSv1:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol1,
-                                           true);
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol11,
-                                           true);
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol12,
-                                           true);
-        break;
-      case CURL_SSLVERSION_TLSv1_0:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol1,
-                                           true);
-        break;
-      case CURL_SSLVERSION_TLSv1_1:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol11,
-                                           true);
-        break;
-      case CURL_SSLVERSION_TLSv1_2:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kTLSProtocol12,
-                                           true);
-        break;
-      case CURL_SSLVERSION_SSLv3:
-        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kSSLProtocol3,
-                                           true);
-        break;
-      case CURL_SSLVERSION_SSLv2:
-        err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                           kSSLProtocol2,
-                                           true);
-        if(err != noErr) {
-          failf(data, "Your version of the OS does not support SSLv2");
-          return CURLE_SSL_CONNECT_ERROR;
-        }
-        break;
-    }
-#endif  /* CURL_SUPPORT_MAC_10_8 */
-  }
-#else
-  (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
-  switch(data->set.ssl.version) {
-    default:
-    case CURL_SSLVERSION_DEFAULT:
-      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                         kSSLProtocol3,
-                                         true);
-      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                         kTLSProtocol1,
-                                         true);
-      break;
-    case CURL_SSLVERSION_TLSv1:
-    case CURL_SSLVERSION_TLSv1_0:
-      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                         kTLSProtocol1,
-                                         true);
-      break;
-    case CURL_SSLVERSION_TLSv1_1:
-      failf(data, "Your version of the OS does not support TLSv1.1");
-      return CURLE_SSL_CONNECT_ERROR;
-    case CURL_SSLVERSION_TLSv1_2:
-      failf(data, "Your version of the OS does not support TLSv1.2");
-      return CURLE_SSL_CONNECT_ERROR;
-    case CURL_SSLVERSION_SSLv2:
-      err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                         kSSLProtocol2,
-                                         true);
-      if(err != noErr) {
-        failf(data, "Your version of the OS does not support SSLv2");
-        return CURLE_SSL_CONNECT_ERROR;
-      }
-      break;
-    case CURL_SSLVERSION_SSLv3:
-      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
-                                         kSSLProtocol3,
-                                         true);
-      break;
-  }
-#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
-
-  if(data->set.str[STRING_KEY]) {
-    infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
-                "Transport. The private key must be in the Keychain.\n");
-  }
-
-  if(data->set.str[STRING_CERT]) {
-    SecIdentityRef cert_and_key = NULL;
-    bool is_cert_file = is_file(data->set.str[STRING_CERT]);
-
-    /* User wants to authenticate with a client cert. Look for it:
-       If we detect that this is a file on disk, then let's load it.
-       Otherwise, assume that the user wants to use an identity loaded
-       from the Keychain. */
-    if(is_cert_file) {
-      if(!data->set.str[STRING_CERT_TYPE])
-        infof(data, "WARNING: SSL: Certificate type not set, assuming "
-                    "PKCS#12 format.\n");
-      else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
-        strlen(data->set.str[STRING_CERT_TYPE])) != 0)
-        infof(data, "WARNING: SSL: The Security framework only supports "
-                    "loading identities that are in PKCS#12 format.\n");
-
-      err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
-        data->set.str[STRING_KEY_PASSWD], &cert_and_key);
-    }
-    else
-      err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
-
-    if(err == noErr) {
-      SecCertificateRef cert = NULL;
-      CFTypeRef certs_c[1];
-      CFArrayRef certs;
-
-      /* If we found one, print it out: */
-      err = SecIdentityCopyCertificate(cert_and_key, &cert);
-      if(err == noErr) {
-        CFStringRef cert_summary = CopyCertSubject(cert);
-        char cert_summary_c[128];
-
-        if(cert_summary) {
-          memset(cert_summary_c, 0, 128);
-          if(CFStringGetCString(cert_summary,
-                                cert_summary_c,
-                                128,
-                                kCFStringEncodingUTF8)) {
-            infof(data, "Client certificate: %s\n", cert_summary_c);
-          }
-          CFRelease(cert_summary);
-          CFRelease(cert);
-        }
-      }
-      certs_c[0] = cert_and_key;
-      certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
-                            &kCFTypeArrayCallBacks);
-      err = SSLSetCertificate(connssl->ssl_ctx, certs);
-      if(certs)
-        CFRelease(certs);
-      if(err != noErr) {
-        failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
-        return CURLE_SSL_CERTPROBLEM;
-      }
-      CFRelease(cert_and_key);
-    }
-    else {
-      switch(err) {
-        case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
-          failf(data, "SSL: Incorrect password for the certificate \"%s\" "
-                      "and its private key.", data->set.str[STRING_CERT]);
-          break;
-        case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
-          failf(data, "SSL: Couldn't make sense of the data in the "
-                      "certificate \"%s\" and its private key.",
-                      data->set.str[STRING_CERT]);
-          break;
-        case -25260: /* errSecPassphraseRequired */
-          failf(data, "SSL The certificate \"%s\" requires a password.",
-                      data->set.str[STRING_CERT]);
-          break;
-        case errSecItemNotFound:
-          failf(data, "SSL: Can't find the certificate \"%s\" and its private "
-                      "key in the Keychain.", data->set.str[STRING_CERT]);
-          break;
-        default:
-          failf(data, "SSL: Can't load the certificate \"%s\" and its private "
-                      "key: OSStatus %d", data->set.str[STRING_CERT], err);
-          break;
-      }
-      return CURLE_SSL_CERTPROBLEM;
-    }
-  }
-
-  /* SSL always tries to verify the peer, this only says whether it should
-   * fail to connect if the verification fails, or if it should continue
-   * anyway. In the latter case the result of the verification is checked with
-   * SSL_get_verify_result() below. */
-#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
-  /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
-     a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
-     works, it doesn't work as expected under Snow Leopard or Lion.
-     So we need to call SSLSetEnableCertVerify() on those older cats in order
-     to disable certificate validation if the user turned that off.
-     (SecureTransport will always validate the certificate chain by
-     default.) */
-  /* (Note: Darwin 12.x.x is Mountain Lion.) */
-#if CURL_BUILD_MAC
-  if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
-#else
-  if(SSLSetSessionOption != NULL) {
-#endif /* CURL_BUILD_MAC */
-    bool break_on_auth = !data->set.ssl.verifypeer ||
-      data->set.str[STRING_SSL_CAFILE];
-    err = SSLSetSessionOption(connssl->ssl_ctx,
-                              kSSLSessionOptionBreakOnServerAuth,
-                              break_on_auth);
-    if(err != noErr) {
-      failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-  }
-  else {
-#if CURL_SUPPORT_MAC_10_8
-    err = SSLSetEnableCertVerify(connssl->ssl_ctx,
-                                 data->set.ssl.verifypeer?true:false);
-    if(err != noErr) {
-      failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-#endif /* CURL_SUPPORT_MAC_10_8 */
-  }
-#else
-  err = SSLSetEnableCertVerify(connssl->ssl_ctx,
-                               data->set.ssl.verifypeer?true:false);
-  if(err != noErr) {
-    failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
-
-  if(data->set.str[STRING_SSL_CAFILE]) {
-    bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
-
-    if(!is_cert_file) {
-      failf(data, "SSL: can't load CA certificate file %s",
-            data->set.str[STRING_SSL_CAFILE]);
-      return CURLE_SSL_CACERT_BADFILE;
-    }
-    if(!data->set.ssl.verifypeer) {
-      failf(data, "SSL: CA certificate set, but certificate verification "
-            "is disabled");
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-  }
-
-  /* Configure hostname check. SNI is used if available.
-   * Both hostname check and SNI require SSLSetPeerDomainName().
-   * Also: the verifyhost setting influences SNI usage */
-  if(data->set.ssl.verifyhost) {
-    err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
-    strlen(conn->host.name));
-
-    if(err != noErr) {
-      infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
-            err);
-    }
-
-    if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
-  #ifdef ENABLE_IPV6
-    || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
-  #endif
-       ) {
-         infof(data, "WARNING: using IP address, SNI is being disabled by "
-         "the OS.\n");
-    }
-  }
-
-  /* Disable cipher suites that ST supports but are not safe. These ciphers
-     are unlikely to be used in any case since ST gives other ciphers a much
-     higher priority, but it's probably better that we not connect at all than
-     to give the user a false sense of security if the server only supports
-     insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
-  (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
-  all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
-  allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
-  if(all_ciphers && allowed_ciphers &&
-     SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
-       &all_ciphers_count) == noErr) {
-    for(i = 0UL ; i < all_ciphers_count ; i++) {
-#if CURL_BUILD_MAC
-     /* There's a known bug in early versions of Mountain Lion where ST's ECC
-        ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
-        Work around the problem here by disabling those ciphers if we are
-        running in an affected version of OS X. */
-      if(darwinver_maj == 12 && darwinver_min <= 3 &&
-         all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
-           continue;
-      }
-#endif /* CURL_BUILD_MAC */
-      switch(all_ciphers[i]) {
-        /* Disable NULL ciphersuites: */
-        case SSL_NULL_WITH_NULL_NULL:
-        case SSL_RSA_WITH_NULL_MD5:
-        case SSL_RSA_WITH_NULL_SHA:
-        case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
-        case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
-        case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
-        case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
-        case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
-        case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
-        case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
-        case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
-        case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
-        case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
-        case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
-        case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
-        case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
-        case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
-        case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
-        /* Disable anonymous ciphersuites: */
-        case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
-        case SSL_DH_anon_WITH_RC4_128_MD5:
-        case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DH_anon_WITH_DES_CBC_SHA:
-        case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
-        case TLS_DH_anon_WITH_AES_128_CBC_SHA:
-        case TLS_DH_anon_WITH_AES_256_CBC_SHA:
-        case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
-        case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
-        case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
-        case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
-        case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
-        case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
-        case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
-        case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
-        case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
-        /* Disable weak key ciphersuites: */
-        case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
-        case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
-        case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
-        case SSL_RSA_WITH_DES_CBC_SHA:
-        case SSL_DH_DSS_WITH_DES_CBC_SHA:
-        case SSL_DH_RSA_WITH_DES_CBC_SHA:
-        case SSL_DHE_DSS_WITH_DES_CBC_SHA:
-        case SSL_DHE_RSA_WITH_DES_CBC_SHA:
-        /* Disable IDEA: */
-        case SSL_RSA_WITH_IDEA_CBC_SHA:
-        case SSL_RSA_WITH_IDEA_CBC_MD5:
-          break;
-        default: /* enable everything else */
-          allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
-          break;
-      }
-    }
-    err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
-                               allowed_ciphers_count);
-    if(err != noErr) {
-      failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-  }
-  else {
-    Curl_safefree(all_ciphers);
-    Curl_safefree(allowed_ciphers);
-    failf(data, "SSL: Failed to allocate memory for allowed ciphers");
-    return CURLE_OUT_OF_MEMORY;
-  }
-  Curl_safefree(all_ciphers);
-  Curl_safefree(allowed_ciphers);
-
-#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
-  /* We want to enable 1/n-1 when using a CBC cipher unless the user
-     specifically doesn't want us doing that: */
-  if(SSLSetSessionOption != NULL)
-    SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
-                      !data->set.ssl_enable_beast);
-#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
-
-  /* Check if there's a cached ID we can/should use here! */
-  if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
-    &ssl_sessionid_len)) {
-    /* we got a session id, use it! */
-    err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
-    if(err != noErr) {
-      failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-    /* Informational message */
-    infof(data, "SSL re-using session ID\n");
-  }
-  /* If there isn't one, then let's make one up! This has to be done prior
-     to starting the handshake. */
-  else {
-    CURLcode retcode;
-
-    ssl_sessionid = malloc(256*sizeof(char));
-    ssl_sessionid_len = snprintf(ssl_sessionid, 256, "curl:%s:%hu",
-      conn->host.name, conn->remote_port);
-    err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
-    if(err != noErr) {
-      failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-    retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
-    if(retcode!= CURLE_OK) {
-      failf(data, "failed to store ssl session");
-      return retcode;
-    }
-  }
-
-  err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
-  if(err != noErr) {
-    failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  /* pass the raw socket into the SSL layers */
-  /* We need to store the FD in a constant memory address, because
-   * SSLSetConnection() will not copy that address. I've found that
-   * conn->sock[sockindex] may change on its own. */
-  connssl->ssl_sockfd = sockfd;
-  err = SSLSetConnection(connssl->ssl_ctx, connssl);
-  if(err != noErr) {
-    failf(data, "SSL: SSLSetConnection() failed: %d", err);
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  connssl->connecting_state = ssl_connect_2;
-  return CURLE_OK;
-}
-
-static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
-{
-  char *sep_start, *sep_end, *cert_start, *cert_end;
-  size_t i, j, err;
-  size_t len;
-  unsigned char *b64;
-
-  /* Jump through the separators at the beginning of the certificate. */
-  sep_start = strstr(in, "-----");
-  if(sep_start == NULL)
-    return 0;
-  cert_start = strstr(sep_start + 1, "-----");
-  if(cert_start == NULL)
-    return -1;
-
-  cert_start += 5;
-
-  /* Find separator after the end of the certificate. */
-  cert_end = strstr(cert_start, "-----");
-  if(cert_end == NULL)
-    return -1;
-
-  sep_end = strstr(cert_end + 1, "-----");
-  if(sep_end == NULL)
-    return -1;
-  sep_end += 5;
-
-  len = cert_end - cert_start;
-  b64 = malloc(len + 1);
-  if(!b64)
-    return -1;
-
-  /* Create base64 string without linefeeds. */
-  for(i = 0, j = 0; i < len; i++) {
-    if(cert_start[i] != '\r' && cert_start[i] != '\n')
-      b64[j++] = cert_start[i];
-  }
-  b64[j] = '\0';
-
-  err = Curl_base64_decode((const char *)b64, out, outlen);
-  free(b64);
-  if(err) {
-    free(*out);
-    return -1;
-  }
-
-  return sep_end - in;
-}
-
-static int read_cert(const char *file, unsigned char **out, size_t *outlen)
-{
-  int fd;
-  ssize_t n, len = 0, cap = 512;
-  unsigned char buf[cap], *data;
-
-  fd = open(file, 0);
-  if(fd < 0)
-    return -1;
-
-  data = malloc(cap);
-  if(!data) {
-    close(fd);
-    return -1;
-  }
-
-  for(;;) {
-    n = read(fd, buf, sizeof(buf));
-    if(n < 0) {
-      close(fd);
-      free(data);
-      return -1;
-    }
-    else if(n == 0) {
-      close(fd);
-      break;
-    }
-
-    if(len + n >= cap) {
-      cap *= 2;
-      data = realloc(data, cap);
-      if(!data) {
-        close(fd);
-        return -1;
-      }
-    }
-
-    memcpy(data + len, buf, n);
-    len += n;
-  }
-  data[len] = '\0';
-
-  *out = data;
-  *outlen = len;
-
-  return 0;
-}
-
-static int sslerr_to_curlerr(struct SessionHandle *data, int err)
-{
-  switch(err) {
-    case errSSLXCertChainInvalid:
-      failf(data, "SSL certificate problem: Invalid certificate chain");
-      return CURLE_SSL_CACERT;
-    case errSSLUnknownRootCert:
-      failf(data, "SSL certificate problem: Untrusted root certificate");
-      return CURLE_SSL_CACERT;
-    case errSSLNoRootCert:
-      failf(data, "SSL certificate problem: No root certificate");
-      return CURLE_SSL_CACERT;
-    case errSSLCertExpired:
-      failf(data, "SSL certificate problem: Certificate chain had an "
-            "expired certificate");
-      return CURLE_SSL_CACERT;
-    case errSSLBadCert:
-      failf(data, "SSL certificate problem: Couldn't understand the server "
-            "certificate format");
-      return CURLE_SSL_CONNECT_ERROR;
-    case errSSLHostNameMismatch:
-      failf(data, "SSL certificate peer hostname mismatch");
-      return CURLE_PEER_FAILED_VERIFICATION;
-    default:
-      failf(data, "SSL unexpected certificate error %d", err);
-      return CURLE_SSL_CACERT;
-  }
-}
-
-static int append_cert_to_array(struct SessionHandle *data,
-                                unsigned char *buf, size_t buflen,
-                                CFMutableArrayRef array)
-{
-    CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
-    if(!certdata) {
-      failf(data, "SSL: failed to allocate array for CA certificate");
-      return CURLE_OUT_OF_MEMORY;
-    }
-
-    SecCertificateRef cacert =
-      SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
-    CFRelease(certdata);
-    if(!cacert) {
-      failf(data, "SSL: failed to create SecCertificate from CA certificate");
-      return CURLE_SSL_CACERT;
-    }
-
-    /* Check if cacert is valid. */
-    CFStringRef subject = CopyCertSubject(cacert);
-    if(subject) {
-      char subject_cbuf[128];
-      memset(subject_cbuf, 0, 128);
-      if(!CFStringGetCString(subject,
-                            subject_cbuf,
-                            128,
-                            kCFStringEncodingUTF8)) {
-        CFRelease(cacert);
-        failf(data, "SSL: invalid CA certificate subject");
-        return CURLE_SSL_CACERT;
-      }
-      CFRelease(subject);
-    }
-    else {
-      CFRelease(cacert);
-      failf(data, "SSL: invalid CA certificate");
-      return CURLE_SSL_CACERT;
-    }
-
-    CFArrayAppendValue(array, cacert);
-    CFRelease(cacert);
-
-    return CURLE_OK;
-}
-
-static int verify_cert(const char *cafile, struct SessionHandle *data,
-                       SSLContextRef ctx)
-{
-  int n = 0, rc;
-  long res;
-  unsigned char *certbuf, *der;
-  size_t buflen, derlen, offset = 0;
-
-  if(read_cert(cafile, &certbuf, &buflen) < 0) {
-    failf(data, "SSL: failed to read or invalid CA certificate");
-    return CURLE_SSL_CACERT;
-  }
-
-  /*
-   * Certbuf now contains the contents of the certificate file, which can be
-   * - a single DER certificate,
-   * - a single PEM certificate or
-   * - a bunch of PEM certificates (certificate bundle).
-   *
-   * Go through certbuf, and convert any PEM certificate in it into DER
-   * format.
-   */
-  CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
-                                                 &kCFTypeArrayCallBacks);
-  if(array == NULL) {
-    free(certbuf);
-    failf(data, "SSL: out of memory creating CA certificate array");
-    return CURLE_OUT_OF_MEMORY;
-  }
-
-  while(offset < buflen) {
-    n++;
-
-    /*
-     * Check if the certificate is in PEM format, and convert it to DER. If
-     * this fails, we assume the certificate is in DER format.
-     */
-    res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
-    if(res < 0) {
-      free(certbuf);
-      CFRelease(array);
-      failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
-            n, offset);
-      return CURLE_SSL_CACERT;
-    }
-    offset += res;
-
-    if(res == 0 && offset == 0) {
-      /* This is not a PEM file, probably a certificate in DER format. */
-      rc = append_cert_to_array(data, certbuf, buflen, array);
-      free(certbuf);
-      if(rc != CURLE_OK) {
-        CFRelease(array);
-        return rc;
-      }
-      break;
-    }
-    else if(res == 0) {
-      /* No more certificates in the bundle. */
-      free(certbuf);
-      break;
-    }
-
-    rc = append_cert_to_array(data, der, derlen, array);
-    free(der);
-    if(rc != CURLE_OK) {
-      free(certbuf);
-      CFRelease(array);
-      return rc;
-    }
-  }
-
-  SecTrustRef trust;
-  OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
-  if(trust == NULL) {
-    failf(data, "SSL: error getting certificate chain");
-    CFRelease(array);
-    return CURLE_OUT_OF_MEMORY;
-  }
-  else if(ret != noErr) {
-    CFRelease(array);
-    return sslerr_to_curlerr(data, ret);
-  }
-
-  ret = SecTrustSetAnchorCertificates(trust, array);
-  if(ret != noErr) {
-    CFRelease(trust);
-    return sslerr_to_curlerr(data, ret);
-  }
-  ret = SecTrustSetAnchorCertificatesOnly(trust, true);
-  if(ret != noErr) {
-    CFRelease(trust);
-    return sslerr_to_curlerr(data, ret);
-  }
-
-  SecTrustResultType trust_eval = 0;
-  ret = SecTrustEvaluate(trust, &trust_eval);
-  CFRelease(array);
-  CFRelease(trust);
-  if(ret != noErr) {
-    return sslerr_to_curlerr(data, ret);
-  }
-
-  switch (trust_eval) {
-    case kSecTrustResultUnspecified:
-    case kSecTrustResultProceed:
-      return CURLE_OK;
-
-    case kSecTrustResultRecoverableTrustFailure:
-    case kSecTrustResultDeny:
-    default:
-      failf(data, "SSL: certificate verification failed (result: %d)",
-            trust_eval);
-      return CURLE_PEER_FAILED_VERIFICATION;
-  }
-}
-
-static CURLcode
-darwinssl_connect_step2(struct connectdata *conn, int sockindex)
-{
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  OSStatus err;
-  SSLCipherSuite cipher;
-  SSLProtocol protocol = 0;
-
-  DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
-              || ssl_connect_2_reading == connssl->connecting_state
-              || ssl_connect_2_writing == connssl->connecting_state);
-
-  /* Here goes nothing: */
-  err = SSLHandshake(connssl->ssl_ctx);
-
-  if(err != noErr) {
-    switch (err) {
-      case errSSLWouldBlock:  /* they're not done with us yet */
-        connssl->connecting_state = connssl->ssl_direction ?
-            ssl_connect_2_writing : ssl_connect_2_reading;
-        return CURLE_OK;
-
-      /* The below is errSSLServerAuthCompleted; it's not defined in
-        Leopard's headers */
-      case -9841:
-        if(data->set.str[STRING_SSL_CAFILE]) {
-          int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
-                                connssl->ssl_ctx);
-          if(res != CURLE_OK)
-            return res;
-        }
-        /* the documentation says we need to call SSLHandshake() again */
-        return darwinssl_connect_step2(conn, sockindex);
-
-      /* These are all certificate problems with the server: */
-      case errSSLXCertChainInvalid:
-        failf(data, "SSL certificate problem: Invalid certificate chain");
-        return CURLE_SSL_CACERT;
-      case errSSLUnknownRootCert:
-        failf(data, "SSL certificate problem: Untrusted root certificate");
-        return CURLE_SSL_CACERT;
-      case errSSLNoRootCert:
-        failf(data, "SSL certificate problem: No root certificate");
-        return CURLE_SSL_CACERT;
-      case errSSLCertExpired:
-        failf(data, "SSL certificate problem: Certificate chain had an "
-              "expired certificate");
-        return CURLE_SSL_CACERT;
-      case errSSLBadCert:
-        failf(data, "SSL certificate problem: Couldn't understand the server "
-              "certificate format");
-        return CURLE_SSL_CONNECT_ERROR;
-
-      /* These are all certificate problems with the client: */
-      case errSecAuthFailed:
-        failf(data, "SSL authentication failed");
-        return CURLE_SSL_CONNECT_ERROR;
-      case errSSLPeerHandshakeFail:
-        failf(data, "SSL peer handshake failed, the server most likely "
-              "requires a client certificate to connect");
-        return CURLE_SSL_CONNECT_ERROR;
-      case errSSLPeerUnknownCA:
-        failf(data, "SSL server rejected the client certificate due to "
-              "the certificate being signed by an unknown certificate "
-              "authority");
-        return CURLE_SSL_CONNECT_ERROR;
-
-      /* This error is raised if the server's cert didn't match the server's
-         host name: */
-      case errSSLHostNameMismatch:
-        failf(data, "SSL certificate peer verification failed, the "
-              "certificate did not match \"%s\"\n", conn->host.dispname);
-        return CURLE_PEER_FAILED_VERIFICATION;
-
-      /* Generic handshake errors: */
-      case errSSLConnectionRefused:
-        failf(data, "Server dropped the connection during the SSL handshake");
-        return CURLE_SSL_CONNECT_ERROR;
-      case errSSLClosedAbort:
-        failf(data, "Server aborted the SSL handshake");
-        return CURLE_SSL_CONNECT_ERROR;
-      case errSSLNegotiation:
-        failf(data, "Could not negotiate an SSL cipher suite with the server");
-        return CURLE_SSL_CONNECT_ERROR;
-      /* Sometimes paramErr happens with buggy ciphers: */
-      case paramErr: case errSSLInternal:
-        failf(data, "Internal SSL engine error encountered during the "
-              "SSL handshake");
-        return CURLE_SSL_CONNECT_ERROR;
-      case errSSLFatalAlert:
-        failf(data, "Fatal SSL engine error encountered during the SSL "
-              "handshake");
-        return CURLE_SSL_CONNECT_ERROR;
-      default:
-        failf(data, "Unknown SSL protocol error in connection to %s:%d",
-              conn->host.name, err);
-        return CURLE_SSL_CONNECT_ERROR;
-    }
-  }
-  else {
-    /* we have been connected fine, we're not waiting for anything else. */
-    connssl->connecting_state = ssl_connect_3;
-
-    /* Informational message */
-    (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
-    (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
-    switch (protocol) {
-      case kSSLProtocol2:
-        infof(data, "SSL 2.0 connection using %s\n",
-              SSLCipherNameForNumber(cipher));
-        break;
-      case kSSLProtocol3:
-        infof(data, "SSL 3.0 connection using %s\n",
-              SSLCipherNameForNumber(cipher));
-        break;
-      case kTLSProtocol1:
-        infof(data, "TLS 1.0 connection using %s\n",
-              TLSCipherNameForNumber(cipher));
-        break;
-#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-      case kTLSProtocol11:
-        infof(data, "TLS 1.1 connection using %s\n",
-              TLSCipherNameForNumber(cipher));
-        break;
-      case kTLSProtocol12:
-        infof(data, "TLS 1.2 connection using %s\n",
-              TLSCipherNameForNumber(cipher));
-        break;
-#endif
-      default:
-        infof(data, "Unknown protocol connection\n");
-        break;
-    }
-
-    return CURLE_OK;
-  }
-}
-
-static CURLcode
-darwinssl_connect_step3(struct connectdata *conn,
-                        int sockindex)
-{
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  CFStringRef server_cert_summary;
-  char server_cert_summary_c[128];
-  CFArrayRef server_certs = NULL;
-  SecCertificateRef server_cert;
-  OSStatus err;
-  CFIndex i, count;
-  SecTrustRef trust = NULL;
-
-  /* There is no step 3!
-   * Well, okay, if verbose mode is on, let's print the details of the
-   * server certificates. */
-#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
-#if CURL_BUILD_IOS
-#pragma unused(server_certs)
-  err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
-  /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
-     a null trust, so be on guard for that: */
-  if(err == noErr && trust) {
-    count = SecTrustGetCertificateCount(trust);
-    for(i = 0L ; i < count ; i++) {
-      server_cert = SecTrustGetCertificateAtIndex(trust, i);
-      server_cert_summary = CopyCertSubject(server_cert);
-      memset(server_cert_summary_c, 0, 128);
-      if(CFStringGetCString(server_cert_summary,
-                            server_cert_summary_c,
-                            128,
-                            kCFStringEncodingUTF8)) {
-        infof(data, "Server certificate: %s\n", server_cert_summary_c);
-      }
-      CFRelease(server_cert_summary);
-    }
-    CFRelease(trust);
-  }
-#else
-  /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
-     The function SecTrustGetCertificateAtIndex() is officially present
-     in Lion, but it is unfortunately also present in Snow Leopard as
-     private API and doesn't work as expected. So we have to look for
-     a different symbol to make sure this code is only executed under
-     Lion or later. */
-  if(SecTrustEvaluateAsync != NULL) {
-#pragma unused(server_certs)
-    err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
-    /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
-       a null trust, so be on guard for that: */
-    if(err == noErr && trust) {
-      count = SecTrustGetCertificateCount(trust);
-      for(i = 0L ; i < count ; i++) {
-        server_cert = SecTrustGetCertificateAtIndex(trust, i);
-        server_cert_summary = CopyCertSubject(server_cert);
-        memset(server_cert_summary_c, 0, 128);
-        if(CFStringGetCString(server_cert_summary,
-                              server_cert_summary_c,
-                              128,
-                              kCFStringEncodingUTF8)) {
-          infof(data, "Server certificate: %s\n", server_cert_summary_c);
-        }
-        CFRelease(server_cert_summary);
-      }
-      CFRelease(trust);
-    }
-  }
-  else {
-#if CURL_SUPPORT_MAC_10_8
-    err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
-    /* Just in case SSLCopyPeerCertificates() returns null too... */
-    if(err == noErr && server_certs) {
-      count = CFArrayGetCount(server_certs);
-      for(i = 0L ; i < count ; i++) {
-        server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
-                                                                i);
-
-        server_cert_summary = CopyCertSubject(server_cert);
-        memset(server_cert_summary_c, 0, 128);
-        if(CFStringGetCString(server_cert_summary,
-                              server_cert_summary_c,
-                              128,
-                              kCFStringEncodingUTF8)) {
-          infof(data, "Server certificate: %s\n", server_cert_summary_c);
-        }
-        CFRelease(server_cert_summary);
-      }
-      CFRelease(server_certs);
-    }
-#endif /* CURL_SUPPORT_MAC_10_8 */
-  }
-#endif /* CURL_BUILD_IOS */
-#else
-#pragma unused(trust)
-  err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
-  if(err == noErr) {
-    count = CFArrayGetCount(server_certs);
-    for(i = 0L ; i < count ; i++) {
-      server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
-      server_cert_summary = CopyCertSubject(server_cert);
-      memset(server_cert_summary_c, 0, 128);
-      if(CFStringGetCString(server_cert_summary,
-                            server_cert_summary_c,
-                            128,
-                            kCFStringEncodingUTF8)) {
-        infof(data, "Server certificate: %s\n", server_cert_summary_c);
-      }
-      CFRelease(server_cert_summary);
-    }
-    CFRelease(server_certs);
-  }
-#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
-
-  connssl->connecting_state = ssl_connect_done;
-  return CURLE_OK;
-}
-
-static Curl_recv darwinssl_recv;
-static Curl_send darwinssl_send;
-
-static CURLcode
-darwinssl_connect_common(struct connectdata *conn,
-                         int sockindex,
-                         bool nonblocking,
-                         bool *done)
-{
-  CURLcode retcode;
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  curl_socket_t sockfd = conn->sock[sockindex];
-  long timeout_ms;
-  int what;
-
-  /* check if the connection has already been established */
-  if(ssl_connection_complete == connssl->state) {
-    *done = TRUE;
-    return CURLE_OK;
-  }
-
-  if(ssl_connect_1==connssl->connecting_state) {
-    /* Find out how much more time we're allowed */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
-    if(timeout_ms < 0) {
-      /* no need to continue if time already is up */
-      failf(data, "SSL connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-    retcode = darwinssl_connect_step1(conn, sockindex);
-    if(retcode)
-      return retcode;
-  }
-
-  while(ssl_connect_2 == connssl->connecting_state ||
-        ssl_connect_2_reading == connssl->connecting_state ||
-        ssl_connect_2_writing == connssl->connecting_state) {
-
-    /* check allowed time left */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
-    if(timeout_ms < 0) {
-      /* no need to continue if time already is up */
-      failf(data, "SSL connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-
-    /* if ssl is expecting something, check if it's available. */
-    if(connssl->connecting_state == ssl_connect_2_reading
-       || connssl->connecting_state == ssl_connect_2_writing) {
-
-      curl_socket_t writefd = ssl_connect_2_writing ==
-      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
-      curl_socket_t readfd = ssl_connect_2_reading ==
-      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
-
-      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
-      if(what < 0) {
-        /* fatal error */
-        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
-        return CURLE_SSL_CONNECT_ERROR;
-      }
-      else if(0 == what) {
-        if(nonblocking) {
-          *done = FALSE;
-          return CURLE_OK;
-        }
-        else {
-          /* timeout */
-          failf(data, "SSL connection timeout");
-          return CURLE_OPERATION_TIMEDOUT;
-        }
-      }
-      /* socket is readable or writable */
-    }
-
-    /* Run transaction, and return to the caller if it failed or if this
-     * connection is done nonblocking and this loop would execute again. This
-     * permits the owner of a multi handle to abort a connection attempt
-     * before step2 has completed while ensuring that a client using select()
-     * or epoll() will always have a valid fdset to wait on.
-     */
-    retcode = darwinssl_connect_step2(conn, sockindex);
-    if(retcode || (nonblocking &&
-                   (ssl_connect_2 == connssl->connecting_state ||
-                    ssl_connect_2_reading == connssl->connecting_state ||
-                    ssl_connect_2_writing == connssl->connecting_state)))
-      return retcode;
-
-  } /* repeat step2 until all transactions are done. */
-
-
-  if(ssl_connect_3==connssl->connecting_state) {
-    retcode = darwinssl_connect_step3(conn, sockindex);
-    if(retcode)
-      return retcode;
-  }
-
-  if(ssl_connect_done==connssl->connecting_state) {
-    connssl->state = ssl_connection_complete;
-    conn->recv[sockindex] = darwinssl_recv;
-    conn->send[sockindex] = darwinssl_send;
-    *done = TRUE;
-  }
-  else
-    *done = FALSE;
-
-  /* Reset our connect state machine */
-  connssl->connecting_state = ssl_connect_1;
-
-  return CURLE_OK;
-}
-
-CURLcode
-Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
-                                   int sockindex,
-                                   bool *done)
-{
-  return darwinssl_connect_common(conn, sockindex, TRUE, done);
-}
-
-CURLcode
-Curl_darwinssl_connect(struct connectdata *conn,
-                       int sockindex)
-{
-  CURLcode retcode;
-  bool done = FALSE;
-
-  retcode = darwinssl_connect_common(conn, sockindex, FALSE, &done);
-
-  if(retcode)
-    return retcode;
-
-  DEBUGASSERT(done);
-
-  return CURLE_OK;
-}
-
-void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
-{
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
-  if(connssl->ssl_ctx) {
-    (void)SSLClose(connssl->ssl_ctx);
-#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-    if(SSLCreateContext != NULL)
-      CFRelease(connssl->ssl_ctx);
-#if CURL_SUPPORT_MAC_10_8
-    else
-      (void)SSLDisposeContext(connssl->ssl_ctx);
-#endif  /* CURL_SUPPORT_MAC_10_8 */
-#else
-    (void)SSLDisposeContext(connssl->ssl_ctx);
-#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
-    connssl->ssl_ctx = NULL;
-  }
-  connssl->ssl_sockfd = 0;
-}
-
-void Curl_darwinssl_close_all(struct SessionHandle *data)
-{
-  /* SecureTransport doesn't separate sessions from contexts, so... */
-  (void)data;
-}
-
-int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
-{
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  struct SessionHandle *data = conn->data;
-  ssize_t nread;
-  int what;
-  int rc;
-  char buf[120];
-
-  if(!connssl->ssl_ctx)
-    return 0;
-
-  if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
-    return 0;
-
-  Curl_darwinssl_close(conn, sockindex);
-
-  rc = 0;
-
-  what = Curl_socket_ready(conn->sock[sockindex],
-                           CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
-
-  for(;;) {
-    if(what < 0) {
-      /* anything that gets here is fatally bad */
-      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
-      rc = -1;
-      break;
-    }
-
-    if(!what) {                                /* timeout */
-      failf(data, "SSL shutdown timeout");
-      break;
-    }
-
-    /* Something to read, let's do it and hope that it is the close
-     notify alert from the server. No way to SSL_Read now, so use read(). */
-
-    nread = read(conn->sock[sockindex], buf, sizeof(buf));
-
-    if(nread < 0) {
-      failf(data, "read: %s", strerror(errno));
-      rc = -1;
-    }
-
-    if(nread <= 0)
-      break;
-
-    what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
-  }
-
-  return rc;
-}
-
-void Curl_darwinssl_session_free(void *ptr)
-{
-  /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
-     cached session ID inside the Security framework. There is a private
-     function that does this, but I don't want to have to explain to you why I
-     got your application rejected from the App Store due to the use of a
-     private API, so the best we can do is free up our own char array that we
-     created way back in darwinssl_connect_step1... */
-  Curl_safefree(ptr);
-}
-
-size_t Curl_darwinssl_version(char *buffer, size_t size)
-{
-  return snprintf(buffer, size, "SecureTransport");
-}
-
-/*
- * This function uses SSLGetSessionState to determine connection status.
- *
- * Return codes:
- *     1 means the connection is still in place
- *     0 means the connection has been closed
- *    -1 means the connection status is unknown
- */
-int Curl_darwinssl_check_cxn(struct connectdata *conn)
-{
-  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
-  OSStatus err;
-  SSLSessionState state;
-
-  if(connssl->ssl_ctx) {
-    err = SSLGetSessionState(connssl->ssl_ctx, &state);
-    if(err == noErr)
-      return state == kSSLConnected || state == kSSLHandshake;
-    return -1;
-  }
-  return 0;
-}
-
-bool Curl_darwinssl_data_pending(const struct connectdata *conn,
-                                 int connindex)
-{
-  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
-  OSStatus err;
-  size_t buffer;
-
-  if(connssl->ssl_ctx) {  /* SSL is in use */
-    err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
-    if(err == noErr)
-      return buffer > 0UL;
-    return false;
-  }
-  else
-    return false;
-}
-
-int Curl_darwinssl_random(unsigned char *entropy,
-                          size_t length)
-{
-  /* arc4random_buf() isn't available on cats older than Lion, so let's
-     do this manually for the benefit of the older cats. */
-  size_t i;
-  u_int32_t random_number = 0;
-
-  for(i = 0 ; i < length ; i++) {
-    if(i % sizeof(u_int32_t) == 0)
-      random_number = arc4random();
-    entropy[i] = random_number & 0xFF;
-    random_number >>= 8;
-  }
-  i = random_number = 0;
-  return 0;
-}
-
-void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
-                           size_t tmplen,
-                           unsigned char *md5sum, /* output */
-                           size_t md5len)
-{
-  (void)md5len;
-  (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
-}
-
-static ssize_t darwinssl_send(struct connectdata *conn,
-                              int sockindex,
-                              const void *mem,
-                              size_t len,
-                              CURLcode *curlcode)
-{
-  /*struct SessionHandle *data = conn->data;*/
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  size_t processed = 0UL;
-  OSStatus err;
-
-  /* The SSLWrite() function works a little differently than expected. The
-     fourth argument (processed) is currently documented in Apple's
-     documentation as: "On return, the length, in bytes, of the data actually
-     written."
-
-     Now, one could interpret that as "written to the socket," but actually,
-     it returns the amount of data that was written to a buffer internal to
-     the SSLContextRef instead. So it's possible for SSLWrite() to return
-     errSSLWouldBlock and a number of bytes "written" because those bytes were
-     encrypted and written to a buffer, not to the socket.
-
-     So if this happens, then we need to keep calling SSLWrite() over and
-     over again with no new data until it quits returning errSSLWouldBlock. */
-
-  /* Do we have buffered data to write from the last time we were called? */
-  if(connssl->ssl_write_buffered_length) {
-    /* Write the buffered data: */
-    err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
-    switch (err) {
-      case noErr:
-        /* processed is always going to be 0 because we didn't write to
-           the buffer, so return how much was written to the socket */
-        processed = connssl->ssl_write_buffered_length;
-        connssl->ssl_write_buffered_length = 0UL;
-        break;
-      case errSSLWouldBlock: /* argh, try again */
-        *curlcode = CURLE_AGAIN;
-        return -1L;
-      default:
-        failf(conn->data, "SSLWrite() returned error %d", err);
-        *curlcode = CURLE_SEND_ERROR;
-        return -1L;
-    }
-  }
-  else {
-    /* We've got new data to write: */
-    err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
-    if(err != noErr) {
-      switch (err) {
-        case errSSLWouldBlock:
-          /* Data was buffered but not sent, we have to tell the caller
-             to try sending again, and remember how much was buffered */
-          connssl->ssl_write_buffered_length = len;
-          *curlcode = CURLE_AGAIN;
-          return -1L;
-        default:
-          failf(conn->data, "SSLWrite() returned error %d", err);
-          *curlcode = CURLE_SEND_ERROR;
-          return -1L;
-      }
-    }
-  }
-  return (ssize_t)processed;
-}
-
-static ssize_t darwinssl_recv(struct connectdata *conn,
-                              int num,
-                              char *buf,
-                              size_t buffersize,
-                              CURLcode *curlcode)
-{
-  /*struct SessionHandle *data = conn->data;*/
-  struct ssl_connect_data *connssl = &conn->ssl[num];
-  size_t processed = 0UL;
-  OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
-
-  if(err != noErr) {
-    switch (err) {
-      case errSSLWouldBlock:  /* return how much we read (if anything) */
-        if(processed)
-          return (ssize_t)processed;
-        *curlcode = CURLE_AGAIN;
-        return -1L;
-        break;
-
-      /* errSSLClosedGraceful - server gracefully shut down the SSL session
-         errSSLClosedNoNotify - server hung up on us instead of sending a
-           closure alert notice, read() is returning 0
-         Either way, inform the caller that the server disconnected. */
-      case errSSLClosedGraceful:
-      case errSSLClosedNoNotify:
-        *curlcode = CURLE_OK;
-        return -1L;
-        break;
-
-      default:
-        failf(conn->data, "SSLRead() return error %d", err);
-        *curlcode = CURLE_RECV_ERROR;
-        return -1L;
-        break;
-    }
-  }
-  return (ssize_t)processed;
-}
-
-#endif /* USE_DARWINSSL */
diff --git a/Utilities/cmcurl/lib/vtls/curl_darwinssl.h b/Utilities/cmcurl/lib/vtls/curl_darwinssl.h
deleted file mode 100644
index f5c03d8..0000000
--- a/Utilities/cmcurl/lib/vtls/curl_darwinssl.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef HEADER_CURL_DARWINSSL_H
-#define HEADER_CURL_DARWINSSL_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman at gmail.com>.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#ifdef USE_DARWINSSL
-
-CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex);
-
-CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
-                                            int sockindex,
-                                            bool *done);
-
-/* this function doesn't actually do anything */
-void Curl_darwinssl_close_all(struct SessionHandle *data);
-
-/* close a SSL connection */
-void Curl_darwinssl_close(struct connectdata *conn, int sockindex);
-
-void Curl_darwinssl_session_free(void *ptr);
-size_t Curl_darwinssl_version(char *buffer, size_t size);
-int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex);
-int Curl_darwinssl_check_cxn(struct connectdata *conn);
-bool Curl_darwinssl_data_pending(const struct connectdata *conn,
-                                 int connindex);
-
-int Curl_darwinssl_random(unsigned char *entropy,
-                          size_t length);
-void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
-                           size_t tmplen,
-                           unsigned char *md5sum, /* output */
-                           size_t md5len);
-
-/* this backend provides these functions: */
-#define have_curlssl_md5sum 1
-
-/* API setup for SecureTransport */
-#define curlssl_init() (1)
-#define curlssl_cleanup() Curl_nop_stmt
-#define curlssl_connect Curl_darwinssl_connect
-#define curlssl_connect_nonblocking Curl_darwinssl_connect_nonblocking
-#define curlssl_session_free(x) Curl_darwinssl_session_free(x)
-#define curlssl_close_all Curl_darwinssl_close_all
-#define curlssl_close Curl_darwinssl_close
-#define curlssl_shutdown(x,y) 0
-#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN)
-#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN)
-#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
-#define curlssl_version Curl_darwinssl_version
-#define curlssl_check_cxn Curl_darwinssl_check_cxn
-#define curlssl_data_pending(x,y) Curl_darwinssl_data_pending(x, y)
-#define curlssl_random(x,y,z) Curl_darwinssl_random(y,z)
-#define curlssl_md5sum(a,b,c,d) Curl_darwinssl_md5sum(a,b,c,d)
-#define CURL_SSL_BACKEND CURLSSLBACKEND_DARWINSSL
-
-#endif /* USE_DARWINSSL */
-#endif /* HEADER_CURL_DARWINSSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/curl_schannel.c b/Utilities/cmcurl/lib/vtls/curl_schannel.c
deleted file mode 100644
index e4e595e..0000000
--- a/Utilities/cmcurl/lib/vtls/curl_schannel.c
+++ /dev/null
@@ -1,1346 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012 - 2014, Marc Hoersken, <info at marc-hoersken.de>
- * Copyright (C) 2012, Mark Salisbury, <mark.salisbury at hp.com>
- * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-/*
- * Source file for all SChannel-specific code for the TLS/SSL layer. No code
- * but vtls.c should ever call or use these functions.
- *
- */
-
-/*
- * Based upon the PolarSSL implementation in polarssl.c and polarssl.h:
- *   Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan at gmail.com>
- *
- * Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
- *   Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
- *
- * Thanks for code and inspiration!
- */
-
-/*
- * TODO list for TLS/SSL implementation:
- * - implement client certificate authentication
- * - implement custom server certificate validation
- * - implement cipher/algorithm option
- *
- * Related articles on MSDN:
- * - Getting a Certificate for Schannel
- *   http://msdn.microsoft.com/en-us/library/windows/desktop/aa375447.aspx
- * - Specifying Schannel Ciphers and Cipher Strengths
- *   http://msdn.microsoft.com/en-us/library/windows/desktop/aa380161.aspx
- */
-
-#include "curl_setup.h"
-
-#ifdef USE_SCHANNEL
-
-#ifndef USE_WINDOWS_SSPI
-#  error "Can't compile SCHANNEL support without SSPI."
-#endif
-
-#include "curl_sspi.h"
-#include "curl_schannel.h"
-#include "vtls.h"
-#include "sendf.h"
-#include "connect.h" /* for the connect timeout */
-#include "strerror.h"
-#include "select.h" /* for the socket readyness */
-#include "inet_pton.h" /* for IP addr SNI check */
-#include "curl_multibyte.h"
-#include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* Uncomment to force verbose output
- * #define infof(x, y, ...) printf(y, __VA_ARGS__)
- * #define failf(x, y, ...) printf(y, __VA_ARGS__)
- */
-
-static Curl_recv schannel_recv;
-static Curl_send schannel_send;
-
-#ifdef _WIN32_WCE
-static CURLcode verify_certificate(struct connectdata *conn, int sockindex);
-#endif
-
-static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
-                          void *BufDataPtr, unsigned long BufByteSize)
-{
-  buffer->cbBuffer = BufByteSize;
-  buffer->BufferType = BufType;
-  buffer->pvBuffer = BufDataPtr;
-}
-
-static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
-                              unsigned long NumArrElem)
-{
-  desc->ulVersion = SECBUFFER_VERSION;
-  desc->pBuffers = BufArr;
-  desc->cBuffers = NumArrElem;
-}
-
-static CURLcode
-schannel_connect_step1(struct connectdata *conn, int sockindex)
-{
-  ssize_t written = -1;
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  SecBuffer outbuf;
-  SecBufferDesc outbuf_desc;
-  SCHANNEL_CRED schannel_cred;
-  SECURITY_STATUS sspi_status = SEC_E_OK;
-  struct curl_schannel_cred *old_cred = NULL;
-  struct in_addr addr;
-#ifdef ENABLE_IPV6
-  struct in6_addr addr6;
-#endif
-  TCHAR *host_name;
-  CURLcode code;
-
-  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
-        conn->host.name, conn->remote_port);
-
-  /* check for an existing re-usable credential handle */
-  if(!Curl_ssl_getsessionid(conn, (void**)&old_cred, NULL)) {
-    connssl->cred = old_cred;
-    infof(data, "schannel: re-using existing credential handle\n");
-  }
-  else {
-    /* setup Schannel API options */
-    memset(&schannel_cred, 0, sizeof(schannel_cred));
-    schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
-
-    if(data->set.ssl.verifypeer) {
-#ifdef _WIN32_WCE
-      /* certificate validation on CE doesn't seem to work right; we'll
-         do it following a more manual process. */
-      schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
-                              SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
-                              SCH_CRED_IGNORE_REVOCATION_OFFLINE;
-#else
-      schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
-                              SCH_CRED_REVOCATION_CHECK_CHAIN;
-#endif
-      infof(data, "schannel: checking server certificate revocation\n");
-    }
-    else {
-      schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
-                              SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
-                              SCH_CRED_IGNORE_REVOCATION_OFFLINE;
-      infof(data, "schannel: disable server certificate revocation checks\n");
-    }
-
-    if(!data->set.ssl.verifyhost) {
-      schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
-      infof(data, "schannel: verifyhost setting prevents Schannel from "
-                  "comparing the supplied target name with the subject "
-                  "names in server certificates. Also disables SNI.\n");
-    }
-
-    switch(data->set.ssl.version) {
-      case CURL_SSLVERSION_TLSv1:
-        schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT |
-                                              SP_PROT_TLS1_1_CLIENT |
-                                              SP_PROT_TLS1_2_CLIENT;
-        break;
-      case CURL_SSLVERSION_TLSv1_0:
-        schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT;
-        break;
-      case CURL_SSLVERSION_TLSv1_1:
-        schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT;
-        break;
-      case CURL_SSLVERSION_TLSv1_2:
-        schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
-        break;
-      case CURL_SSLVERSION_SSLv3:
-        schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
-        break;
-      case CURL_SSLVERSION_SSLv2:
-        schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT;
-        break;
-      default:
-        schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT |
-                                              SP_PROT_TLS1_1_CLIENT |
-                                              SP_PROT_TLS1_2_CLIENT |
-                                              SP_PROT_SSL3_CLIENT;
-        break;
-    }
-
-    /* allocate memory for the re-usable credential handle */
-    connssl->cred = (struct curl_schannel_cred *)
-                     malloc(sizeof(struct curl_schannel_cred));
-    if(!connssl->cred) {
-      failf(data, "schannel: unable to allocate memory");
-      return CURLE_OUT_OF_MEMORY;
-    }
-    memset(connssl->cred, 0, sizeof(struct curl_schannel_cred));
-
-    /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx */
-    sspi_status = s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
-      SECPKG_CRED_OUTBOUND, NULL, &schannel_cred, NULL, NULL,
-      &connssl->cred->cred_handle, &connssl->cred->time_stamp);
-
-    if(sspi_status != SEC_E_OK) {
-      if(sspi_status == SEC_E_WRONG_PRINCIPAL)
-        failf(data, "schannel: SNI or certificate check failed: %s",
-              Curl_sspi_strerror(conn, sspi_status));
-      else
-        failf(data, "schannel: AcquireCredentialsHandle failed: %s",
-              Curl_sspi_strerror(conn, sspi_status));
-      Curl_safefree(connssl->cred);
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-  }
-
-  /* Warn if SNI is disabled due to use of an IP address */
-  if(Curl_inet_pton(AF_INET, conn->host.name, &addr)
-#ifdef ENABLE_IPV6
-     || Curl_inet_pton(AF_INET6, conn->host.name, &addr6)
-#endif
-    ) {
-    infof(data, "schannel: using IP address, SNI is not supported by OS.\n");
-  }
-
-  /* setup output buffer */
-  InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
-  InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
-
-  /* setup request flags */
-  connssl->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
-                       ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
-                       ISC_REQ_STREAM;
-
-  /* allocate memory for the security context handle */
-  connssl->ctxt = (struct curl_schannel_ctxt *)
-                   malloc(sizeof(struct curl_schannel_ctxt));
-  if(!connssl->ctxt) {
-    failf(data, "schannel: unable to allocate memory");
-    return CURLE_OUT_OF_MEMORY;
-  }
-  memset(connssl->ctxt, 0, sizeof(struct curl_schannel_ctxt));
-
-  host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
-  if(!host_name)
-    return CURLE_OUT_OF_MEMORY;
-
-  /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
-
-  sspi_status = s_pSecFn->InitializeSecurityContext(
-    &connssl->cred->cred_handle, NULL, host_name,
-    connssl->req_flags, 0, 0, NULL, 0, &connssl->ctxt->ctxt_handle,
-    &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
-
-  Curl_unicodefree(host_name);
-
-  if(sspi_status != SEC_I_CONTINUE_NEEDED) {
-    if(sspi_status == SEC_E_WRONG_PRINCIPAL)
-      failf(data, "schannel: SNI or certificate check failed: %s",
-            Curl_sspi_strerror(conn, sspi_status));
-    else
-      failf(data, "schannel: initial InitializeSecurityContext failed: %s",
-            Curl_sspi_strerror(conn, sspi_status));
-    Curl_safefree(connssl->ctxt);
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  infof(data, "schannel: sending initial handshake data: "
-        "sending %lu bytes...\n", outbuf.cbBuffer);
-
-  /* send initial handshake data which is now stored in output buffer */
-  code = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
-                          outbuf.cbBuffer, &written);
-  s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
-  if((code != CURLE_OK) || (outbuf.cbBuffer != (size_t)written)) {
-    failf(data, "schannel: failed to send initial handshake data: "
-          "sent %zd of %lu bytes", written, outbuf.cbBuffer);
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  infof(data, "schannel: sent initial handshake data: "
-        "sent %zd bytes\n", written);
-
-  /* continue to second handshake step */
-  connssl->connecting_state = ssl_connect_2;
-
-  return CURLE_OK;
-}
-
-static CURLcode
-schannel_connect_step2(struct connectdata *conn, int sockindex)
-{
-  int i;
-  ssize_t nread = -1, written = -1;
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  SecBuffer outbuf[2];
-  SecBufferDesc outbuf_desc;
-  SecBuffer inbuf[2];
-  SecBufferDesc inbuf_desc;
-  SECURITY_STATUS sspi_status = SEC_E_OK;
-  TCHAR *host_name;
-  CURLcode code;
-  bool doread;
-
-  doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
-
-  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
-        conn->host.name, conn->remote_port);
-
-  if(!connssl->cred || !connssl->ctxt)
-    return CURLE_SSL_CONNECT_ERROR;
-
-  /* buffer to store previously received and encrypted data */
-  if(connssl->encdata_buffer == NULL) {
-    connssl->encdata_offset = 0;
-    connssl->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
-    connssl->encdata_buffer = malloc(connssl->encdata_length);
-    if(connssl->encdata_buffer == NULL) {
-      failf(data, "schannel: unable to allocate memory");
-      return CURLE_OUT_OF_MEMORY;
-    }
-  }
-
-  /* if we need a bigger buffer to read a full message, increase buffer now */
-  if(connssl->encdata_length - connssl->encdata_offset <
-     CURL_SCHANNEL_BUFFER_FREE_SIZE) {
-    /* increase internal encrypted data buffer */
-    connssl->encdata_length *= CURL_SCHANNEL_BUFFER_STEP_FACTOR;
-    connssl->encdata_buffer = realloc(connssl->encdata_buffer,
-                                      connssl->encdata_length);
-
-    if(connssl->encdata_buffer == NULL) {
-      failf(data, "schannel: unable to re-allocate memory");
-      return CURLE_OUT_OF_MEMORY;
-    }
-  }
-
-  for(;;) {
-    if(doread) {
-      /* read encrypted handshake data from socket */
-      code = Curl_read_plain(conn->sock[sockindex],
-                (char *) (connssl->encdata_buffer + connssl->encdata_offset),
-                          connssl->encdata_length - connssl->encdata_offset,
-                          &nread);
-      if(code == CURLE_AGAIN) {
-        if(connssl->connecting_state != ssl_connect_2_writing)
-          connssl->connecting_state = ssl_connect_2_reading;
-        infof(data, "schannel: failed to receive handshake, "
-              "need more data\n");
-        return CURLE_OK;
-      }
-      else if((code != CURLE_OK) || (nread == 0)) {
-        failf(data, "schannel: failed to receive handshake, "
-              "SSL/TLS connection failed");
-        return CURLE_SSL_CONNECT_ERROR;
-      }
-
-      /* increase encrypted data buffer offset */
-      connssl->encdata_offset += nread;
-    }
-
-    infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
-        connssl->encdata_offset, connssl->encdata_length);
-
-    /* setup input buffers */
-    InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(connssl->encdata_offset),
-                  curlx_uztoul(connssl->encdata_offset));
-    InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
-    InitSecBufferDesc(&inbuf_desc, inbuf, 2);
-
-    /* setup output buffers */
-    InitSecBuffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0);
-    InitSecBuffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0);
-    InitSecBufferDesc(&outbuf_desc, outbuf, 2);
-
-    if(inbuf[0].pvBuffer == NULL) {
-      failf(data, "schannel: unable to allocate memory");
-      return CURLE_OUT_OF_MEMORY;
-    }
-
-    /* copy received handshake data into input buffer */
-    memcpy(inbuf[0].pvBuffer, connssl->encdata_buffer,
-           connssl->encdata_offset);
-
-    host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
-    if(!host_name)
-      return CURLE_OUT_OF_MEMORY;
-
-    /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
-
-    sspi_status = s_pSecFn->InitializeSecurityContext(
-      &connssl->cred->cred_handle, &connssl->ctxt->ctxt_handle,
-      host_name, connssl->req_flags, 0, 0, &inbuf_desc, 0, NULL,
-      &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
-
-    Curl_unicodefree(host_name);
-
-    /* free buffer for received handshake data */
-    Curl_safefree(inbuf[0].pvBuffer);
-
-    /* check if the handshake was incomplete */
-    if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
-      connssl->connecting_state = ssl_connect_2_reading;
-      infof(data, "schannel: received incomplete message, need more data\n");
-      return CURLE_OK;
-    }
-
-    /* check if the handshake needs to be continued */
-    if(sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) {
-      for(i = 0; i < 2; i++) {
-        /* search for handshake tokens that need to be send */
-        if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
-          infof(data, "schannel: sending next handshake data: "
-                "sending %lu bytes...\n", outbuf[i].cbBuffer);
-
-          /* send handshake token to server */
-          code = Curl_write_plain(conn, conn->sock[sockindex],
-                                  outbuf[i].pvBuffer, outbuf[i].cbBuffer,
-                                  &written);
-          if((code != CURLE_OK) || (outbuf[i].cbBuffer != (size_t)written)) {
-            failf(data, "schannel: failed to send next handshake data: "
-                  "sent %zd of %lu bytes", written, outbuf[i].cbBuffer);
-            return CURLE_SSL_CONNECT_ERROR;
-          }
-        }
-
-        /* free obsolete buffer */
-        if(outbuf[i].pvBuffer != NULL) {
-          s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer);
-        }
-      }
-    }
-    else {
-      if(sspi_status == SEC_E_WRONG_PRINCIPAL)
-        failf(data, "schannel: SNI or certificate check failed: %s",
-              Curl_sspi_strerror(conn, sspi_status));
-      else
-        failf(data, "schannel: next InitializeSecurityContext failed: %s",
-              Curl_sspi_strerror(conn, sspi_status));
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-
-    /* check if there was additional remaining encrypted data */
-    if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
-      infof(data, "schannel: encrypted data length: %lu\n", inbuf[1].cbBuffer);
-      /*
-         There are two cases where we could be getting extra data here:
-         1) If we're renegotiating a connection and the handshake is already
-            complete (from the server perspective), it can encrypted app data
-            (not handshake data) in an extra buffer at this point.
-         2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a
-            connection and this extra data is part of the handshake.
-            We should process the data immediately; waiting for the socket to
-            be ready may fail since the server is done sending handshake data.
-       */
-      /* check if the remaining data is less than the total amount
-         and therefore begins after the already processed data */
-      if(connssl->encdata_offset > inbuf[1].cbBuffer) {
-        memmove(connssl->encdata_buffer,
-                (connssl->encdata_buffer + connssl->encdata_offset) -
-                  inbuf[1].cbBuffer, inbuf[1].cbBuffer);
-        connssl->encdata_offset = inbuf[1].cbBuffer;
-        if(sspi_status == SEC_I_CONTINUE_NEEDED) {
-          doread = FALSE;
-          continue;
-        }
-      }
-    }
-    else {
-      connssl->encdata_offset = 0;
-    }
-    break;
-  }
-
-  /* check if the handshake needs to be continued */
-  if(sspi_status == SEC_I_CONTINUE_NEEDED) {
-    connssl->connecting_state = ssl_connect_2_reading;
-    return CURLE_OK;
-  }
-
-  /* check if the handshake is complete */
-  if(sspi_status == SEC_E_OK) {
-    connssl->connecting_state = ssl_connect_3;
-    infof(data, "schannel: SSL/TLS handshake complete\n");
-  }
-
-#ifdef _WIN32_WCE
-  /* Windows CE doesn't do any server certificate validation.
-     We have to do it manually. */
-  if(data->set.ssl.verifypeer)
-    return verify_certificate(conn, sockindex);
-#endif
-
-  return CURLE_OK;
-}
-
-static CURLcode
-schannel_connect_step3(struct connectdata *conn, int sockindex)
-{
-  CURLcode retcode = CURLE_OK;
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  struct curl_schannel_cred *old_cred = NULL;
-  int incache;
-
-  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
-
-  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
-        conn->host.name, conn->remote_port);
-
-  if(!connssl->cred)
-    return CURLE_SSL_CONNECT_ERROR;
-
-  /* check if the required context attributes are met */
-  if(connssl->ret_flags != connssl->req_flags) {
-    if(!(connssl->ret_flags & ISC_RET_SEQUENCE_DETECT))
-      failf(data, "schannel: failed to setup sequence detection");
-    if(!(connssl->ret_flags & ISC_RET_REPLAY_DETECT))
-      failf(data, "schannel: failed to setup replay detection");
-    if(!(connssl->ret_flags & ISC_RET_CONFIDENTIALITY))
-      failf(data, "schannel: failed to setup confidentiality");
-    if(!(connssl->ret_flags & ISC_RET_ALLOCATED_MEMORY))
-      failf(data, "schannel: failed to setup memory allocation");
-    if(!(connssl->ret_flags & ISC_RET_STREAM))
-      failf(data, "schannel: failed to setup stream orientation");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  /* increment the reference counter of the credential/session handle */
-  if(connssl->cred && connssl->ctxt) {
-    connssl->cred->refcount++;
-    infof(data, "schannel: incremented credential handle refcount = %d\n",
-          connssl->cred->refcount);
-  }
-
-  /* save the current session data for possible re-use */
-  incache = !(Curl_ssl_getsessionid(conn, (void**)&old_cred, NULL));
-  if(incache) {
-    if(old_cred != connssl->cred) {
-      infof(data, "schannel: old credential handle is stale, removing\n");
-      Curl_ssl_delsessionid(conn, (void*)old_cred);
-      incache = FALSE;
-    }
-  }
-  if(!incache) {
-    retcode = Curl_ssl_addsessionid(conn, (void*)connssl->cred,
-                                    sizeof(struct curl_schannel_cred));
-    if(retcode) {
-      failf(data, "schannel: failed to store credential handle");
-      return retcode;
-    }
-    else {
-      connssl->cred->cached = TRUE;
-      infof(data, "schannel: stored credential handle in session cache\n");
-    }
-  }
-
-  connssl->connecting_state = ssl_connect_done;
-
-  return CURLE_OK;
-}
-
-static CURLcode
-schannel_connect_common(struct connectdata *conn, int sockindex,
-                        bool nonblocking, bool *done)
-{
-  CURLcode retcode;
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  curl_socket_t sockfd = conn->sock[sockindex];
-  long timeout_ms;
-  int what;
-
-  /* check if the connection has already been established */
-  if(ssl_connection_complete == connssl->state) {
-    *done = TRUE;
-    return CURLE_OK;
-  }
-
-  if(ssl_connect_1 == connssl->connecting_state) {
-    /* check out how much more time we're allowed */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
-    if(timeout_ms < 0) {
-      /* no need to continue if time already is up */
-      failf(data, "SSL/TLS connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-
-    retcode = schannel_connect_step1(conn, sockindex);
-    if(retcode)
-      return retcode;
-  }
-
-  while(ssl_connect_2 == connssl->connecting_state ||
-        ssl_connect_2_reading == connssl->connecting_state ||
-        ssl_connect_2_writing == connssl->connecting_state) {
-
-    /* check out how much more time we're allowed */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
-    if(timeout_ms < 0) {
-      /* no need to continue if time already is up */
-      failf(data, "SSL/TLS connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-
-    /* if ssl is expecting something, check if it's available. */
-    if(connssl->connecting_state == ssl_connect_2_reading
-       || connssl->connecting_state == ssl_connect_2_writing) {
-
-      curl_socket_t writefd = ssl_connect_2_writing ==
-        connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
-      curl_socket_t readfd = ssl_connect_2_reading ==
-        connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
-
-      what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
-      if(what < 0) {
-        /* fatal error */
-        failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO);
-        return CURLE_SSL_CONNECT_ERROR;
-      }
-      else if(0 == what) {
-        if(nonblocking) {
-          *done = FALSE;
-          return CURLE_OK;
-        }
-        else {
-          /* timeout */
-          failf(data, "SSL/TLS connection timeout");
-          return CURLE_OPERATION_TIMEDOUT;
-        }
-      }
-      /* socket is readable or writable */
-    }
-
-    /* Run transaction, and return to the caller if it failed or if
-     * this connection is part of a multi handle and this loop would
-     * execute again. This permits the owner of a multi handle to
-     * abort a connection attempt before step2 has completed while
-     * ensuring that a client using select() or epoll() will always
-     * have a valid fdset to wait on.
-     */
-    retcode = schannel_connect_step2(conn, sockindex);
-    if(retcode || (nonblocking &&
-                   (ssl_connect_2 == connssl->connecting_state ||
-                    ssl_connect_2_reading == connssl->connecting_state ||
-                    ssl_connect_2_writing == connssl->connecting_state)))
-      return retcode;
-
-  } /* repeat step2 until all transactions are done. */
-
-  if(ssl_connect_3 == connssl->connecting_state) {
-    retcode = schannel_connect_step3(conn, sockindex);
-    if(retcode)
-      return retcode;
-  }
-
-  if(ssl_connect_done == connssl->connecting_state) {
-    connssl->state = ssl_connection_complete;
-    conn->recv[sockindex] = schannel_recv;
-    conn->send[sockindex] = schannel_send;
-    *done = TRUE;
-  }
-  else
-    *done = FALSE;
-
-  /* reset our connection state machine */
-  connssl->connecting_state = ssl_connect_1;
-
-  return CURLE_OK;
-}
-
-static ssize_t
-schannel_send(struct connectdata *conn, int sockindex,
-              const void *buf, size_t len, CURLcode *err)
-{
-  ssize_t written = -1;
-  size_t data_len = 0;
-  unsigned char *data = NULL;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  SecBuffer outbuf[4];
-  SecBufferDesc outbuf_desc;
-  SECURITY_STATUS sspi_status = SEC_E_OK;
-  CURLcode code;
-
-  /* check if the maximum stream sizes were queried */
-  if(connssl->stream_sizes.cbMaximumMessage == 0) {
-    sspi_status = s_pSecFn->QueryContextAttributes(
-                              &connssl->ctxt->ctxt_handle,
-                              SECPKG_ATTR_STREAM_SIZES,
-                              &connssl->stream_sizes);
-    if(sspi_status != SEC_E_OK) {
-      *err = CURLE_SEND_ERROR;
-      return -1;
-    }
-  }
-
-  /* check if the buffer is longer than the maximum message length */
-  if(len > connssl->stream_sizes.cbMaximumMessage) {
-    *err = CURLE_SEND_ERROR;
-    return -1;
-  }
-
-  /* calculate the complete message length and allocate a buffer for it */
-  data_len = connssl->stream_sizes.cbHeader + len +
-              connssl->stream_sizes.cbTrailer;
-  data = (unsigned char*) malloc(data_len);
-  if(data == NULL) {
-    *err = CURLE_OUT_OF_MEMORY;
-    return -1;
-  }
-
-  /* setup output buffers (header, data, trailer, empty) */
-  InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
-                data, connssl->stream_sizes.cbHeader);
-  InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
-                data + connssl->stream_sizes.cbHeader, curlx_uztoul(len));
-  InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
-                data + connssl->stream_sizes.cbHeader + len,
-                connssl->stream_sizes.cbTrailer);
-  InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
-  InitSecBufferDesc(&outbuf_desc, outbuf, 4);
-
-  /* copy data into output buffer */
-  memcpy(outbuf[1].pvBuffer, buf, len);
-
-  /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
-  sspi_status = s_pSecFn->EncryptMessage(&connssl->ctxt->ctxt_handle, 0,
-                                         &outbuf_desc, 0);
-
-  /* check if the message was encrypted */
-  if(sspi_status == SEC_E_OK) {
-    written = 0;
-
-    /* send the encrypted message including header, data and trailer */
-    len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
-
-    /*
-       It's important to send the full message which includes the header,
-       encrypted payload, and trailer.  Until the client receives all the
-       data a coherent message has not been delivered and the client
-       can't read any of it.
-
-       If we wanted to buffer the unwritten encrypted bytes, we would
-       tell the client that all data it has requested to be sent has been
-       sent. The unwritten encrypted bytes would be the first bytes to
-       send on the next invocation.
-       Here's the catch with this - if we tell the client that all the
-       bytes have been sent, will the client call this method again to
-       send the buffered data?  Looking at who calls this function, it
-       seems the answer is NO.
-    */
-
-    /* send entire message or fail */
-    while(len > (size_t)written) {
-      ssize_t this_write;
-      long timeleft;
-      int what;
-
-      this_write = 0;
-
-      timeleft = Curl_timeleft(conn->data, NULL, FALSE);
-      if(timeleft < 0) {
-        /* we already got the timeout */
-        failf(conn->data, "schannel: timed out sending data "
-              "(bytes sent: %zd)", written);
-        *err = CURLE_OPERATION_TIMEDOUT;
-        written = -1;
-        break;
-      }
-
-      what = Curl_socket_ready(CURL_SOCKET_BAD, conn->sock[sockindex],
-                               timeleft);
-      if(what < 0) {
-        /* fatal error */
-        failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
-        *err = CURLE_SEND_ERROR;
-        written = -1;
-        break;
-      }
-      else if(0 == what) {
-        failf(conn->data, "schannel: timed out sending data "
-              "(bytes sent: %zd)", written);
-        *err = CURLE_OPERATION_TIMEDOUT;
-        written = -1;
-        break;
-      }
-      /* socket is writable */
-
-      code = Curl_write_plain(conn, conn->sock[sockindex], data + written,
-                              len - written, &this_write);
-      if(code == CURLE_AGAIN)
-        continue;
-      else if(code != CURLE_OK) {
-        *err = code;
-        written = -1;
-        break;
-      }
-
-      written += this_write;
-    }
-  }
-  else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) {
-    *err = CURLE_OUT_OF_MEMORY;
-  }
-  else{
-    *err = CURLE_SEND_ERROR;
-  }
-
-  Curl_safefree(data);
-
-  if(len == (size_t)written)
-    /* Encrypted message including header, data and trailer entirely sent.
-       The return value is the number of unencrypted bytes that were sent. */
-    written = outbuf[1].cbBuffer;
-
-  return written;
-}
-
-static ssize_t
-schannel_recv(struct connectdata *conn, int sockindex,
-              char *buf, size_t len, CURLcode *err)
-{
-  size_t size = 0;
-  ssize_t nread = 0, ret = -1;
-  CURLcode retcode;
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  bool done = FALSE;
-  SecBuffer inbuf[4];
-  SecBufferDesc inbuf_desc;
-  SECURITY_STATUS sspi_status = SEC_E_OK;
-
-  infof(data, "schannel: client wants to read %zu bytes\n", len);
-  *err = CURLE_OK;
-
-  /* buffer to store previously received and decrypted data */
-  if(connssl->decdata_buffer == NULL) {
-    connssl->decdata_offset = 0;
-    connssl->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
-    connssl->decdata_buffer = malloc(connssl->decdata_length);
-    if(connssl->decdata_buffer == NULL) {
-      failf(data, "schannel: unable to allocate memory");
-      *err = CURLE_OUT_OF_MEMORY;
-      return -1;
-    }
-  }
-
-  /* increase buffer in order to fit the requested amount of data */
-  while(connssl->encdata_length - connssl->encdata_offset <
-        CURL_SCHANNEL_BUFFER_FREE_SIZE || connssl->encdata_length < len) {
-    /* increase internal encrypted data buffer */
-    connssl->encdata_length *= CURL_SCHANNEL_BUFFER_STEP_FACTOR;
-    connssl->encdata_buffer = realloc(connssl->encdata_buffer,
-                                      connssl->encdata_length);
-
-    if(connssl->encdata_buffer == NULL) {
-      failf(data, "schannel: unable to re-allocate memory");
-      *err = CURLE_OUT_OF_MEMORY;
-      return -1;
-    }
-  }
-
-  /* read encrypted data from socket */
-  infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
-        connssl->encdata_offset, connssl->encdata_length);
-  size = connssl->encdata_length - connssl->encdata_offset;
-  if(size > 0) {
-    *err = Curl_read_plain(conn->sock[sockindex],
-                  (char *) (connssl->encdata_buffer + connssl->encdata_offset),
-                           size, &nread);
-    /* check for received data */
-    if(*err != CURLE_OK)
-      ret = -1;
-    else {
-      if(nread > 0)
-        /* increase encrypted data buffer offset */
-        connssl->encdata_offset += nread;
-      ret = nread;
-    }
-    infof(data, "schannel: encrypted data got %zd\n", ret);
-  }
-
-  infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
-        connssl->encdata_offset, connssl->encdata_length);
-
-  /* check if we still have some data in our buffers */
-  while(connssl->encdata_offset > 0 && sspi_status == SEC_E_OK &&
-        connssl->decdata_offset < len) {
-    /* prepare data buffer for DecryptMessage call */
-    InitSecBuffer(&inbuf[0], SECBUFFER_DATA, connssl->encdata_buffer,
-                  curlx_uztoul(connssl->encdata_offset));
-
-    /* we need 3 more empty input buffers for possible output */
-    InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
-    InitSecBuffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0);
-    InitSecBuffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0);
-
-    InitSecBufferDesc(&inbuf_desc, inbuf, 4);
-
-    /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx */
-    sspi_status = s_pSecFn->DecryptMessage(&connssl->ctxt->ctxt_handle,
-                                           &inbuf_desc, 0, NULL);
-
-    /* check if we need more data */
-    if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
-      infof(data, "schannel: failed to decrypt data, need more data\n");
-      *err = CURLE_AGAIN;
-      return -1;
-    }
-
-    /* check if everything went fine (server may want to renegotiate
-       context) */
-    if(sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE ||
-                                  sspi_status == SEC_I_CONTEXT_EXPIRED) {
-      /* check for successfully decrypted data */
-      if(inbuf[1].BufferType == SECBUFFER_DATA) {
-        infof(data, "schannel: decrypted data length: %lu\n",
-              inbuf[1].cbBuffer);
-
-        /* increase buffer in order to fit the received amount of data */
-        size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
-               inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
-        while(connssl->decdata_length - connssl->decdata_offset < size ||
-              connssl->decdata_length < len) {
-          /* increase internal decrypted data buffer */
-          connssl->decdata_length *= CURL_SCHANNEL_BUFFER_STEP_FACTOR;
-          connssl->decdata_buffer = realloc(connssl->decdata_buffer,
-                                            connssl->decdata_length);
-
-          if(connssl->decdata_buffer == NULL) {
-            failf(data, "schannel: unable to re-allocate memory");
-            *err = CURLE_OUT_OF_MEMORY;
-            return -1;
-          }
-        }
-
-        /* copy decrypted data to internal buffer */
-        size = inbuf[1].cbBuffer;
-        if(size > 0) {
-          memcpy(connssl->decdata_buffer + connssl->decdata_offset,
-                 inbuf[1].pvBuffer, size);
-          connssl->decdata_offset += size;
-        }
-
-        infof(data, "schannel: decrypted data added: %zu\n", size);
-        infof(data, "schannel: decrypted data cached: offset %zu length %zu\n",
-              connssl->decdata_offset, connssl->decdata_length);
-      }
-
-      /* check for remaining encrypted data */
-      if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
-        infof(data, "schannel: encrypted data length: %lu\n",
-              inbuf[3].cbBuffer);
-
-        /* check if the remaining data is less than the total amount
-         * and therefore begins after the already processed data
-        */
-        if(connssl->encdata_offset > inbuf[3].cbBuffer) {
-          /* move remaining encrypted data forward to the beginning of
-             buffer */
-          memmove(connssl->encdata_buffer,
-                  (connssl->encdata_buffer + connssl->encdata_offset) -
-                    inbuf[3].cbBuffer, inbuf[3].cbBuffer);
-          connssl->encdata_offset = inbuf[3].cbBuffer;
-        }
-
-        infof(data, "schannel: encrypted data cached: offset %zu length %zu\n",
-              connssl->encdata_offset, connssl->encdata_length);
-      }
-      else{
-        /* reset encrypted buffer offset, because there is no data remaining */
-        connssl->encdata_offset = 0;
-      }
-    }
-
-    /* check if server wants to renegotiate the connection context */
-    if(sspi_status == SEC_I_RENEGOTIATE) {
-      infof(data, "schannel: remote party requests SSL/TLS renegotiation\n");
-
-      /* begin renegotiation */
-      infof(data, "schannel: renegotiating SSL/TLS connection\n");
-      connssl->state = ssl_connection_negotiating;
-      connssl->connecting_state = ssl_connect_2_writing;
-      retcode = schannel_connect_common(conn, sockindex, FALSE, &done);
-      if(retcode)
-        *err = retcode;
-      else {
-        infof(data, "schannel: SSL/TLS connection renegotiated\n");
-        /* now retry receiving data */
-        return schannel_recv(conn, sockindex, buf, len, err);
-      }
-    }
-  }
-
-  infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
-        connssl->decdata_offset, connssl->decdata_length);
-
-  /* copy requested decrypted data to supplied buffer */
-  size = len < connssl->decdata_offset ? len : connssl->decdata_offset;
-  if(size > 0) {
-    memcpy(buf, connssl->decdata_buffer, size);
-    ret = size;
-
-    /* move remaining decrypted data forward to the beginning of buffer */
-    memmove(connssl->decdata_buffer, connssl->decdata_buffer + size,
-            connssl->decdata_offset - size);
-    connssl->decdata_offset -= size;
-
-    infof(data, "schannel: decrypted data returned %zd\n", size);
-    infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
-          connssl->decdata_offset, connssl->decdata_length);
-  }
-
-  /* check if the server closed the connection */
-  if(ret <= 0 && ( /* special check for Windows 2000 Professional */
-      sspi_status == SEC_I_CONTEXT_EXPIRED || (sspi_status == SEC_E_OK &&
-        connssl->encdata_offset > 0 && connssl->encdata_buffer[0] == 0x15))) {
-    infof(data, "schannel: server closed the connection\n");
-    *err = CURLE_OK;
-    return 0;
-  }
-
-  /* check if something went wrong and we need to return an error */
-  if(ret < 0 && sspi_status != SEC_E_OK) {
-    infof(data, "schannel: failed to read data from server: %s\n",
-          Curl_sspi_strerror(conn, sspi_status));
-    *err = CURLE_RECV_ERROR;
-    return -1;
-  }
-
-  return ret;
-}
-
-CURLcode
-Curl_schannel_connect_nonblocking(struct connectdata *conn, int sockindex,
-                                  bool *done)
-{
-  return schannel_connect_common(conn, sockindex, TRUE, done);
-}
-
-CURLcode
-Curl_schannel_connect(struct connectdata *conn, int sockindex)
-{
-  CURLcode retcode;
-  bool done = FALSE;
-
-  retcode = schannel_connect_common(conn, sockindex, FALSE, &done);
-  if(retcode)
-    return retcode;
-
-  DEBUGASSERT(done);
-
-  return CURLE_OK;
-}
-
-bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex)
-{
-  const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
-  if(connssl->use) /* SSL/TLS is in use */
-    return (connssl->encdata_offset > 0 ||
-            connssl->decdata_offset > 0 ) ? TRUE : FALSE;
-  else
-    return FALSE;
-}
-
-void Curl_schannel_close(struct connectdata *conn, int sockindex)
-{
-  if(conn->ssl[sockindex].use)
-    /* if the SSL/TLS channel hasn't been shut down yet, do that now. */
-    Curl_ssl_shutdown(conn, sockindex);
-}
-
-int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
-{
-  /* See http://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx
-   * Shutting Down an Schannel Connection
-   */
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
-  infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
-        conn->host.name, conn->remote_port);
-
-  if(connssl->cred && connssl->ctxt) {
-    SecBufferDesc BuffDesc;
-    SecBuffer Buffer;
-    SECURITY_STATUS sspi_status;
-    SecBuffer outbuf;
-    SecBufferDesc outbuf_desc;
-    CURLcode code;
-    TCHAR *host_name;
-    DWORD dwshut = SCHANNEL_SHUTDOWN;
-
-    InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
-    InitSecBufferDesc(&BuffDesc, &Buffer, 1);
-
-    sspi_status = s_pSecFn->ApplyControlToken(&connssl->ctxt->ctxt_handle,
-                                              &BuffDesc);
-
-    if(sspi_status != SEC_E_OK)
-      failf(data, "schannel: ApplyControlToken failure: %s",
-            Curl_sspi_strerror(conn, sspi_status));
-
-    host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
-    if(!host_name)
-      return CURLE_OUT_OF_MEMORY;
-
-    /* setup output buffer */
-    InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
-    InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
-
-    sspi_status = s_pSecFn->InitializeSecurityContext(
-         &connssl->cred->cred_handle,
-         &connssl->ctxt->ctxt_handle,
-         host_name,
-         connssl->req_flags,
-         0,
-         0,
-         NULL,
-         0,
-         &connssl->ctxt->ctxt_handle,
-         &outbuf_desc,
-         &connssl->ret_flags,
-         &connssl->ctxt->time_stamp);
-
-    Curl_unicodefree(host_name);
-
-    if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
-      /* send close message which is in output buffer */
-      ssize_t written;
-      code = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
-                              outbuf.cbBuffer, &written);
-
-      s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
-      if((code != CURLE_OK) || (outbuf.cbBuffer != (size_t)written)) {
-        infof(data, "schannel: failed to send close msg: %s"
-              " (bytes written: %zd)\n", curl_easy_strerror(code), written);
-      }
-    }
-
-    /* free SSPI Schannel API security context handle */
-    if(connssl->ctxt) {
-      infof(data, "schannel: clear security context handle\n");
-      s_pSecFn->DeleteSecurityContext(&connssl->ctxt->ctxt_handle);
-      Curl_safefree(connssl->ctxt);
-    }
-
-    /* free SSPI Schannel API credential handle */
-    if(connssl->cred) {
-      /* decrement the reference counter of the credential/session handle */
-      if(connssl->cred->refcount > 0) {
-        connssl->cred->refcount--;
-        infof(data, "schannel: decremented credential handle refcount = %d\n",
-              connssl->cred->refcount);
-      }
-
-      /* if the handle was not cached and the refcount is zero */
-      if(!connssl->cred->cached && connssl->cred->refcount == 0) {
-        infof(data, "schannel: clear credential handle\n");
-        s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
-        Curl_safefree(connssl->cred);
-      }
-    }
-  }
-
-  /* free internal buffer for received encrypted data */
-  if(connssl->encdata_buffer != NULL) {
-    Curl_safefree(connssl->encdata_buffer);
-    connssl->encdata_length = 0;
-    connssl->encdata_offset = 0;
-  }
-
-  /* free internal buffer for received decrypted data */
-  if(connssl->decdata_buffer != NULL) {
-    Curl_safefree(connssl->decdata_buffer);
-    connssl->decdata_length = 0;
-    connssl->decdata_offset = 0;
-  }
-
-  return CURLE_OK;
-}
-
-void Curl_schannel_session_free(void *ptr)
-{
-  struct curl_schannel_cred *cred = ptr;
-
-  if(cred && cred->cached && cred->refcount == 0) {
-    s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
-    Curl_safefree(cred);
-  }
-}
-
-int Curl_schannel_init(void)
-{
-  return (Curl_sspi_global_init() == CURLE_OK ? 1 : 0);
-}
-
-void Curl_schannel_cleanup(void)
-{
-  Curl_sspi_global_cleanup();
-}
-
-size_t Curl_schannel_version(char *buffer, size_t size)
-{
-  size = snprintf(buffer, size, "WinSSL");
-
-  return size;
-}
-
-int Curl_schannel_random(unsigned char *entropy, size_t length)
-{
-  HCRYPTPROV hCryptProv = 0;
-
-  if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
-                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
-    return 1;
-
-  if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) {
-    CryptReleaseContext(hCryptProv, 0UL);
-    return 1;
-  }
-
-  CryptReleaseContext(hCryptProv, 0UL);
-  return 0;
-}
-
-#ifdef _WIN32_WCE
-static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
-{
-  SECURITY_STATUS status;
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  CURLcode result = CURLE_OK;
-  CERT_CONTEXT *pCertContextServer = NULL;
-  const CERT_CHAIN_CONTEXT *pChainContext = NULL;
-
-  status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
-                                            SECPKG_ATTR_REMOTE_CERT_CONTEXT,
-                                            &pCertContextServer);
-
-  if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
-    failf(data, "schannel: Failed to read remote certificate context: %s",
-          Curl_sspi_strerror(conn, status));
-    result = CURLE_PEER_FAILED_VERIFICATION;
-  }
-
-  if(result == CURLE_OK) {
-    CERT_CHAIN_PARA ChainPara;
-    memset(&ChainPara, 0, sizeof(ChainPara));
-    ChainPara.cbSize = sizeof(ChainPara);
-
-    if(!CertGetCertificateChain(NULL,
-                                pCertContextServer,
-                                NULL,
-                                pCertContextServer->hCertStore,
-                                &ChainPara,
-                                0,
-                                NULL,
-                                &pChainContext)) {
-      failf(data, "schannel: CertGetCertificateChain failed: %s",
-            Curl_sspi_strerror(conn, GetLastError()));
-      pChainContext = NULL;
-      result = CURLE_PEER_FAILED_VERIFICATION;
-    }
-
-    if(result == CURLE_OK) {
-      CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
-      DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED|
-                                 CERT_TRUST_REVOCATION_STATUS_UNKNOWN);
-      dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
-      if(dwTrustErrorMask) {
-        if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
-          failf(data, "schannel: CertGetCertificateChain trust error"
-                      " CERT_TRUST_IS_PARTIAL_CHAIN");
-        if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
-          failf(data, "schannel: CertGetCertificateChain trust error"
-                      " CERT_TRUST_IS_UNTRUSTED_ROOT");
-        if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
-          failf(data, "schannel: CertGetCertificateChain trust error"
-                      " CERT_TRUST_IS_NOT_TIME_VALID");
-        failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
-              dwTrustErrorMask);
-        result = CURLE_PEER_FAILED_VERIFICATION;
-      }
-    }
-  }
-
-  if(result == CURLE_OK) {
-    if(data->set.ssl.verifyhost) {
-      TCHAR cert_hostname_buff[128];
-      xcharp_u hostname;
-      xcharp_u cert_hostname;
-      DWORD len;
-
-      cert_hostname.const_tchar_ptr = cert_hostname_buff;
-      hostname.tchar_ptr = Curl_convert_UTF8_to_tchar(conn->host.name);
-
-      len = CertGetNameString(pCertContextServer,
-                              CERT_NAME_DNS_TYPE,
-                              0,
-                              NULL,
-                              cert_hostname.tchar_ptr,
-                              128);
-      if(len > 0 && *cert_hostname.tchar_ptr == '*') {
-        /* this is a wildcard cert.  try matching the last len - 1 chars */
-        int hostname_len = strlen(conn->host.name);
-        cert_hostname.tchar_ptr++;
-        if(_tcsicmp(cert_hostname.const_tchar_ptr,
-                    hostname.const_tchar_ptr + hostname_len - len + 2) != 0)
-          result = CURLE_PEER_FAILED_VERIFICATION;
-      }
-      else if(len == 0 || _tcsicmp(hostname.const_tchar_ptr,
-                                   cert_hostname.const_tchar_ptr) != 0) {
-        result = CURLE_PEER_FAILED_VERIFICATION;
-      }
-      if(result == CURLE_PEER_FAILED_VERIFICATION) {
-        char *_cert_hostname;
-        _cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname.tchar_ptr);
-        failf(data, "schannel: CertGetNameString() certificate hostname "
-              "(%s) did not match connection (%s)",
-              _cert_hostname, conn->host.name);
-        Curl_unicodefree(_cert_hostname);
-      }
-      Curl_unicodefree(hostname.tchar_ptr);
-    }
-  }
-
-  if(pChainContext)
-    CertFreeCertificateChain(pChainContext);
-
-  if(pCertContextServer)
-    CertFreeCertificateContext(pCertContextServer);
-
-  return result;
-}
-#endif /* _WIN32_WCE */
-
-#endif /* USE_SCHANNEL */
diff --git a/Utilities/cmcurl/lib/vtls/curl_schannel.h b/Utilities/cmcurl/lib/vtls/curl_schannel.h
deleted file mode 100644
index 700516b..0000000
--- a/Utilities/cmcurl/lib/vtls/curl_schannel.h
+++ /dev/null
@@ -1,137 +0,0 @@
-#ifndef HEADER_CURL_SCHANNEL_H
-#define HEADER_CURL_SCHANNEL_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012, Marc Hoersken, <info at marc-hoersken.de>, et al.
- * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#ifdef USE_SCHANNEL
-
-#include "urldata.h"
-
-#ifndef UNISP_NAME_A
-#define UNISP_NAME_A "Microsoft Unified Security Protocol Provider"
-#endif
-
-#ifndef UNISP_NAME_W
-#define UNISP_NAME_W L"Microsoft Unified Security Protocol Provider"
-#endif
-
-#ifndef UNISP_NAME
-#ifdef UNICODE
-#define UNISP_NAME  UNISP_NAME_W
-#else
-#define UNISP_NAME  UNISP_NAME_A
-#endif
-#endif
-
-#ifndef SP_PROT_SSL2_CLIENT
-#define SP_PROT_SSL2_CLIENT             0x00000008
-#endif
-
-#ifndef SP_PROT_SSL3_CLIENT
-#define SP_PROT_SSL3_CLIENT             0x00000008
-#endif
-
-#ifndef SP_PROT_TLS1_CLIENT
-#define SP_PROT_TLS1_CLIENT             0x00000080
-#endif
-
-#ifndef SP_PROT_TLS1_0_CLIENT
-#define SP_PROT_TLS1_0_CLIENT           SP_PROT_TLS1_CLIENT
-#endif
-
-#ifndef SP_PROT_TLS1_1_CLIENT
-#define SP_PROT_TLS1_1_CLIENT           0x00000200
-#endif
-
-#ifndef SP_PROT_TLS1_2_CLIENT
-#define SP_PROT_TLS1_2_CLIENT           0x00000800
-#endif
-
-#ifndef SECBUFFER_ALERT
-#define SECBUFFER_ALERT                 17
-#endif
-
-#ifndef ISC_RET_REPLAY_DETECT
-#define ISC_RET_REPLAY_DETECT           0x00000004
-#endif
-
-#ifndef ISC_RET_SEQUENCE_DETECT
-#define ISC_RET_SEQUENCE_DETECT         0x00000008
-#endif
-
-#ifndef ISC_RET_CONFIDENTIALITY
-#define ISC_RET_CONFIDENTIALITY         0x00000010
-#endif
-
-#ifndef ISC_RET_ALLOCATED_MEMORY
-#define ISC_RET_ALLOCATED_MEMORY        0x00000100
-#endif
-
-#ifndef ISC_RET_STREAM
-#define ISC_RET_STREAM                  0x00008000
-#endif
-
-
-#define CURL_SCHANNEL_BUFFER_INIT_SIZE   4096
-#define CURL_SCHANNEL_BUFFER_FREE_SIZE   1024
-#define CURL_SCHANNEL_BUFFER_STEP_FACTOR 2
-
-
-CURLcode Curl_schannel_connect(struct connectdata *conn, int sockindex);
-
-CURLcode Curl_schannel_connect_nonblocking(struct connectdata *conn,
-                                           int sockindex,
-                                           bool *done);
-
-bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex);
-void Curl_schannel_close(struct connectdata *conn, int sockindex);
-int Curl_schannel_shutdown(struct connectdata *conn, int sockindex);
-void Curl_schannel_session_free(void *ptr);
-
-int Curl_schannel_init(void);
-void Curl_schannel_cleanup(void);
-size_t Curl_schannel_version(char *buffer, size_t size);
-
-int Curl_schannel_random(unsigned char *entropy, size_t length);
-
-/* API setup for Schannel */
-#define curlssl_init Curl_schannel_init
-#define curlssl_cleanup Curl_schannel_cleanup
-#define curlssl_connect Curl_schannel_connect
-#define curlssl_connect_nonblocking Curl_schannel_connect_nonblocking
-#define curlssl_session_free Curl_schannel_session_free
-#define curlssl_close_all(x) (x=x, CURLE_NOT_BUILT_IN)
-#define curlssl_close Curl_schannel_close
-#define curlssl_shutdown Curl_schannel_shutdown
-#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN)
-#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN)
-#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
-#define curlssl_version Curl_schannel_version
-#define curlssl_check_cxn(x) (x=x, -1)
-#define curlssl_data_pending Curl_schannel_data_pending
-#define CURL_SSL_BACKEND CURLSSLBACKEND_SCHANNEL
-#define curlssl_random(x,y,z) ((void)x, Curl_schannel_random(y,z))
-
-#endif /* USE_SCHANNEL */
-#endif /* HEADER_CURL_SCHANNEL_H */
diff --git a/Utilities/cmcurl/lib/vtls/cyassl.c b/Utilities/cmcurl/lib/vtls/cyassl.c
index 9b5c7c6..3ded7f1 100644
--- a/Utilities/cmcurl/lib/vtls/cyassl.c
+++ b/Utilities/cmcurl/lib/vtls/cyassl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,6 +30,20 @@
 
 #ifdef USE_CYASSL
 
+#define WOLFSSL_OPTIONS_IGNORE_SYS
+/* CyaSSL's version.h, which should contain only the version, should come
+before all other CyaSSL includes and be immediately followed by build config
+aka options.h. http://curl.haxx.se/mail/lib-2015-04/0069.html */
+#include <cyassl/version.h>
+#if defined(HAVE_CYASSL_OPTIONS_H) && (LIBCYASSL_VERSION_HEX > 0x03004008)
+#if defined(CYASSL_API) || defined(WOLFSSL_API)
+/* Safety measure. If either is defined some API include was already included
+and that's a problem since options.h hasn't been included yet. */
+#error "CyaSSL API was included before the CyaSSL build options."
+#endif
+#include <cyassl/options.h>
+#endif
+
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif
@@ -43,10 +57,8 @@
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
 #include "rawstr.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-#include "curl_memory.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
 
 #include <cyassl/ssl.h>
 #ifdef HAVE_CYASSL_ERROR_SSL_H
@@ -55,10 +67,16 @@
 #include <cyassl/error.h>
 #endif
 #include <cyassl/ctaocrypt/random.h>
+#include <cyassl/ctaocrypt/sha256.h>
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
+#if LIBCYASSL_VERSION_HEX < 0x02007002 /* < 2.7.2 */
+#define CYASSL_MAX_ERROR_SZ 80
+#endif
+
 static Curl_recv cyassl_recv;
 static Curl_send cyassl_send;
 
@@ -82,46 +100,58 @@ static CURLcode
 cyassl_connect_step1(struct connectdata *conn,
                      int sockindex)
 {
+  char error_buffer[CYASSL_MAX_ERROR_SZ];
   struct SessionHandle *data = conn->data;
   struct ssl_connect_data* conssl = &conn->ssl[sockindex];
   SSL_METHOD* req_method = NULL;
   void* ssl_sessionid = NULL;
   curl_socket_t sockfd = conn->sock[sockindex];
+#ifdef HAVE_SNI
+  bool sni = FALSE;
+#define use_sni(x)  sni = (x)
+#else
+#define use_sni(x)  Curl_nop_stmt
+#endif
 
   if(conssl->state == ssl_connection_complete)
     return CURLE_OK;
 
-  /* CyaSSL doesn't support SSLv2 */
-  if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
-    failf(data, "CyaSSL does not support SSLv2");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
   /* check to see if we've been told to use an explicit SSL/TLS version */
   switch(data->set.ssl.version) {
   case CURL_SSLVERSION_DEFAULT:
-    /* we try to figure out version */
-    req_method = SSLv23_client_method();
-    break;
   case CURL_SSLVERSION_TLSv1:
-    infof(data, "CyaSSL cannot be configured to use TLS 1.0-1.2, "
+#if LIBCYASSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
+    /* minimum protocol version is set later after the CTX object is created */
+    req_method = SSLv23_client_method();
+#else
+    infof(data, "CyaSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, "
           "TLS 1.0 is used exclusively\n");
     req_method = TLSv1_client_method();
+#endif
+    use_sni(TRUE);
     break;
   case CURL_SSLVERSION_TLSv1_0:
     req_method = TLSv1_client_method();
+    use_sni(TRUE);
     break;
   case CURL_SSLVERSION_TLSv1_1:
     req_method = TLSv1_1_client_method();
+    use_sni(TRUE);
     break;
   case CURL_SSLVERSION_TLSv1_2:
     req_method = TLSv1_2_client_method();
+    use_sni(TRUE);
     break;
   case CURL_SSLVERSION_SSLv3:
     req_method = SSLv3_client_method();
+    use_sni(FALSE);
     break;
+  case CURL_SSLVERSION_SSLv2:
+    failf(data, "CyaSSL does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
   default:
-    req_method = TLSv1_client_method();
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
   }
 
   if(!req_method) {
@@ -138,15 +168,36 @@ cyassl_connect_step1(struct connectdata *conn,
     return CURLE_OUT_OF_MEMORY;
   }
 
+  switch(data->set.ssl.version) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+#if LIBCYASSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
+    /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is whatever
+    minimum version of TLS was built in and at least TLS 1.0. For later library
+    versions that could change (eg TLS 1.0 built in but defaults to TLS 1.1) so
+    we have this short circuit evaluation to find the minimum supported TLS
+    version. We use wolfSSL_CTX_SetMinVersion and not CyaSSL_SetMinVersion
+    because only the former will work before the user's CTX callback is called.
+    */
+    if((wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_2) != 1)) {
+      failf(data, "SSL: couldn't set the minimum protocol version");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+#endif
+    break;
+  }
+
 #ifndef NO_FILESYSTEM
   /* load trusted cacert */
   if(data->set.str[STRING_SSL_CAFILE]) {
-    if(!SSL_CTX_load_verify_locations(conssl->ctx,
-                                      data->set.str[STRING_SSL_CAFILE],
-                                      data->set.str[STRING_SSL_CAPATH])) {
+    if(1 != SSL_CTX_load_verify_locations(conssl->ctx,
+                                          data->set.str[STRING_SSL_CAFILE],
+                                          data->set.str[STRING_SSL_CAPATH])) {
       if(data->set.ssl.verifypeer) {
         /* Fail if we insist on successfully verifying the server. */
-        failf(data,"error setting certificate verify locations:\n"
+        failf(data, "error setting certificate verify locations:\n"
               "  CAfile: %s\n  CApath: %s",
               data->set.str[STRING_SSL_CAFILE]?
               data->set.str[STRING_SSL_CAFILE]: "none",
@@ -192,11 +243,7 @@ cyassl_connect_step1(struct connectdata *conn,
       return CURLE_SSL_CONNECT_ERROR;
     }
   }
-#else
-  if(CyaSSL_no_filesystem_verify(conssl->ctx)!= SSL_SUCCESS) {
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-#endif /* NO_FILESYSTEM */
+#endif /* !NO_FILESYSTEM */
 
   /* SSL always tries to verify the peer, this only says whether it should
    * fail to connect if the verification fails, or if it should continue
@@ -206,6 +253,46 @@ cyassl_connect_step1(struct connectdata *conn,
                      data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
                      NULL);
 
+#ifdef HAVE_SNI
+  if(sni) {
+    struct in_addr addr4;
+#ifdef ENABLE_IPV6
+    struct in6_addr addr6;
+#endif
+    size_t hostname_len = strlen(conn->host.name);
+    if((hostname_len < USHRT_MAX) &&
+       (0 == Curl_inet_pton(AF_INET, conn->host.name, &addr4)) &&
+#ifdef ENABLE_IPV6
+       (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr6)) &&
+#endif
+       (CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, conn->host.name,
+                          (unsigned short)hostname_len) != 1)) {
+      infof(data, "WARNING: failed to configure server name indication (SNI) "
+            "TLS extension\n");
+    }
+  }
+#endif
+
+  /* give application a chance to interfere with SSL set up. */
+  if(data->set.ssl.fsslctx) {
+    CURLcode result = CURLE_OK;
+    result = (*data->set.ssl.fsslctx)(data, conssl->ctx,
+                                      data->set.ssl.fsslctxp);
+    if(result) {
+      failf(data, "error signaled by ssl ctx callback");
+      return result;
+    }
+  }
+#ifdef NO_FILESYSTEM
+  else if(data->set.ssl.verifypeer) {
+    failf(data, "SSL: Certificates couldn't be loaded because CyaSSL was built"
+          " with \"no filesystem\". Either disable peer verification"
+          " (insecure) or if you are building an application with libcurl you"
+          " can load certificates via CURLOPT_SSL_CTX_FUNCTION.");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif
+
   /* Let's make an SSL structure */
   if(conssl->handle)
     SSL_free(conssl->handle);
@@ -220,7 +307,7 @@ cyassl_connect_step1(struct connectdata *conn,
     /* we got a session id, use it! */
     if(!SSL_set_session(conssl->handle, ssl_sessionid)) {
       failf(data, "SSL: SSL_set_session failed: %s",
-            ERR_error_string(SSL_get_error(conssl->handle, 0),NULL));
+            ERR_error_string(SSL_get_error(conssl->handle, 0), error_buffer));
       return CURLE_SSL_CONNECT_ERROR;
     }
     /* Informational message */
@@ -246,9 +333,6 @@ cyassl_connect_step2(struct connectdata *conn,
   struct SessionHandle *data = conn->data;
   struct ssl_connect_data* conssl = &conn->ssl[sockindex];
 
-  infof(data, "CyaSSL: Connecting to %s:%d\n",
-        conn->host.name, conn->remote_port);
-
   conn->recv[sockindex] = cyassl_recv;
   conn->send[sockindex] = cyassl_send;
 
@@ -261,7 +345,7 @@ cyassl_connect_step2(struct connectdata *conn,
 
   ret = SSL_connect(conssl->handle);
   if(ret != 1) {
-    char error_buffer[80];
+    char error_buffer[CYASSL_MAX_ERROR_SZ];
     int  detail = SSL_get_error(conssl->handle, ret);
 
     if(SSL_ERROR_WANT_READ == detail) {
@@ -321,6 +405,44 @@ cyassl_connect_step2(struct connectdata *conn,
     }
   }
 
+  if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
+    X509 *x509;
+    const char *x509_der;
+    int x509_der_len;
+    curl_X509certificate x509_parsed;
+    curl_asn1Element *pubkey;
+    CURLcode result;
+
+    x509 = SSL_get_peer_certificate(conssl->handle);
+    if(!x509) {
+      failf(data, "SSL: failed retrieving server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    x509_der = (const char *)CyaSSL_X509_get_der(x509, &x509_der_len);
+    if(!x509_der) {
+      failf(data, "SSL: failed retrieving ASN.1 server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    memset(&x509_parsed, 0, sizeof x509_parsed);
+    Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len);
+
+    pubkey = &x509_parsed.subjectPublicKeyInfo;
+    if(!pubkey->header || pubkey->end <= pubkey->header) {
+      failf(data, "SSL: failed retrieving public key from server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    result = Curl_pin_peer_pubkey(data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+                                  (const unsigned char *)pubkey->header,
+                                  (size_t)(pubkey->end - pubkey->header));
+    if(result) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      return result;
+    }
+  }
+
   conssl->connecting_state = ssl_connect_3;
   infof(data, "SSL connected\n");
 
@@ -332,11 +454,11 @@ static CURLcode
 cyassl_connect_step3(struct connectdata *conn,
                      int sockindex)
 {
-  CURLcode retcode = CURLE_OK;
+  CURLcode result = CURLE_OK;
   void *old_ssl_sessionid=NULL;
   struct SessionHandle *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  int incache;
+  bool incache;
   SSL_SESSION *our_ssl_sessionid;
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -351,18 +473,19 @@ cyassl_connect_step3(struct connectdata *conn,
       incache = FALSE;
     }
   }
+
   if(!incache) {
-    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
-                                    0 /* unknown size */);
-    if(retcode) {
+    result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+                                   0 /* unknown size */);
+    if(result) {
       failf(data, "failed to store ssl session");
-      return retcode;
+      return result;
     }
   }
 
   connssl->connecting_state = ssl_connect_done;
 
-  return retcode;
+  return result;
 }
 
 
@@ -372,7 +495,7 @@ static ssize_t cyassl_send(struct connectdata *conn,
                            size_t len,
                            CURLcode *curlcode)
 {
-  char error_buffer[80];
+  char error_buffer[CYASSL_MAX_ERROR_SZ];
   int  memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
   int  rc     = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
 
@@ -396,11 +519,6 @@ static ssize_t cyassl_send(struct connectdata *conn,
   return rc;
 }
 
-void Curl_cyassl_close_all(struct SessionHandle *data)
-{
-  (void)data;
-}
-
 void Curl_cyassl_close(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *conssl = &conn->ssl[sockindex];
@@ -422,7 +540,7 @@ static ssize_t cyassl_recv(struct connectdata *conn,
                            size_t buffersize,
                            CURLcode *curlcode)
 {
-  char error_buffer[80];
+  char error_buffer[CYASSL_MAX_ERROR_SZ];
   int  buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
   int  nread    = SSL_read(conn->ssl[num].handle, buf, buffsize);
 
@@ -458,7 +576,9 @@ void Curl_cyassl_session_free(void *ptr)
 
 size_t Curl_cyassl_version(char *buffer, size_t size)
 {
-#ifdef CYASSL_VERSION
+#ifdef WOLFSSL_VERSION
+  return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
+#elif defined(CYASSL_VERSION)
   return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
 #else
   return snprintf(buffer, size, "CyaSSL/%s", "<1.8.8");
@@ -468,10 +588,7 @@ size_t Curl_cyassl_version(char *buffer, size_t size)
 
 int Curl_cyassl_init(void)
 {
-  if(CyaSSL_Init() == 0)
-    return 1;
-
-  return -1;
+  return (CyaSSL_Init() == SSL_SUCCESS);
 }
 
 
@@ -507,7 +624,7 @@ cyassl_connect_common(struct connectdata *conn,
                       bool nonblocking,
                       bool *done)
 {
-  CURLcode retcode;
+  CURLcode result;
   struct SessionHandle *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
@@ -529,9 +646,10 @@ cyassl_connect_common(struct connectdata *conn,
       failf(data, "SSL connection timeout");
       return CURLE_OPERATION_TIMEDOUT;
     }
-    retcode = cyassl_connect_step1(conn, sockindex);
-    if(retcode)
-      return retcode;
+
+    result = cyassl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
   }
 
   while(ssl_connect_2 == connssl->connecting_state ||
@@ -583,22 +701,21 @@ cyassl_connect_common(struct connectdata *conn,
      * ensuring that a client using select() or epoll() will always
      * have a valid fdset to wait on.
      */
-    retcode = cyassl_connect_step2(conn, sockindex);
-    if(retcode || (nonblocking &&
-                   (ssl_connect_2 == connssl->connecting_state ||
-                    ssl_connect_2_reading == connssl->connecting_state ||
-                    ssl_connect_2_writing == connssl->connecting_state)))
-      return retcode;
-
+    result = cyassl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
   } /* repeat step2 until all transactions are done. */
 
-  if(ssl_connect_3==connssl->connecting_state) {
-    retcode = cyassl_connect_step3(conn, sockindex);
-    if(retcode)
-      return retcode;
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = cyassl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
   }
 
-  if(ssl_connect_done==connssl->connecting_state) {
+  if(ssl_connect_done == connssl->connecting_state) {
     connssl->state = ssl_connection_complete;
     conn->recv[sockindex] = cyassl_recv;
     conn->send[sockindex] = cyassl_send;
@@ -627,12 +744,12 @@ CURLcode
 Curl_cyassl_connect(struct connectdata *conn,
                     int sockindex)
 {
-  CURLcode retcode;
+  CURLcode result;
   bool done = FALSE;
 
-  retcode = cyassl_connect_common(conn, sockindex, FALSE, &done);
-  if(retcode)
-    return retcode;
+  result = cyassl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
 
   DEBUGASSERT(done);
 
@@ -647,9 +764,23 @@ int Curl_cyassl_random(struct SessionHandle *data,
   (void)data;
   if(InitRng(&rng))
     return 1;
-  if(RNG_GenerateBlock(&rng, entropy, length))
+  if(length > UINT_MAX)
+    return 1;
+  if(RNG_GenerateBlock(&rng, entropy, (unsigned)length))
     return 1;
   return 0;
 }
 
+void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum /* output */,
+                      size_t unused)
+{
+  Sha256 SHA256pw;
+  (void)unused;
+  InitSha256(&SHA256pw);
+  Sha256Update(&SHA256pw, tmp, tmplen);
+  Sha256Final(&SHA256pw, sha256sum);
+}
+
 #endif
diff --git a/Utilities/cmcurl/lib/vtls/cyassl.h b/Utilities/cmcurl/lib/vtls/cyassl.h
index b10b607..167de74 100644
--- a/Utilities/cmcurl/lib/vtls/cyassl.h
+++ b/Utilities/cmcurl/lib/vtls/cyassl.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,13 +26,9 @@
 #ifdef USE_CYASSL
 
 CURLcode Curl_cyassl_connect(struct connectdata *conn, int sockindex);
-bool Curl_cyassl_data_pending(const struct connectdata* conn,int connindex);
+bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex);
 int Curl_cyassl_shutdown(struct connectdata* conn, int sockindex);
 
-/* tell CyaSSL to close down all open information regarding connections (and
-   thus session ID caching etc) */
-void Curl_cyassl_close_all(struct SessionHandle *data);
-
  /* close a SSL connection */
 void Curl_cyassl_close(struct connectdata *conn, int sockindex);
 
@@ -46,6 +42,16 @@ CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn,
 int Curl_cyassl_random(struct SessionHandle *data,
                        unsigned char *entropy,
                        size_t length);
+void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
+                     size_t tmplen,
+                     unsigned char *sha256sum, /* output */
+                     size_t unused);
+
+/* Set the API backend definition to Schannel */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_CYASSL
+
+/* this backend supports CURLOPT_SSL_CTX_* */
+#define have_curlssl_ssl_ctx 1
 
 /* API setup for CyaSSL */
 #define curlssl_init Curl_cyassl_init
@@ -53,17 +59,17 @@ int Curl_cyassl_random(struct SessionHandle *data,
 #define curlssl_connect Curl_cyassl_connect
 #define curlssl_connect_nonblocking Curl_cyassl_connect_nonblocking
 #define curlssl_session_free(x)  Curl_cyassl_session_free(x)
-#define curlssl_close_all Curl_cyassl_close_all
+#define curlssl_close_all(x) ((void)x)
 #define curlssl_close Curl_cyassl_close
 #define curlssl_shutdown(x,y) Curl_cyassl_shutdown(x,y)
-#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN)
-#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN)
-#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
 #define curlssl_version Curl_cyassl_version
-#define curlssl_check_cxn(x) (x=x, -1)
+#define curlssl_check_cxn(x) ((void)x, -1)
 #define curlssl_data_pending(x,y) Curl_cyassl_data_pending(x,y)
 #define curlssl_random(x,y,z) Curl_cyassl_random(x,y,z)
-#define CURL_SSL_BACKEND CURLSSLBACKEND_CYASSL
+#define curlssl_sha256sum(a,b,c,d) Curl_cyassl_sha256sum(a,b,c,d)
 
 #endif /* USE_CYASSL */
 #endif /* HEADER_CURL_CYASSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/darwinssl.c b/Utilities/cmcurl/lib/vtls/darwinssl.c
new file mode 100644
index 0000000..03adcef
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/darwinssl.c
@@ -0,0 +1,2484 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman at gmail.com>.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all iOS and Mac OS X SecureTransport-specific code for the
+ * TLS/SSL layer. No code but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#include "urldata.h" /* for the SessionHandle definition */
+#include "curl_base64.h"
+#include "strtok.h"
+
+#ifdef USE_DARWINSSL
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <Security/Security.h>
+#include <Security/SecureTransport.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CommonCrypto/CommonDigest.h>
+
+/* The Security framework has changed greatly between iOS and different OS X
+   versions, and we will try to support as many of them as we can (back to
+   Leopard and iOS 5) by using macros and weak-linking.
+
+   IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
+   you must build this project against the 10.8 SDK or later. */
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
+#error "The darwinssl back-end requires Leopard or later."
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
+
+#define CURL_BUILD_IOS 0
+#define CURL_BUILD_IOS_7 0
+#define CURL_BUILD_MAC 1
+/* This is the maximum API level we are allowed to use when building: */
+#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
+#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
+/* These macros mean "the following code is present to allow runtime backward
+   compatibility with at least this cat or earlier":
+   (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
+   environmental variable.) */
+#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
+#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
+#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
+#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
+#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
+
+#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+#define CURL_BUILD_IOS 1
+#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
+#define CURL_BUILD_MAC 0
+#define CURL_BUILD_MAC_10_5 0
+#define CURL_BUILD_MAC_10_6 0
+#define CURL_BUILD_MAC_10_7 0
+#define CURL_BUILD_MAC_10_8 0
+#define CURL_SUPPORT_MAC_10_5 0
+#define CURL_SUPPORT_MAC_10_6 0
+#define CURL_SUPPORT_MAC_10_7 0
+#define CURL_SUPPORT_MAC_10_8 0
+#define CURL_SUPPORT_MAC_10_9 0
+
+#else
+#error "The darwinssl back-end requires iOS or OS X."
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
+
+#if CURL_BUILD_MAC
+#include <sys/sysctl.h>
+#endif /* CURL_BUILD_MAC */
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "select.h"
+#include "vtls.h"
+#include "darwinssl.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* From MacTypes.h (which we can't include because it isn't present in iOS: */
+#define ioErr -36
+#define paramErr -50
+
+/* The following two functions were ripped from Apple sample code,
+ * with some modifications: */
+static OSStatus SocketRead(SSLConnectionRef connection,
+                           void *data,          /* owned by
+                                                 * caller, data
+                                                 * RETURNED */
+                           size_t *dataLength)  /* IN/OUT */
+{
+  size_t bytesToGo = *dataLength;
+  size_t initLen = bytesToGo;
+  UInt8 *currData = (UInt8 *)data;
+  /*int sock = *(int *)connection;*/
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+  int sock = connssl->ssl_sockfd;
+  OSStatus rtn = noErr;
+  size_t bytesRead;
+  ssize_t rrtn;
+  int theErr;
+
+  *dataLength = 0;
+
+  for(;;) {
+    bytesRead = 0;
+    rrtn = read(sock, currData, bytesToGo);
+    if(rrtn <= 0) {
+      /* this is guesswork... */
+      theErr = errno;
+      if(rrtn == 0) { /* EOF = server hung up */
+        /* the framework will turn this into errSSLClosedNoNotify */
+        rtn = errSSLClosedGraceful;
+      }
+      else /* do the switch */
+        switch(theErr) {
+          case ENOENT:
+            /* connection closed */
+            rtn = errSSLClosedGraceful;
+            break;
+          case ECONNRESET:
+            rtn = errSSLClosedAbort;
+            break;
+          case EAGAIN:
+            rtn = errSSLWouldBlock;
+            connssl->ssl_direction = false;
+            break;
+          default:
+            rtn = ioErr;
+            break;
+        }
+      break;
+    }
+    else {
+      bytesRead = rrtn;
+    }
+    bytesToGo -= bytesRead;
+    currData  += bytesRead;
+
+    if(bytesToGo == 0) {
+      /* filled buffer with incoming data, done */
+      break;
+    }
+  }
+  *dataLength = initLen - bytesToGo;
+
+  return rtn;
+}
+
+static OSStatus SocketWrite(SSLConnectionRef connection,
+                            const void *data,
+                            size_t *dataLength)  /* IN/OUT */
+{
+  size_t bytesSent = 0;
+  /*int sock = *(int *)connection;*/
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+  int sock = connssl->ssl_sockfd;
+  ssize_t length;
+  size_t dataLen = *dataLength;
+  const UInt8 *dataPtr = (UInt8 *)data;
+  OSStatus ortn;
+  int theErr;
+
+  *dataLength = 0;
+
+  do {
+    length = write(sock,
+                   (char*)dataPtr + bytesSent,
+                   dataLen - bytesSent);
+  } while((length > 0) &&
+           ( (bytesSent += length) < dataLen) );
+
+  if(length <= 0) {
+    theErr = errno;
+    if(theErr == EAGAIN) {
+      ortn = errSSLWouldBlock;
+      connssl->ssl_direction = true;
+    }
+    else {
+      ortn = ioErr;
+    }
+  }
+  else {
+    ortn = noErr;
+  }
+  *dataLength = bytesSent;
+  return ortn;
+}
+
+CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
+  switch (cipher) {
+    /* SSL version 3.0 */
+    case SSL_RSA_WITH_NULL_MD5:
+      return "SSL_RSA_WITH_NULL_MD5";
+      break;
+    case SSL_RSA_WITH_NULL_SHA:
+      return "SSL_RSA_WITH_NULL_SHA";
+      break;
+    case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+      return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
+      break;
+    case SSL_RSA_WITH_RC4_128_MD5:
+      return "SSL_RSA_WITH_RC4_128_MD5";
+      break;
+    case SSL_RSA_WITH_RC4_128_SHA:
+      return "SSL_RSA_WITH_RC4_128_SHA";
+      break;
+    case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+      return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
+      break;
+    case SSL_RSA_WITH_IDEA_CBC_SHA:
+      return "SSL_RSA_WITH_IDEA_CBC_SHA";
+      break;
+    case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_RSA_WITH_DES_CBC_SHA:
+      return "SSL_RSA_WITH_DES_CBC_SHA";
+      break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DH_DSS_WITH_DES_CBC_SHA:
+      return "SSL_DH_DSS_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DH_RSA_WITH_DES_CBC_SHA:
+      return "SSL_DH_RSA_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DHE_DSS_WITH_DES_CBC_SHA:
+      return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DHE_RSA_WITH_DES_CBC_SHA:
+      return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
+      return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
+      break;
+    case SSL_DH_anon_WITH_RC4_128_MD5:
+      return "SSL_DH_anon_WITH_RC4_128_MD5";
+      break;
+    case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DH_anon_WITH_DES_CBC_SHA:
+      return "SSL_DH_anon_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+      return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
+      break;
+    case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
+      return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
+      break;
+    /* TLS 1.0 with AES (RFC 3268)
+       (Apparently these are used in SSLv3 implementations as well.) */
+    case TLS_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
+      break;
+    /* SSL version 2.0 */
+    case SSL_RSA_WITH_RC2_CBC_MD5:
+      return "SSL_RSA_WITH_RC2_CBC_MD5";
+      break;
+    case SSL_RSA_WITH_IDEA_CBC_MD5:
+      return "SSL_RSA_WITH_IDEA_CBC_MD5";
+      break;
+    case SSL_RSA_WITH_DES_CBC_MD5:
+      return "SSL_RSA_WITH_DES_CBC_MD5";
+      break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
+      return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
+      break;
+  }
+  return "SSL_NULL_WITH_NULL_NULL";
+}
+
+CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
+  switch(cipher) {
+    /* TLS 1.0 with AES (RFC 3268) */
+    case TLS_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
+      break;
+#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
+    /* TLS 1.0 with ECDSA (RFC 4492) */
+    case TLS_ECDH_ECDSA_WITH_NULL_SHA:
+      return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+      return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_NULL_SHA:
+      return "TLS_ECDH_RSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_RC4_128_SHA:
+      return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_NULL_SHA:
+      return "TLS_ECDHE_RSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+      return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_NULL_SHA:
+      return "TLS_ECDH_anon_WITH_NULL_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_RC4_128_SHA:
+      return "TLS_ECDH_anon_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
+      break;
+#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+    /* TLS 1.2 (RFC 5246) */
+    case TLS_RSA_WITH_NULL_MD5:
+      return "TLS_RSA_WITH_NULL_MD5";
+      break;
+    case TLS_RSA_WITH_NULL_SHA:
+      return "TLS_RSA_WITH_NULL_SHA";
+      break;
+    case TLS_RSA_WITH_RC4_128_MD5:
+      return "TLS_RSA_WITH_RC4_128_MD5";
+      break;
+    case TLS_RSA_WITH_RC4_128_SHA:
+      return "TLS_RSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_RSA_WITH_NULL_SHA256:
+      return "TLS_RSA_WITH_NULL_SHA256";
+      break;
+    case TLS_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA256:
+      return "TLS_RSA_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
+      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
+      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
+      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DH_anon_WITH_RC4_128_MD5:
+      return "TLS_DH_anon_WITH_RC4_128_MD5";
+      break;
+    case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
+      return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
+      return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
+      break;
+    /* TLS 1.2 with AES GCM (RFC 5288) */
+    case TLS_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
+      return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+      return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
+      return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
+      return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
+      return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
+      return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
+      break;
+    /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
+      return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
+      break;
+#else
+    case SSL_RSA_WITH_NULL_MD5:
+      return "TLS_RSA_WITH_NULL_MD5";
+      break;
+    case SSL_RSA_WITH_NULL_SHA:
+      return "TLS_RSA_WITH_NULL_SHA";
+      break;
+    case SSL_RSA_WITH_RC4_128_MD5:
+      return "TLS_RSA_WITH_RC4_128_MD5";
+      break;
+    case SSL_RSA_WITH_RC4_128_SHA:
+      return "TLS_RSA_WITH_RC4_128_SHA";
+      break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_anon_WITH_RC4_128_MD5:
+      return "TLS_DH_anon_WITH_RC4_128_MD5";
+      break;
+    case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+    /* TLS PSK (RFC 4279): */
+    case TLS_PSK_WITH_RC4_128_SHA:
+      return "TLS_PSK_WITH_RC4_128_SHA";
+      break;
+    case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_PSK_WITH_AES_128_CBC_SHA:
+      return "TLS_PSK_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_PSK_WITH_AES_256_CBC_SHA:
+      return "TLS_PSK_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_RC4_128_SHA:
+      return "TLS_DHE_PSK_WITH_RC4_128_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_RC4_128_SHA:
+      return "TLS_RSA_PSK_WITH_RC4_128_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+      return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+      return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
+      break;
+    /* More TLS PSK (RFC 4785): */
+    case TLS_PSK_WITH_NULL_SHA:
+      return "TLS_PSK_WITH_NULL_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_NULL_SHA:
+      return "TLS_DHE_PSK_WITH_NULL_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_NULL_SHA:
+      return "TLS_RSA_PSK_WITH_NULL_SHA";
+      break;
+    /* Even more TLS PSK (RFC 5487): */
+    case TLS_PSK_WITH_AES_128_GCM_SHA256:
+      return "TLS_PSK_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_PSK_WITH_AES_256_GCM_SHA384:
+      return "TLS_PSK_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+      return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+      return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
+      return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+      return "TLS_PSK_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_PSK_WITH_AES_128_CBC_SHA256:
+      return "TLS_PSK_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_PSK_WITH_AES_256_CBC_SHA384:
+      return "TLS_PSK_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_PSK_WITH_NULL_SHA256:
+      return "TLS_PSK_WITH_NULL_SHA256";
+      break;
+    case TLS_PSK_WITH_NULL_SHA384:
+      return "TLS_PSK_WITH_NULL_SHA384";
+      break;
+    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+      return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+      return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_DHE_PSK_WITH_NULL_SHA256:
+      return "TLS_DHE_PSK_WITH_NULL_SHA256";
+      break;
+    case TLS_DHE_PSK_WITH_NULL_SHA384:
+      return "TLS_RSA_PSK_WITH_NULL_SHA384";
+      break;
+    case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+      return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+      return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_RSA_PSK_WITH_NULL_SHA256:
+      return "TLS_RSA_PSK_WITH_NULL_SHA256";
+      break;
+    case TLS_RSA_PSK_WITH_NULL_SHA384:
+      return "TLS_RSA_PSK_WITH_NULL_SHA384";
+      break;
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+  }
+  return "TLS_NULL_WITH_NULL_NULL";
+}
+
+#if CURL_BUILD_MAC
+CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
+{
+  int mib[2];
+  char *os_version;
+  size_t os_version_len;
+  char *os_version_major, *os_version_minor/*, *os_version_point*/;
+  char *tok_buf;
+
+  /* Get the Darwin kernel version from the kernel using sysctl(): */
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_OSRELEASE;
+  if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
+    return;
+  os_version = malloc(os_version_len*sizeof(char));
+  if(!os_version)
+    return;
+  if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
+    free(os_version);
+    return;
+  }
+
+  /* Parse the version: */
+  os_version_major = strtok_r(os_version, ".", &tok_buf);
+  os_version_minor = strtok_r(NULL, ".", &tok_buf);
+  /*os_version_point = strtok_r(NULL, ".", &tok_buf);*/
+  *major = atoi(os_version_major);
+  *minor = atoi(os_version_minor);
+  free(os_version);
+}
+#endif /* CURL_BUILD_MAC */
+
+/* Apple provides a myriad of ways of getting information about a certificate
+   into a string. Some aren't available under iOS or newer cats. So here's
+   a unified function for getting a string describing the certificate that
+   ought to work in all cats starting with Leopard. */
+CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
+{
+  CFStringRef server_cert_summary = CFSTR("(null)");
+
+#if CURL_BUILD_IOS
+  /* iOS: There's only one way to do this. */
+  server_cert_summary = SecCertificateCopySubjectSummary(cert);
+#else
+#if CURL_BUILD_MAC_10_7
+  /* Lion & later: Get the long description if we can. */
+  if(SecCertificateCopyLongDescription != NULL)
+    server_cert_summary =
+      SecCertificateCopyLongDescription(NULL, cert, NULL);
+  else
+#endif /* CURL_BUILD_MAC_10_7 */
+#if CURL_BUILD_MAC_10_6
+  /* Snow Leopard: Get the certificate summary. */
+  if(SecCertificateCopySubjectSummary != NULL)
+    server_cert_summary = SecCertificateCopySubjectSummary(cert);
+  else
+#endif /* CURL_BUILD_MAC_10_6 */
+  /* Leopard is as far back as we go... */
+  (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
+#endif /* CURL_BUILD_IOS */
+  return server_cert_summary;
+}
+
+#if CURL_SUPPORT_MAC_10_6
+/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
+   deprecation warnings, so let's not compile this unless it's necessary: */
+static OSStatus CopyIdentityWithLabelOldSchool(char *label,
+                                               SecIdentityRef *out_c_a_k)
+{
+  OSStatus status = errSecItemNotFound;
+  SecKeychainAttributeList attr_list;
+  SecKeychainAttribute attr;
+  SecKeychainSearchRef search = NULL;
+  SecCertificateRef cert = NULL;
+
+  /* Set up the attribute list: */
+  attr_list.count = 1L;
+  attr_list.attr = &attr;
+
+  /* Set up our lone search criterion: */
+  attr.tag = kSecLabelItemAttr;
+  attr.data = label;
+  attr.length = (UInt32)strlen(label);
+
+  /* Start searching: */
+  status = SecKeychainSearchCreateFromAttributes(NULL,
+                                                 kSecCertificateItemClass,
+                                                 &attr_list,
+                                                 &search);
+  if(status == noErr) {
+    status = SecKeychainSearchCopyNext(search,
+                                       (SecKeychainItemRef *)&cert);
+    if(status == noErr && cert) {
+      /* If we found a certificate, does it have a private key? */
+      status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
+      CFRelease(cert);
+    }
+  }
+
+  if(search)
+    CFRelease(search);
+  return status;
+}
+#endif /* CURL_SUPPORT_MAC_10_6 */
+
+static OSStatus CopyIdentityWithLabel(char *label,
+                                      SecIdentityRef *out_cert_and_key)
+{
+  OSStatus status = errSecItemNotFound;
+
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+  /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
+     kSecClassIdentity was introduced in Lion. If both exist, let's use them
+     to find the certificate. */
+  if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
+    CFTypeRef keys[4];
+    CFTypeRef values[4];
+    CFDictionaryRef query_dict;
+    CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
+      kCFStringEncodingUTF8);
+
+    /* Set up our search criteria and expected results: */
+    values[0] = kSecClassIdentity; /* we want a certificate and a key */
+    keys[0] = kSecClass;
+    values[1] = kCFBooleanTrue;    /* we want a reference */
+    keys[1] = kSecReturnRef;
+    values[2] = kSecMatchLimitOne; /* one is enough, thanks */
+    keys[2] = kSecMatchLimit;
+    /* identity searches need a SecPolicyRef in order to work */
+    values[3] = SecPolicyCreateSSL(false, label_cf);
+    keys[3] = kSecMatchPolicy;
+    query_dict = CFDictionaryCreate(NULL, (const void **)keys,
+                                   (const void **)values, 4L,
+                                   &kCFCopyStringDictionaryKeyCallBacks,
+                                   &kCFTypeDictionaryValueCallBacks);
+    CFRelease(values[3]);
+    CFRelease(label_cf);
+
+    /* Do we have a match? */
+    status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
+    CFRelease(query_dict);
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_6
+    /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
+    status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
+#endif /* CURL_SUPPORT_MAC_10_7 */
+  }
+#elif CURL_SUPPORT_MAC_10_6
+  /* For developers building on older cats, we have no choice but to fall back
+     to SecKeychainSearch. */
+  status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+  return status;
+}
+
+static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
+                                           const char *cPassword,
+                                           SecIdentityRef *out_cert_and_key)
+{
+  OSStatus status = errSecItemNotFound;
+  CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
+    (const UInt8 *)cPath, strlen(cPath), false);
+  CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
+    cPassword, kCFStringEncodingUTF8) : NULL;
+  CFDataRef pkcs_data = NULL;
+
+  /* We can import P12 files on iOS or OS X 10.7 or later: */
+  /* These constants are documented as having first appeared in 10.6 but they
+     raise linker errors when used on that cat for some reason. */
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+  if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
+    NULL, NULL, &status)) {
+    const void *cKeys[] = {kSecImportExportPassphrase};
+    const void *cValues[] = {password};
+    CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
+      password ? 1L : 0L, NULL, NULL);
+    CFArrayRef items = NULL;
+
+    /* Here we go: */
+    status = SecPKCS12Import(pkcs_data, options, &items);
+    if(status == noErr && items && CFArrayGetCount(items)) {
+      CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
+      const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
+        kSecImportItemIdentity);
+
+      /* Retain the identity; we don't care about any other data... */
+      CFRetain(temp_identity);
+      *out_cert_and_key = (SecIdentityRef)temp_identity;
+    }
+
+    if(items)
+      CFRelease(items);
+    CFRelease(options);
+    CFRelease(pkcs_data);
+  }
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+  if(password)
+    CFRelease(password);
+  CFRelease(pkcs_url);
+  return status;
+}
+
+/* This code was borrowed from nss.c, with some modifications:
+ * Determine whether the nickname passed in is a filename that needs to
+ * be loaded as a PEM or a regular NSS nickname.
+ *
+ * returns 1 for a file
+ * returns 0 for not a file
+ */
+CF_INLINE bool is_file(const char *filename)
+{
+  struct_stat st;
+
+  if(filename == NULL)
+    return false;
+
+  if(stat(filename, &st) == 0)
+    return S_ISREG(st.st_mode);
+  return false;
+}
+
+static CURLcode darwinssl_connect_step1(struct connectdata *conn,
+                                        int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif /* ENABLE_IPV6 */
+  size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
+  SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
+  char *ssl_sessionid;
+  size_t ssl_sessionid_len;
+  OSStatus err = noErr;
+#if CURL_BUILD_MAC
+  int darwinver_maj = 0, darwinver_min = 0;
+
+  GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
+#endif /* CURL_BUILD_MAC */
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+  if(SSLCreateContext != NULL) {  /* use the newer API if avaialble */
+    if(connssl->ssl_ctx)
+      CFRelease(connssl->ssl_ctx);
+    connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
+    if(!connssl->ssl_ctx) {
+      failf(data, "SSL: couldn't create a context!");
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+  else {
+  /* The old ST API does not exist under iOS, so don't compile it: */
+#if CURL_SUPPORT_MAC_10_8
+    if(connssl->ssl_ctx)
+      (void)SSLDisposeContext(connssl->ssl_ctx);
+    err = SSLNewContext(false, &(connssl->ssl_ctx));
+    if(err != noErr) {
+      failf(data, "SSL: couldn't create a context: OSStatus %d", err);
+      return CURLE_OUT_OF_MEMORY;
+    }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  if(connssl->ssl_ctx)
+    (void)SSLDisposeContext(connssl->ssl_ctx);
+  err = SSLNewContext(false, &(connssl->ssl_ctx));
+  if(err != noErr) {
+    failf(data, "SSL: couldn't create a context: OSStatus %d", err);
+    return CURLE_OUT_OF_MEMORY;
+  }
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+  connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
+
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+  if(SSLSetProtocolVersionMax != NULL) {
+    switch(data->set.ssl.version) {
+      default:
+      case CURL_SSLVERSION_DEFAULT:
+      case CURL_SSLVERSION_TLSv1:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+        break;
+      case CURL_SSLVERSION_TLSv1_0:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+        break;
+      case CURL_SSLVERSION_SSLv3:
+        err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
+        if(err != noErr) {
+          failf(data, "Your version of the OS does not support SSLv3");
+          return CURLE_SSL_CONNECT_ERROR;
+        }
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
+        break;
+      case CURL_SSLVERSION_SSLv2:
+        err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
+        if(err != noErr) {
+          failf(data, "Your version of the OS does not support SSLv2");
+          return CURLE_SSL_CONNECT_ERROR;
+        }
+        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
+    }
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                       kSSLProtocolAll,
+                                       false);
+    switch (data->set.ssl.version) {
+      default:
+      case CURL_SSLVERSION_DEFAULT:
+      case CURL_SSLVERSION_TLSv1:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol1,
+                                           true);
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol11,
+                                           true);
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol12,
+                                           true);
+        break;
+      case CURL_SSLVERSION_TLSv1_0:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol1,
+                                           true);
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol11,
+                                           true);
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kTLSProtocol12,
+                                           true);
+        break;
+      case CURL_SSLVERSION_SSLv3:
+        err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kSSLProtocol3,
+                                           true);
+        if(err != noErr) {
+          failf(data, "Your version of the OS does not support SSLv3");
+          return CURLE_SSL_CONNECT_ERROR;
+        }
+        break;
+      case CURL_SSLVERSION_SSLv2:
+        err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                           kSSLProtocol2,
+                                           true);
+        if(err != noErr) {
+          failf(data, "Your version of the OS does not support SSLv2");
+          return CURLE_SSL_CONNECT_ERROR;
+        }
+        break;
+    }
+#endif  /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
+  switch(data->set.ssl.version) {
+    default:
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+    case CURL_SSLVERSION_TLSv1_0:
+      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kTLSProtocol1,
+                                         true);
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      failf(data, "Your version of the OS does not support TLSv1.1");
+      return CURLE_SSL_CONNECT_ERROR;
+    case CURL_SSLVERSION_TLSv1_2:
+      failf(data, "Your version of the OS does not support TLSv1.2");
+      return CURLE_SSL_CONNECT_ERROR;
+    case CURL_SSLVERSION_SSLv2:
+      err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kSSLProtocol2,
+                                         true);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv2");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      break;
+    case CURL_SSLVERSION_SSLv3:
+      err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+                                         kSSLProtocol3,
+                                         true);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv3");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      break;
+  }
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+
+  if(data->set.str[STRING_KEY]) {
+    infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
+                "Transport. The private key must be in the Keychain.\n");
+  }
+
+  if(data->set.str[STRING_CERT]) {
+    SecIdentityRef cert_and_key = NULL;
+    bool is_cert_file = is_file(data->set.str[STRING_CERT]);
+
+    /* User wants to authenticate with a client cert. Look for it:
+       If we detect that this is a file on disk, then let's load it.
+       Otherwise, assume that the user wants to use an identity loaded
+       from the Keychain. */
+    if(is_cert_file) {
+      if(!data->set.str[STRING_CERT_TYPE])
+        infof(data, "WARNING: SSL: Certificate type not set, assuming "
+                    "PKCS#12 format.\n");
+      else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
+        strlen(data->set.str[STRING_CERT_TYPE])) != 0)
+        infof(data, "WARNING: SSL: The Security framework only supports "
+                    "loading identities that are in PKCS#12 format.\n");
+
+      err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
+        data->set.str[STRING_KEY_PASSWD], &cert_and_key);
+    }
+    else
+      err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
+
+    if(err == noErr) {
+      SecCertificateRef cert = NULL;
+      CFTypeRef certs_c[1];
+      CFArrayRef certs;
+
+      /* If we found one, print it out: */
+      err = SecIdentityCopyCertificate(cert_and_key, &cert);
+      if(err == noErr) {
+        CFStringRef cert_summary = CopyCertSubject(cert);
+        char cert_summary_c[128];
+
+        if(cert_summary) {
+          memset(cert_summary_c, 0, 128);
+          if(CFStringGetCString(cert_summary,
+                                cert_summary_c,
+                                128,
+                                kCFStringEncodingUTF8)) {
+            infof(data, "Client certificate: %s\n", cert_summary_c);
+          }
+          CFRelease(cert_summary);
+          CFRelease(cert);
+        }
+      }
+      certs_c[0] = cert_and_key;
+      certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
+                            &kCFTypeArrayCallBacks);
+      err = SSLSetCertificate(connssl->ssl_ctx, certs);
+      if(certs)
+        CFRelease(certs);
+      if(err != noErr) {
+        failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
+        return CURLE_SSL_CERTPROBLEM;
+      }
+      CFRelease(cert_and_key);
+    }
+    else {
+      switch(err) {
+        case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
+          failf(data, "SSL: Incorrect password for the certificate \"%s\" "
+                      "and its private key.", data->set.str[STRING_CERT]);
+          break;
+        case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
+          failf(data, "SSL: Couldn't make sense of the data in the "
+                      "certificate \"%s\" and its private key.",
+                      data->set.str[STRING_CERT]);
+          break;
+        case -25260: /* errSecPassphraseRequired */
+          failf(data, "SSL The certificate \"%s\" requires a password.",
+                      data->set.str[STRING_CERT]);
+          break;
+        case errSecItemNotFound:
+          failf(data, "SSL: Can't find the certificate \"%s\" and its private "
+                      "key in the Keychain.", data->set.str[STRING_CERT]);
+          break;
+        default:
+          failf(data, "SSL: Can't load the certificate \"%s\" and its private "
+                      "key: OSStatus %d", data->set.str[STRING_CERT], err);
+          break;
+      }
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* SSL always tries to verify the peer, this only says whether it should
+   * fail to connect if the verification fails, or if it should continue
+   * anyway. In the latter case the result of the verification is checked with
+   * SSL_get_verify_result() below. */
+#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
+  /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
+     a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
+     works, it doesn't work as expected under Snow Leopard or Lion.
+     So we need to call SSLSetEnableCertVerify() on those older cats in order
+     to disable certificate validation if the user turned that off.
+     (SecureTransport will always validate the certificate chain by
+     default.) */
+  /* (Note: Darwin 12.x.x is Mountain Lion.) */
+#if CURL_BUILD_MAC
+  if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
+#else
+  if(SSLSetSessionOption != NULL) {
+#endif /* CURL_BUILD_MAC */
+    bool break_on_auth = !data->set.ssl.verifypeer ||
+      data->set.str[STRING_SSL_CAFILE];
+    err = SSLSetSessionOption(connssl->ssl_ctx,
+                              kSSLSessionOptionBreakOnServerAuth,
+                              break_on_auth);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    err = SSLSetEnableCertVerify(connssl->ssl_ctx,
+                                 data->set.ssl.verifypeer?true:false);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  err = SSLSetEnableCertVerify(connssl->ssl_ctx,
+                               data->set.ssl.verifypeer?true:false);
+  if(err != noErr) {
+    failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
+
+  if(data->set.str[STRING_SSL_CAFILE]) {
+    bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
+
+    if(!is_cert_file) {
+      failf(data, "SSL: can't load CA certificate file %s",
+            data->set.str[STRING_SSL_CAFILE]);
+      return CURLE_SSL_CACERT_BADFILE;
+    }
+    if(!data->set.ssl.verifypeer) {
+      failf(data, "SSL: CA certificate set, but certificate verification "
+            "is disabled");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* Configure hostname check. SNI is used if available.
+   * Both hostname check and SNI require SSLSetPeerDomainName().
+   * Also: the verifyhost setting influences SNI usage */
+  if(data->set.ssl.verifyhost) {
+    err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
+    strlen(conn->host.name));
+
+    if(err != noErr) {
+      infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
+            err);
+    }
+
+    if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
+  #ifdef ENABLE_IPV6
+    || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
+  #endif
+       ) {
+         infof(data, "WARNING: using IP address, SNI is being disabled by "
+         "the OS.\n");
+    }
+  }
+
+  /* Disable cipher suites that ST supports but are not safe. These ciphers
+     are unlikely to be used in any case since ST gives other ciphers a much
+     higher priority, but it's probably better that we not connect at all than
+     to give the user a false sense of security if the server only supports
+     insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
+  (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
+  all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+  allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+  if(all_ciphers && allowed_ciphers &&
+     SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
+       &all_ciphers_count) == noErr) {
+    for(i = 0UL ; i < all_ciphers_count ; i++) {
+#if CURL_BUILD_MAC
+     /* There's a known bug in early versions of Mountain Lion where ST's ECC
+        ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
+        Work around the problem here by disabling those ciphers if we are
+        running in an affected version of OS X. */
+      if(darwinver_maj == 12 && darwinver_min <= 3 &&
+         all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
+           continue;
+      }
+#endif /* CURL_BUILD_MAC */
+      switch(all_ciphers[i]) {
+        /* Disable NULL ciphersuites: */
+        case SSL_NULL_WITH_NULL_NULL:
+        case SSL_RSA_WITH_NULL_MD5:
+        case SSL_RSA_WITH_NULL_SHA:
+        case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
+        case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+        case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
+        case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
+        case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
+        case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
+        case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
+        case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
+        case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
+        case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
+        case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
+        case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
+        case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
+        case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
+        case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
+        /* Disable anonymous ciphersuites: */
+        case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
+        case SSL_DH_anon_WITH_RC4_128_MD5:
+        case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_anon_WITH_DES_CBC_SHA:
+        case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+        case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+        case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
+        case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
+        case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
+        case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
+        case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
+        case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
+        case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
+        case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
+        case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
+        /* Disable weak key ciphersuites: */
+        case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+        case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+        case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_RSA_WITH_DES_CBC_SHA:
+        case SSL_DH_DSS_WITH_DES_CBC_SHA:
+        case SSL_DH_RSA_WITH_DES_CBC_SHA:
+        case SSL_DHE_DSS_WITH_DES_CBC_SHA:
+        case SSL_DHE_RSA_WITH_DES_CBC_SHA:
+        /* Disable IDEA: */
+        case SSL_RSA_WITH_IDEA_CBC_SHA:
+        case SSL_RSA_WITH_IDEA_CBC_MD5:
+          break;
+        default: /* enable everything else */
+          allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
+          break;
+      }
+    }
+    err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
+                               allowed_ciphers_count);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+    Curl_safefree(all_ciphers);
+    Curl_safefree(allowed_ciphers);
+    failf(data, "SSL: Failed to allocate memory for allowed ciphers");
+    return CURLE_OUT_OF_MEMORY;
+  }
+  Curl_safefree(all_ciphers);
+  Curl_safefree(allowed_ciphers);
+
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+  /* We want to enable 1/n-1 when using a CBC cipher unless the user
+     specifically doesn't want us doing that: */
+  if(SSLSetSessionOption != NULL) {
+    SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
+                      !data->set.ssl_enable_beast);
+    SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
+                      data->set.ssl.falsestart); /* false start support */
+  }
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
+                            &ssl_sessionid_len)) {
+    /* we got a session id, use it! */
+    err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    /* Informational message */
+    infof(data, "SSL re-using session ID\n");
+  }
+  /* If there isn't one, then let's make one up! This has to be done prior
+     to starting the handshake. */
+  else {
+    CURLcode result;
+    ssl_sessionid =
+      aprintf("%s:%d:%d:%s:%hu", data->set.str[STRING_SSL_CAFILE],
+              data->set.ssl.verifypeer, data->set.ssl.verifyhost,
+              conn->host.name, conn->remote_port);
+    ssl_sessionid_len = strlen(ssl_sessionid);
+
+    err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
+    if(result) {
+      failf(data, "failed to store ssl session");
+      return result;
+    }
+  }
+
+  err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
+  if(err != noErr) {
+    failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* pass the raw socket into the SSL layers */
+  /* We need to store the FD in a constant memory address, because
+   * SSLSetConnection() will not copy that address. I've found that
+   * conn->sock[sockindex] may change on its own. */
+  connssl->ssl_sockfd = sockfd;
+  err = SSLSetConnection(connssl->ssl_ctx, connssl);
+  if(err != noErr) {
+    failf(data, "SSL: SSLSetConnection() failed: %d", err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  connssl->connecting_state = ssl_connect_2;
+  return CURLE_OK;
+}
+
+static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
+{
+  char *sep_start, *sep_end, *cert_start, *cert_end;
+  size_t i, j, err;
+  size_t len;
+  unsigned char *b64;
+
+  /* Jump through the separators at the beginning of the certificate. */
+  sep_start = strstr(in, "-----");
+  if(sep_start == NULL)
+    return 0;
+  cert_start = strstr(sep_start + 1, "-----");
+  if(cert_start == NULL)
+    return -1;
+
+  cert_start += 5;
+
+  /* Find separator after the end of the certificate. */
+  cert_end = strstr(cert_start, "-----");
+  if(cert_end == NULL)
+    return -1;
+
+  sep_end = strstr(cert_end + 1, "-----");
+  if(sep_end == NULL)
+    return -1;
+  sep_end += 5;
+
+  len = cert_end - cert_start;
+  b64 = malloc(len + 1);
+  if(!b64)
+    return -1;
+
+  /* Create base64 string without linefeeds. */
+  for(i = 0, j = 0; i < len; i++) {
+    if(cert_start[i] != '\r' && cert_start[i] != '\n')
+      b64[j++] = cert_start[i];
+  }
+  b64[j] = '\0';
+
+  err = Curl_base64_decode((const char *)b64, out, outlen);
+  free(b64);
+  if(err) {
+    free(*out);
+    return -1;
+  }
+
+  return sep_end - in;
+}
+
+static int read_cert(const char *file, unsigned char **out, size_t *outlen)
+{
+  int fd;
+  ssize_t n, len = 0, cap = 512;
+  unsigned char buf[cap], *data;
+
+  fd = open(file, 0);
+  if(fd < 0)
+    return -1;
+
+  data = malloc(cap);
+  if(!data) {
+    close(fd);
+    return -1;
+  }
+
+  for(;;) {
+    n = read(fd, buf, sizeof(buf));
+    if(n < 0) {
+      close(fd);
+      free(data);
+      return -1;
+    }
+    else if(n == 0) {
+      close(fd);
+      break;
+    }
+
+    if(len + n >= cap) {
+      cap *= 2;
+      data = realloc(data, cap);
+      if(!data) {
+        close(fd);
+        return -1;
+      }
+    }
+
+    memcpy(data + len, buf, n);
+    len += n;
+  }
+  data[len] = '\0';
+
+  *out = data;
+  *outlen = len;
+
+  return 0;
+}
+
+static int sslerr_to_curlerr(struct SessionHandle *data, int err)
+{
+  switch(err) {
+    case errSSLXCertChainInvalid:
+      failf(data, "SSL certificate problem: Invalid certificate chain");
+      return CURLE_SSL_CACERT;
+    case errSSLUnknownRootCert:
+      failf(data, "SSL certificate problem: Untrusted root certificate");
+      return CURLE_SSL_CACERT;
+    case errSSLNoRootCert:
+      failf(data, "SSL certificate problem: No root certificate");
+      return CURLE_SSL_CACERT;
+    case errSSLCertExpired:
+      failf(data, "SSL certificate problem: Certificate chain had an "
+            "expired certificate");
+      return CURLE_SSL_CACERT;
+    case errSSLBadCert:
+      failf(data, "SSL certificate problem: Couldn't understand the server "
+            "certificate format");
+      return CURLE_SSL_CONNECT_ERROR;
+    case errSSLHostNameMismatch:
+      failf(data, "SSL certificate peer hostname mismatch");
+      return CURLE_PEER_FAILED_VERIFICATION;
+    default:
+      failf(data, "SSL unexpected certificate error %d", err);
+      return CURLE_SSL_CACERT;
+  }
+}
+
+static int append_cert_to_array(struct SessionHandle *data,
+                                unsigned char *buf, size_t buflen,
+                                CFMutableArrayRef array)
+{
+    CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
+    if(!certdata) {
+      failf(data, "SSL: failed to allocate array for CA certificate");
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    SecCertificateRef cacert =
+      SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
+    CFRelease(certdata);
+    if(!cacert) {
+      failf(data, "SSL: failed to create SecCertificate from CA certificate");
+      return CURLE_SSL_CACERT;
+    }
+
+    /* Check if cacert is valid. */
+    CFStringRef subject = CopyCertSubject(cacert);
+    if(subject) {
+      char subject_cbuf[128];
+      memset(subject_cbuf, 0, 128);
+      if(!CFStringGetCString(subject,
+                            subject_cbuf,
+                            128,
+                            kCFStringEncodingUTF8)) {
+        CFRelease(cacert);
+        failf(data, "SSL: invalid CA certificate subject");
+        return CURLE_SSL_CACERT;
+      }
+      CFRelease(subject);
+    }
+    else {
+      CFRelease(cacert);
+      failf(data, "SSL: invalid CA certificate");
+      return CURLE_SSL_CACERT;
+    }
+
+    CFArrayAppendValue(array, cacert);
+    CFRelease(cacert);
+
+    return CURLE_OK;
+}
+
+static int verify_cert(const char *cafile, struct SessionHandle *data,
+                       SSLContextRef ctx)
+{
+  int n = 0, rc;
+  long res;
+  unsigned char *certbuf, *der;
+  size_t buflen, derlen, offset = 0;
+
+  if(read_cert(cafile, &certbuf, &buflen) < 0) {
+    failf(data, "SSL: failed to read or invalid CA certificate");
+    return CURLE_SSL_CACERT;
+  }
+
+  /*
+   * Certbuf now contains the contents of the certificate file, which can be
+   * - a single DER certificate,
+   * - a single PEM certificate or
+   * - a bunch of PEM certificates (certificate bundle).
+   *
+   * Go through certbuf, and convert any PEM certificate in it into DER
+   * format.
+   */
+  CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+                                                 &kCFTypeArrayCallBacks);
+  if(array == NULL) {
+    free(certbuf);
+    failf(data, "SSL: out of memory creating CA certificate array");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  while(offset < buflen) {
+    n++;
+
+    /*
+     * Check if the certificate is in PEM format, and convert it to DER. If
+     * this fails, we assume the certificate is in DER format.
+     */
+    res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
+    if(res < 0) {
+      free(certbuf);
+      CFRelease(array);
+      failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
+            n, offset);
+      return CURLE_SSL_CACERT;
+    }
+    offset += res;
+
+    if(res == 0 && offset == 0) {
+      /* This is not a PEM file, probably a certificate in DER format. */
+      rc = append_cert_to_array(data, certbuf, buflen, array);
+      free(certbuf);
+      if(rc != CURLE_OK) {
+        CFRelease(array);
+        return rc;
+      }
+      break;
+    }
+    else if(res == 0) {
+      /* No more certificates in the bundle. */
+      free(certbuf);
+      break;
+    }
+
+    rc = append_cert_to_array(data, der, derlen, array);
+    free(der);
+    if(rc != CURLE_OK) {
+      free(certbuf);
+      CFRelease(array);
+      return rc;
+    }
+  }
+
+  SecTrustRef trust;
+  OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
+  if(trust == NULL) {
+    failf(data, "SSL: error getting certificate chain");
+    CFRelease(array);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  else if(ret != noErr) {
+    CFRelease(array);
+    return sslerr_to_curlerr(data, ret);
+  }
+
+  ret = SecTrustSetAnchorCertificates(trust, array);
+  if(ret != noErr) {
+    CFRelease(trust);
+    return sslerr_to_curlerr(data, ret);
+  }
+  ret = SecTrustSetAnchorCertificatesOnly(trust, true);
+  if(ret != noErr) {
+    CFRelease(trust);
+    return sslerr_to_curlerr(data, ret);
+  }
+
+  SecTrustResultType trust_eval = 0;
+  ret = SecTrustEvaluate(trust, &trust_eval);
+  CFRelease(array);
+  CFRelease(trust);
+  if(ret != noErr) {
+    return sslerr_to_curlerr(data, ret);
+  }
+
+  switch (trust_eval) {
+    case kSecTrustResultUnspecified:
+    case kSecTrustResultProceed:
+      return CURLE_OK;
+
+    case kSecTrustResultRecoverableTrustFailure:
+    case kSecTrustResultDeny:
+    default:
+      failf(data, "SSL: certificate verification failed (result: %d)",
+            trust_eval);
+      return CURLE_PEER_FAILED_VERIFICATION;
+  }
+}
+
+static CURLcode
+darwinssl_connect_step2(struct connectdata *conn, int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  OSStatus err;
+  SSLCipherSuite cipher;
+  SSLProtocol protocol = 0;
+
+  DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
+              || ssl_connect_2_reading == connssl->connecting_state
+              || ssl_connect_2_writing == connssl->connecting_state);
+
+  /* Here goes nothing: */
+  err = SSLHandshake(connssl->ssl_ctx);
+
+  if(err != noErr) {
+    switch (err) {
+      case errSSLWouldBlock:  /* they're not done with us yet */
+        connssl->connecting_state = connssl->ssl_direction ?
+            ssl_connect_2_writing : ssl_connect_2_reading;
+        return CURLE_OK;
+
+      /* The below is errSSLServerAuthCompleted; it's not defined in
+        Leopard's headers */
+      case -9841:
+        if(data->set.str[STRING_SSL_CAFILE]) {
+          int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
+                                connssl->ssl_ctx);
+          if(res != CURLE_OK)
+            return res;
+        }
+        /* the documentation says we need to call SSLHandshake() again */
+        return darwinssl_connect_step2(conn, sockindex);
+
+      /* These are all certificate problems with the server: */
+      case errSSLXCertChainInvalid:
+        failf(data, "SSL certificate problem: Invalid certificate chain");
+        return CURLE_SSL_CACERT;
+      case errSSLUnknownRootCert:
+        failf(data, "SSL certificate problem: Untrusted root certificate");
+        return CURLE_SSL_CACERT;
+      case errSSLNoRootCert:
+        failf(data, "SSL certificate problem: No root certificate");
+        return CURLE_SSL_CACERT;
+      case errSSLCertExpired:
+        failf(data, "SSL certificate problem: Certificate chain had an "
+              "expired certificate");
+        return CURLE_SSL_CACERT;
+      case errSSLBadCert:
+        failf(data, "SSL certificate problem: Couldn't understand the server "
+              "certificate format");
+        return CURLE_SSL_CONNECT_ERROR;
+
+      /* These are all certificate problems with the client: */
+      case errSecAuthFailed:
+        failf(data, "SSL authentication failed");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLPeerHandshakeFail:
+        failf(data, "SSL peer handshake failed, the server most likely "
+              "requires a client certificate to connect");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLPeerUnknownCA:
+        failf(data, "SSL server rejected the client certificate due to "
+              "the certificate being signed by an unknown certificate "
+              "authority");
+        return CURLE_SSL_CONNECT_ERROR;
+
+      /* This error is raised if the server's cert didn't match the server's
+         host name: */
+      case errSSLHostNameMismatch:
+        failf(data, "SSL certificate peer verification failed, the "
+              "certificate did not match \"%s\"\n", conn->host.dispname);
+        return CURLE_PEER_FAILED_VERIFICATION;
+
+      /* Generic handshake errors: */
+      case errSSLConnectionRefused:
+        failf(data, "Server dropped the connection during the SSL handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLClosedAbort:
+        failf(data, "Server aborted the SSL handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLNegotiation:
+        failf(data, "Could not negotiate an SSL cipher suite with the server");
+        return CURLE_SSL_CONNECT_ERROR;
+      /* Sometimes paramErr happens with buggy ciphers: */
+      case paramErr: case errSSLInternal:
+        failf(data, "Internal SSL engine error encountered during the "
+              "SSL handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLFatalAlert:
+        failf(data, "Fatal SSL engine error encountered during the SSL "
+              "handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      default:
+        failf(data, "Unknown SSL protocol error in connection to %s:%d",
+              conn->host.name, err);
+        return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+    /* we have been connected fine, we're not waiting for anything else. */
+    connssl->connecting_state = ssl_connect_3;
+
+    /* Informational message */
+    (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
+    (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
+    switch (protocol) {
+      case kSSLProtocol2:
+        infof(data, "SSL 2.0 connection using %s\n",
+              SSLCipherNameForNumber(cipher));
+        break;
+      case kSSLProtocol3:
+        infof(data, "SSL 3.0 connection using %s\n",
+              SSLCipherNameForNumber(cipher));
+        break;
+      case kTLSProtocol1:
+        infof(data, "TLS 1.0 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+      case kTLSProtocol11:
+        infof(data, "TLS 1.1 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+      case kTLSProtocol12:
+        infof(data, "TLS 1.2 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+#endif
+      default:
+        infof(data, "Unknown protocol connection\n");
+        break;
+    }
+
+    return CURLE_OK;
+  }
+}
+
+static CURLcode
+darwinssl_connect_step3(struct connectdata *conn,
+                        int sockindex)
+{
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CFStringRef server_cert_summary;
+  char server_cert_summary_c[128];
+  CFArrayRef server_certs = NULL;
+  SecCertificateRef server_cert;
+  OSStatus err;
+  CFIndex i, count;
+  SecTrustRef trust = NULL;
+
+  /* There is no step 3!
+   * Well, okay, if verbose mode is on, let's print the details of the
+   * server certificates. */
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+#if CURL_BUILD_IOS
+#pragma unused(server_certs)
+  err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
+  /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
+     a null trust, so be on guard for that: */
+  if(err == noErr && trust) {
+    count = SecTrustGetCertificateCount(trust);
+    for(i = 0L ; i < count ; i++) {
+      server_cert = SecTrustGetCertificateAtIndex(trust, i);
+      server_cert_summary = CopyCertSubject(server_cert);
+      memset(server_cert_summary_c, 0, 128);
+      if(CFStringGetCString(server_cert_summary,
+                            server_cert_summary_c,
+                            128,
+                            kCFStringEncodingUTF8)) {
+        infof(data, "Server certificate: %s\n", server_cert_summary_c);
+      }
+      CFRelease(server_cert_summary);
+    }
+    CFRelease(trust);
+  }
+#else
+  /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
+     The function SecTrustGetCertificateAtIndex() is officially present
+     in Lion, but it is unfortunately also present in Snow Leopard as
+     private API and doesn't work as expected. So we have to look for
+     a different symbol to make sure this code is only executed under
+     Lion or later. */
+  if(SecTrustEvaluateAsync != NULL) {
+#pragma unused(server_certs)
+    err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
+    /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
+       a null trust, so be on guard for that: */
+    if(err == noErr && trust) {
+      count = SecTrustGetCertificateCount(trust);
+      for(i = 0L ; i < count ; i++) {
+        server_cert = SecTrustGetCertificateAtIndex(trust, i);
+        server_cert_summary = CopyCertSubject(server_cert);
+        memset(server_cert_summary_c, 0, 128);
+        if(CFStringGetCString(server_cert_summary,
+                              server_cert_summary_c,
+                              128,
+                              kCFStringEncodingUTF8)) {
+          infof(data, "Server certificate: %s\n", server_cert_summary_c);
+        }
+        CFRelease(server_cert_summary);
+      }
+      CFRelease(trust);
+    }
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
+    /* Just in case SSLCopyPeerCertificates() returns null too... */
+    if(err == noErr && server_certs) {
+      count = CFArrayGetCount(server_certs);
+      for(i = 0L ; i < count ; i++) {
+        server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
+                                                                i);
+
+        server_cert_summary = CopyCertSubject(server_cert);
+        memset(server_cert_summary_c, 0, 128);
+        if(CFStringGetCString(server_cert_summary,
+                              server_cert_summary_c,
+                              128,
+                              kCFStringEncodingUTF8)) {
+          infof(data, "Server certificate: %s\n", server_cert_summary_c);
+        }
+        CFRelease(server_cert_summary);
+      }
+      CFRelease(server_certs);
+    }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+  }
+#endif /* CURL_BUILD_IOS */
+#else
+#pragma unused(trust)
+  err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
+  if(err == noErr) {
+    count = CFArrayGetCount(server_certs);
+    for(i = 0L ; i < count ; i++) {
+      server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
+      server_cert_summary = CopyCertSubject(server_cert);
+      memset(server_cert_summary_c, 0, 128);
+      if(CFStringGetCString(server_cert_summary,
+                            server_cert_summary_c,
+                            128,
+                            kCFStringEncodingUTF8)) {
+        infof(data, "Server certificate: %s\n", server_cert_summary_c);
+      }
+      CFRelease(server_cert_summary);
+    }
+    CFRelease(server_certs);
+  }
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+
+  connssl->connecting_state = ssl_connect_done;
+  return CURLE_OK;
+}
+
+static Curl_recv darwinssl_recv;
+static Curl_send darwinssl_send;
+
+static CURLcode
+darwinssl_connect_common(struct connectdata *conn,
+                         int sockindex,
+                         bool nonblocking,
+                         bool *done)
+{
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1==connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = darwinssl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading ||
+       connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if this
+     * connection is done nonblocking and this loop would execute again. This
+     * permits the owner of a multi handle to abort a connection attempt
+     * before step2 has completed while ensuring that a client using select()
+     * or epoll() will always have a valid fdset to wait on.
+     */
+    result = darwinssl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = darwinssl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = darwinssl_recv;
+    conn->send[sockindex] = darwinssl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+CURLcode
+Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
+                                   int sockindex,
+                                   bool *done)
+{
+  return darwinssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode
+Curl_darwinssl_connect(struct connectdata *conn,
+                       int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
+
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->ssl_ctx) {
+    (void)SSLClose(connssl->ssl_ctx);
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+    if(SSLCreateContext != NULL)
+      CFRelease(connssl->ssl_ctx);
+#if CURL_SUPPORT_MAC_10_8
+    else
+      (void)SSLDisposeContext(connssl->ssl_ctx);
+#endif  /* CURL_SUPPORT_MAC_10_8 */
+#else
+    (void)SSLDisposeContext(connssl->ssl_ctx);
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+    connssl->ssl_ctx = NULL;
+  }
+  connssl->ssl_sockfd = 0;
+}
+
+int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  ssize_t nread;
+  int what;
+  int rc;
+  char buf[120];
+
+  if(!connssl->ssl_ctx)
+    return 0;
+
+  if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
+    return 0;
+
+  Curl_darwinssl_close(conn, sockindex);
+
+  rc = 0;
+
+  what = Curl_socket_ready(conn->sock[sockindex],
+                           CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+
+  for(;;) {
+    if(what < 0) {
+      /* anything that gets here is fatally bad */
+      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+      rc = -1;
+      break;
+    }
+
+    if(!what) {                                /* timeout */
+      failf(data, "SSL shutdown timeout");
+      break;
+    }
+
+    /* Something to read, let's do it and hope that it is the close
+     notify alert from the server. No way to SSL_Read now, so use read(). */
+
+    nread = read(conn->sock[sockindex], buf, sizeof(buf));
+
+    if(nread < 0) {
+      failf(data, "read: %s", strerror(errno));
+      rc = -1;
+    }
+
+    if(nread <= 0)
+      break;
+
+    what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
+  }
+
+  return rc;
+}
+
+void Curl_darwinssl_session_free(void *ptr)
+{
+  /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
+     cached session ID inside the Security framework. There is a private
+     function that does this, but I don't want to have to explain to you why I
+     got your application rejected from the App Store due to the use of a
+     private API, so the best we can do is free up our own char array that we
+     created way back in darwinssl_connect_step1... */
+  Curl_safefree(ptr);
+}
+
+size_t Curl_darwinssl_version(char *buffer, size_t size)
+{
+  return snprintf(buffer, size, "SecureTransport");
+}
+
+/*
+ * This function uses SSLGetSessionState to determine connection status.
+ *
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+int Curl_darwinssl_check_cxn(struct connectdata *conn)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+  OSStatus err;
+  SSLSessionState state;
+
+  if(connssl->ssl_ctx) {
+    err = SSLGetSessionState(connssl->ssl_ctx, &state);
+    if(err == noErr)
+      return state == kSSLConnected || state == kSSLHandshake;
+    return -1;
+  }
+  return 0;
+}
+
+bool Curl_darwinssl_data_pending(const struct connectdata *conn,
+                                 int connindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  OSStatus err;
+  size_t buffer;
+
+  if(connssl->ssl_ctx) {  /* SSL is in use */
+    err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
+    if(err == noErr)
+      return buffer > 0UL;
+    return false;
+  }
+  else
+    return false;
+}
+
+int Curl_darwinssl_random(unsigned char *entropy,
+                          size_t length)
+{
+  /* arc4random_buf() isn't available on cats older than Lion, so let's
+     do this manually for the benefit of the older cats. */
+  size_t i;
+  u_int32_t random_number = 0;
+
+  for(i = 0 ; i < length ; i++) {
+    if(i % sizeof(u_int32_t) == 0)
+      random_number = arc4random();
+    entropy[i] = random_number & 0xFF;
+    random_number >>= 8;
+  }
+  i = random_number = 0;
+  return 0;
+}
+
+void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+                           size_t tmplen,
+                           unsigned char *md5sum, /* output */
+                           size_t md5len)
+{
+  (void)md5len;
+  (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
+}
+
+bool Curl_darwinssl_false_start(void) {
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+  if(SSLSetSessionOption != NULL)
+    return TRUE;
+#endif
+  return FALSE;
+}
+
+static ssize_t darwinssl_send(struct connectdata *conn,
+                              int sockindex,
+                              const void *mem,
+                              size_t len,
+                              CURLcode *curlcode)
+{
+  /*struct SessionHandle *data = conn->data;*/
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  size_t processed = 0UL;
+  OSStatus err;
+
+  /* The SSLWrite() function works a little differently than expected. The
+     fourth argument (processed) is currently documented in Apple's
+     documentation as: "On return, the length, in bytes, of the data actually
+     written."
+
+     Now, one could interpret that as "written to the socket," but actually,
+     it returns the amount of data that was written to a buffer internal to
+     the SSLContextRef instead. So it's possible for SSLWrite() to return
+     errSSLWouldBlock and a number of bytes "written" because those bytes were
+     encrypted and written to a buffer, not to the socket.
+
+     So if this happens, then we need to keep calling SSLWrite() over and
+     over again with no new data until it quits returning errSSLWouldBlock. */
+
+  /* Do we have buffered data to write from the last time we were called? */
+  if(connssl->ssl_write_buffered_length) {
+    /* Write the buffered data: */
+    err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
+    switch (err) {
+      case noErr:
+        /* processed is always going to be 0 because we didn't write to
+           the buffer, so return how much was written to the socket */
+        processed = connssl->ssl_write_buffered_length;
+        connssl->ssl_write_buffered_length = 0UL;
+        break;
+      case errSSLWouldBlock: /* argh, try again */
+        *curlcode = CURLE_AGAIN;
+        return -1L;
+      default:
+        failf(conn->data, "SSLWrite() returned error %d", err);
+        *curlcode = CURLE_SEND_ERROR;
+        return -1L;
+    }
+  }
+  else {
+    /* We've got new data to write: */
+    err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
+    if(err != noErr) {
+      switch (err) {
+        case errSSLWouldBlock:
+          /* Data was buffered but not sent, we have to tell the caller
+             to try sending again, and remember how much was buffered */
+          connssl->ssl_write_buffered_length = len;
+          *curlcode = CURLE_AGAIN;
+          return -1L;
+        default:
+          failf(conn->data, "SSLWrite() returned error %d", err);
+          *curlcode = CURLE_SEND_ERROR;
+          return -1L;
+      }
+    }
+  }
+  return (ssize_t)processed;
+}
+
+static ssize_t darwinssl_recv(struct connectdata *conn,
+                              int num,
+                              char *buf,
+                              size_t buffersize,
+                              CURLcode *curlcode)
+{
+  /*struct SessionHandle *data = conn->data;*/
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  size_t processed = 0UL;
+  OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
+
+  if(err != noErr) {
+    switch (err) {
+      case errSSLWouldBlock:  /* return how much we read (if anything) */
+        if(processed)
+          return (ssize_t)processed;
+        *curlcode = CURLE_AGAIN;
+        return -1L;
+        break;
+
+      /* errSSLClosedGraceful - server gracefully shut down the SSL session
+         errSSLClosedNoNotify - server hung up on us instead of sending a
+           closure alert notice, read() is returning 0
+         Either way, inform the caller that the server disconnected. */
+      case errSSLClosedGraceful:
+      case errSSLClosedNoNotify:
+        *curlcode = CURLE_OK;
+        return -1L;
+        break;
+
+      default:
+        failf(conn->data, "SSLRead() return error %d", err);
+        *curlcode = CURLE_RECV_ERROR;
+        return -1L;
+        break;
+    }
+  }
+  return (ssize_t)processed;
+}
+
+#endif /* USE_DARWINSSL */
diff --git a/Utilities/cmcurl/lib/vtls/darwinssl.h b/Utilities/cmcurl/lib/vtls/darwinssl.h
new file mode 100644
index 0000000..3bb69c0
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/darwinssl.h
@@ -0,0 +1,76 @@
+#ifndef HEADER_CURL_DARWINSSL_H
+#define HEADER_CURL_DARWINSSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman at gmail.com>.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_DARWINSSL
+
+CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex);
+
+CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
+                                            int sockindex,
+                                            bool *done);
+
+/* close a SSL connection */
+void Curl_darwinssl_close(struct connectdata *conn, int sockindex);
+
+void Curl_darwinssl_session_free(void *ptr);
+size_t Curl_darwinssl_version(char *buffer, size_t size);
+int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex);
+int Curl_darwinssl_check_cxn(struct connectdata *conn);
+bool Curl_darwinssl_data_pending(const struct connectdata *conn,
+                                 int connindex);
+
+int Curl_darwinssl_random(unsigned char *entropy,
+                          size_t length);
+void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+                           size_t tmplen,
+                           unsigned char *md5sum, /* output */
+                           size_t md5len);
+bool Curl_darwinssl_false_start(void);
+
+/* Set the API backend definition to SecureTransport */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_DARWINSSL
+
+/* API setup for SecureTransport */
+#define curlssl_init() (1)
+#define curlssl_cleanup() Curl_nop_stmt
+#define curlssl_connect Curl_darwinssl_connect
+#define curlssl_connect_nonblocking Curl_darwinssl_connect_nonblocking
+#define curlssl_session_free(x) Curl_darwinssl_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_darwinssl_close
+#define curlssl_shutdown(x,y) 0
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_darwinssl_version
+#define curlssl_check_cxn Curl_darwinssl_check_cxn
+#define curlssl_data_pending(x,y) Curl_darwinssl_data_pending(x, y)
+#define curlssl_random(x,y,z) ((void)x, Curl_darwinssl_random(y,z))
+#define curlssl_md5sum(a,b,c,d) Curl_darwinssl_md5sum(a,b,c,d)
+#define curlssl_false_start() Curl_darwinssl_false_start()
+
+#endif /* USE_DARWINSSL */
+#endif /* HEADER_CURL_DARWINSSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/gskit.c b/Utilities/cmcurl/lib/vtls/gskit.c
index 0f8b08f..d884bd4 100644
--- a/Utilities/cmcurl/lib/vtls/gskit.c
+++ b/Utilities/cmcurl/lib/vtls/gskit.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -74,9 +74,7 @@
 #include "select.h"
 #include "strequal.h"
 #include "x509asn1.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -134,8 +132,12 @@ static const gskit_cipher  ciphertable[] = {
       CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
       CURL_GSKPROTO_TLSV12_MASK },
   { "null-sha256",      "3B",   CURL_GSKPROTO_TLSV12_MASK },
-  { "aes128-sha256",    "3D",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes128-sha256",    "3C",   CURL_GSKPROTO_TLSV12_MASK },
   { "aes256-sha256",    "3D",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes128-gcm-sha256",
+                        "9C",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes256-gcm-sha384",
+                        "9D",   CURL_GSKPROTO_TLSV12_MASK },
   { "rc4-md5",          "1",    CURL_GSKPROTO_SSLV2_MASK },
   { "exp-rc4-md5",      "2",    CURL_GSKPROTO_SSLV2_MASK },
   { "rc2-md5",          "3",    CURL_GSKPROTO_SSLV2_MASK },
@@ -164,8 +166,6 @@ static bool is_separator(char c)
 static CURLcode gskit_status(struct SessionHandle *data, int rc,
                              const char *procname, CURLcode defcode)
 {
-  CURLcode cc;
-
   /* Process GSKit status and map it to a CURLcode. */
   switch (rc) {
   case GSK_OK:
@@ -298,7 +298,7 @@ static CURLcode set_ciphers(struct SessionHandle *data,
   int i;
   int l;
   bool unsupported;
-  CURLcode cc;
+  CURLcode result;
   struct {
     char *buf;
     char *ptr;
@@ -331,7 +331,7 @@ static CURLcode set_ciphers(struct SessionHandle *data,
 
   /* Process each cipher in input string. */
   unsupported = FALSE;
-  cc = CURLE_OK;
+  result = CURLE_OK;
   for(;;) {
     for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
       cipherlist++;
@@ -344,7 +344,7 @@ static CURLcode set_ciphers(struct SessionHandle *data,
         break;
     if(!ctp->name) {
       failf(data, "Unknown cipher %.*s", l, clp);
-      cc = CURLE_SSL_CIPHER;
+      result = CURLE_SSL_CIPHER;
     }
     else {
       unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
@@ -372,53 +372,53 @@ static CURLcode set_ciphers(struct SessionHandle *data,
 
   /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
   if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
-    cc = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
-                    ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
-    if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
-      cc = CURLE_OK;
+    result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
       if(unsupported) {
         failf(data, "TLSv1.1-only ciphers are not yet supported");
-        cc = CURLE_SSL_CIPHER;
+        result = CURLE_SSL_CIPHER;
       }
     }
   }
-  if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
-    cc = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
-                    ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
-    if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
-      cc = CURLE_OK;
+  if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
+    result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
       if(unsupported) {
         failf(data, "TLSv1.2-only ciphers are not yet supported");
-        cc = CURLE_SSL_CIPHER;
+        result = CURLE_SSL_CIPHER;
       }
     }
   }
 
   /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to
      the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */
-  if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
-    cc = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
-                    ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
-    if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
-      cc = CURLE_OK;
+  if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
+    result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
       strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr,
              ciphers[CURL_GSKPROTO_TLSV10].ptr);
     }
   }
 
   /* Set-up other ciphers. */
-  if(cc == CURLE_OK &&  (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
-    cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
-                    ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
-  if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
-    cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
-                    ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
+  if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
+    result = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
+  if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
+    result = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
 
   /* Clean-up. */
   for(i = 0; i < CURL_GSKPROTO_LAST; i++)
     free(ciphers[i].buf);
 
-  return cc;
+  return result;
 }
 
 
@@ -442,7 +442,7 @@ static CURLcode init_environment(struct SessionHandle *data,
                                  const char *password)
 {
   int rc;
-  CURLcode c;
+  CURLcode result;
   gsk_handle h;
 
   /* Creates the GSKit environment. */
@@ -458,29 +458,29 @@ static CURLcode init_environment(struct SessionHandle *data,
     return CURLE_SSL_CONNECT_ERROR;
   }
 
-  c = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
-  if(c == CURLE_OK && appid)
-    c = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
-  if(c == CURLE_OK && file)
-    c = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
-  if(c == CURLE_OK && label)
-    c = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
-  if(c == CURLE_OK && password)
-    c = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
-
-  if(c == CURLE_OK) {
+  result = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
+  if(!result && appid)
+    result = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
+  if(!result && file)
+    result = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
+  if(!result && label)
+    result = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
+  if(!result && password)
+    result = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
+
+  if(!result) {
     /* Locate CAs, Client certificate and key according to our settings.
        Note: this call may be blocking for some tenths of seconds. */
-    c = gskit_status(data, gsk_environment_init(h),
-                     "gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
-    if(c == CURLE_OK) {
+    result = gskit_status(data, gsk_environment_init(h),
+                          "gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
+    if(!result) {
       *envir = h;
-      return c;
+      return result;
     }
   }
   /* Error: rollback. */
   gsk_environment_close(&h);
-  return c;
+  return result;
 }
 
 
@@ -558,7 +558,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
   struct SessionHandle *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   gsk_handle envir;
-  CURLcode cc;
+  CURLcode result;
   int rc;
   char *keyringfile;
   char *keyringpwd;
@@ -600,22 +600,22 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
 
   if(!envir) {
     /* Use keyring mode. */
-    cc = init_environment(data, &envir, (const char *) NULL,
-                          keyringfile, keyringlabel, keyringpwd);
-    if(cc != CURLE_OK)
-      return cc;
+    result = init_environment(data, &envir, (const char *) NULL,
+                              keyringfile, keyringlabel, keyringpwd);
+    if(result)
+      return result;
   }
 
   /* Create secure session. */
-  cc = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
-                    "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
+  result = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
+                        "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
   gsk_environment_close(&envir);
-  if(cc != CURLE_OK)
-    return cc;
+  if(result)
+    return result;
 
   /* Determine which SSL/TLS version should be enabled. */
-  protoflags = CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
-               CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
+  protoflags = CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+               CURL_GSKPROTO_TLSV12_MASK;
   sni = conn->host.name;
   switch (data->set.ssl.version) {
   case CURL_SSLVERSION_SSLv2:
@@ -623,7 +623,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
     sni = (char *) NULL;
     break;
   case CURL_SSLVERSION_SSLv3:
-    protoflags = CURL_GSKPROTO_SSLV2_MASK;
+    protoflags = CURL_GSKPROTO_SSLV3_MASK;
     sni = (char *) NULL;
     break;
   case CURL_SSLVERSION_TLSv1:
@@ -643,81 +643,84 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
 
   /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
   if(sni) {
-    cc = set_buffer(data, connssl->handle,
-                    GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
-    if(cc == CURLE_UNSUPPORTED_PROTOCOL)
-      cc = CURLE_OK;
+    result = set_buffer(data, connssl->handle,
+                        GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL)
+      result = CURLE_OK;
   }
 
   /* Set session parameters. */
-  if(cc == CURLE_OK) {
+  if(!result) {
     /* Compute the handshake timeout. Since GSKit granularity is 1 second,
        we round up the required value. */
     timeout = Curl_timeleft(data, NULL, TRUE);
     if(timeout < 0)
-      cc = CURLE_OPERATION_TIMEDOUT;
+      result = CURLE_OPERATION_TIMEDOUT;
     else
-      cc = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
-                       (timeout + 999) / 1000);
+      result = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
+                           (timeout + 999) / 1000);
   }
-  if(cc == CURLE_OK)
-    cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
-  if(cc == CURLE_OK)
-    cc = set_ciphers(data, connssl->handle, &protoflags);
+  if(!result)
+    result = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
+  if(!result)
+    result = set_ciphers(data, connssl->handle, &protoflags);
   if(!protoflags) {
     failf(data, "No SSL protocol/cipher combination enabled");
-    cc = CURLE_SSL_CIPHER;
+    result = CURLE_SSL_CIPHER;
   }
-  if(cc == CURLE_OK)
-      cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
-                    (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
-                    GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
-  if(cc == CURLE_OK)
-    cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
-                  (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
-                  GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
-  if(cc == CURLE_OK)
-    cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
-                  (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
-                  GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
-  if(cc == CURLE_OK) {
-    cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
-                   (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
-                   GSK_TRUE: GSK_FALSE, TRUE);
-    if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
-      cc = CURLE_OK;
+  if(!result)
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
+                      (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
+                      GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
+  if(!result)
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
+                      (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
+                      GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
+  if(!result)
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
+                      (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
+                      GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
+  if(!result) {
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
+                      (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
+                      GSK_TRUE: GSK_FALSE, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
       if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
         failf(data, "TLS 1.1 not yet supported");
-        cc = CURLE_SSL_CIPHER;
+        result = CURLE_SSL_CIPHER;
       }
     }
   }
-  if(cc == CURLE_OK) {
-    cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
-                  (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
-                  GSK_TRUE: GSK_FALSE, TRUE);
-    if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
-      cc = CURLE_OK;
+  if(!result) {
+    result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
+                      (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
+                      GSK_TRUE: GSK_FALSE, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
       if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
         failf(data, "TLS 1.2 not yet supported");
-        cc = CURLE_SSL_CIPHER;
+        result = CURLE_SSL_CIPHER;
       }
     }
   }
-  if(cc == CURLE_OK)
-    cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
-                  data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
-                  GSK_SERVER_AUTH_PASSTHRU, FALSE);
+  if(!result)
+    result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
+                      data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
+                      GSK_SERVER_AUTH_PASSTHRU, FALSE);
 
-  if(cc == CURLE_OK) {
+  if(!result) {
     /* Start handshake. Try asynchronous first. */
     memset(&commarea, 0, sizeof commarea);
     connssl->iocport = QsoCreateIOCompletionPort();
     if(connssl->iocport != -1) {
-      cc = gskit_status(data, gsk_secure_soc_startInit(connssl->handle,
-                        connssl->iocport, &commarea),
-                        "gsk_secure_soc_startInit()", CURLE_SSL_CONNECT_ERROR);
-      if(cc == CURLE_OK) {
+      result = gskit_status(data,
+                            gsk_secure_soc_startInit(connssl->handle,
+                                                     connssl->iocport,
+                                                     &commarea),
+                            "gsk_secure_soc_startInit()",
+                            CURLE_SSL_CONNECT_ERROR);
+      if(!result) {
         connssl->connecting_state = ssl_connect_2;
         return CURLE_OK;
       }
@@ -725,12 +728,13 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
         close_async_handshake(connssl);
     }
     else if(errno != ENOBUFS)
-      cc = gskit_status(data, GSK_ERROR_IO, "QsoCreateIOCompletionPort()", 0);
+      result = gskit_status(data, GSK_ERROR_IO,
+                            "QsoCreateIOCompletionPort()", 0);
     else {
       /* No more completion port available. Use synchronous IO. */
-      cc = gskit_status(data, gsk_secure_soc_init(connssl->handle),
-                       "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
-      if(cc == CURLE_OK) {
+      result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
+                            "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
+      if(!result) {
         connssl->connecting_state = ssl_connect_3;
         return CURLE_OK;
       }
@@ -739,7 +743,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
 
   /* Error: rollback. */
   close_one(connssl, data);
-  return cc;
+  return result;
 }
 
 
@@ -751,7 +755,7 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
   Qso_OverlappedIO_t cstat;
   long timeout_ms;
   struct timeval stmv;
-  CURLcode cc;
+  CURLcode result;
 
   /* Poll or wait for end of SSL asynchronous handshake. */
 
@@ -786,12 +790,12 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
     }
     break;
   }
-  cc = gskit_status(data, cstat.returnValue, "SSL handshake",
-                    CURLE_SSL_CONNECT_ERROR);
-  if(cc == CURLE_OK)
+  result = gskit_status(data, cstat.returnValue, "SSL handshake",
+                        CURLE_SSL_CONNECT_ERROR);
+  if(!result)
     connssl->connecting_state = ssl_connect_3;
   close_async_handshake(connssl);
-  return cc;
+  return result;
 }
 
 
@@ -804,8 +808,9 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
   const gsk_cert_data_elem *p;
   const char *cert = (const char *) NULL;
   const char *certend;
+  const char *ptr;
   int i;
-  CURLcode cc;
+  CURLcode result;
 
   /* SSL handshake done: gather certificate info and verify host. */
 
@@ -838,9 +843,9 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
   }
 
   /* Verify host. */
-  cc = Curl_verifyhost(conn, cert, certend);
-  if(cc != CURLE_OK)
-    return cc;
+  result = Curl_verifyhost(conn, cert, certend);
+  if(result)
+    return result;
 
   /* The only place GSKit can get the whole CA chain is a validation
      callback where no user data pointer is available. Therefore it's not
@@ -848,12 +853,31 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
      However the server certificate may be available, thus we can return
      info about it. */
   if(data->set.ssl.certinfo) {
-    if(Curl_ssl_init_certinfo(data, 1))
-      return CURLE_OUT_OF_MEMORY;
+    result = Curl_ssl_init_certinfo(data, 1);
+    if(result)
+      return result;
+
     if(cert) {
-      cc = Curl_extract_certinfo(conn, 0, cert, certend);
-      if(cc != CURLE_OK)
-        return cc;
+      result = Curl_extract_certinfo(conn, 0, cert, certend);
+      if(result)
+        return result;
+    }
+  }
+
+  /* Check pinned public key. */
+  ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+  if(!result && ptr) {
+    curl_X509certificate x509;
+    curl_asn1Element *p;
+
+    if(!cert)
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    Curl_parseX509(&x509, cert, certend);
+    p = &x509.subjectPublicKeyInfo;
+    result = Curl_pin_peer_pubkey(ptr, p->header, p->end - p->header);
+    if(result) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      return result;
     }
   }
 
@@ -869,7 +893,7 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   long timeout_ms;
   Qso_OverlappedIO_t cstat;
-  CURLcode cc = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
   *done = connssl->state == ssl_connection_complete;
   if(*done)
@@ -883,31 +907,31 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
     if(timeout_ms < 0) {
       /* no need to continue if time already is up */
       failf(data, "SSL connection timeout");
-      cc = CURLE_OPERATION_TIMEDOUT;
+      result = CURLE_OPERATION_TIMEDOUT;
     }
     else
-      cc = gskit_connect_step1(conn, sockindex);
+      result = gskit_connect_step1(conn, sockindex);
   }
 
   /* Step 2: check if handshake is over. */
-  if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_2) {
+  if(!result && connssl->connecting_state == ssl_connect_2) {
     /* check allowed time left */
     timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
     if(timeout_ms < 0) {
       /* no need to continue if time already is up */
       failf(data, "SSL connection timeout");
-      cc = CURLE_OPERATION_TIMEDOUT;
+      result = CURLE_OPERATION_TIMEDOUT;
     }
     else
-      cc = gskit_connect_step2(conn, sockindex, nonblocking);
+      result = gskit_connect_step2(conn, sockindex, nonblocking);
   }
 
   /* Step 3: gather certificate info, verify host. */
-  if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_3)
-    cc = gskit_connect_step3(conn, sockindex);
+  if(!result && connssl->connecting_state == ssl_connect_3)
+    result = gskit_connect_step3(conn, sockindex);
 
-  if(cc != CURLE_OK)
+  if(result)
     close_one(connssl, data);
   else if(connssl->connecting_state == ssl_connect_done) {
     connssl->state = ssl_connection_complete;
@@ -917,7 +941,7 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
     *done = TRUE;
   }
 
-  return cc;
+  return result;
 }
 
 
@@ -925,24 +949,24 @@ CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
                                         int sockindex,
                                         bool *done)
 {
-  CURLcode cc;
+  CURLcode result;
 
-  cc = gskit_connect_common(conn, sockindex, TRUE, done);
-  if(*done || cc != CURLE_OK)
+  result = gskit_connect_common(conn, sockindex, TRUE, done);
+  if(*done || result)
     conn->ssl[sockindex].connecting_state = ssl_connect_1;
-  return cc;
+  return result;
 }
 
 
 CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
 {
-  CURLcode retcode;
+  CURLcode result;
   bool done;
 
   conn->ssl[sockindex].connecting_state = ssl_connect_1;
-  retcode = gskit_connect_common(conn, sockindex, FALSE, &done);
-  if(retcode)
-    return retcode;
+  result = gskit_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
 
   DEBUGASSERT(done);
 
@@ -960,14 +984,6 @@ void Curl_gskit_close(struct connectdata *conn, int sockindex)
 }
 
 
-int Curl_gskit_close_all(struct SessionHandle *data)
-{
-  /* Unimplemented. */
-  (void) data;
-  return 0;
-}
-
-
 int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
diff --git a/Utilities/cmcurl/lib/vtls/gskit.h b/Utilities/cmcurl/lib/vtls/gskit.h
index a4caa6f..af31faf 100644
--- a/Utilities/cmcurl/lib/vtls/gskit.h
+++ b/Utilities/cmcurl/lib/vtls/gskit.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,15 +32,20 @@
 #ifdef USE_GSKIT
 int Curl_gskit_init(void);
 void Curl_gskit_cleanup(void);
-CURLcode Curl_gskit_connect(struct connectdata * conn, int sockindex);
-CURLcode Curl_gskit_connect_nonblocking(struct connectdata * conn,
-                                        int sockindex, bool * done);
+CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
+                                        int sockindex, bool *done);
 void Curl_gskit_close(struct connectdata *conn, int sockindex);
-int Curl_gskit_close_all(struct SessionHandle * data);
-int Curl_gskit_shutdown(struct connectdata * conn, int sockindex);
+int Curl_gskit_shutdown(struct connectdata *conn, int sockindex);
 
-size_t Curl_gskit_version(char * buffer, size_t size);
-int Curl_gskit_check_cxn(struct connectdata * cxn);
+size_t Curl_gskit_version(char *buffer, size_t size);
+int Curl_gskit_check_cxn(struct connectdata *cxn);
+
+/* Set the API backend definition to GSKit */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_GSKIT
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
 
 /* API setup for GSKit */
 #define curlssl_init Curl_gskit_init
@@ -50,7 +55,7 @@ int Curl_gskit_check_cxn(struct connectdata * cxn);
 
 /*  No session handling for GSKit */
 #define curlssl_session_free(x) Curl_nop_stmt
-#define curlssl_close_all Curl_gskit_close_all
+#define curlssl_close_all(x) ((void)x)
 #define curlssl_close Curl_gskit_close
 #define curlssl_shutdown(x,y) Curl_gskit_shutdown(x,y)
 #define curlssl_set_engine(x,y) CURLE_NOT_BUILT_IN
@@ -59,7 +64,8 @@ int Curl_gskit_check_cxn(struct connectdata * cxn);
 #define curlssl_version Curl_gskit_version
 #define curlssl_check_cxn(x) Curl_gskit_check_cxn(x)
 #define curlssl_data_pending(x,y) 0
-#define CURL_SSL_BACKEND CURLSSLBACKEND_GSKIT
+#define curlssl_random(x,y,z) -1
+
 #endif /* USE_GSKIT */
 
 #endif /* HEADER_CURL_GSKIT_H */
diff --git a/Utilities/cmcurl/lib/vtls/gtls.c b/Utilities/cmcurl/lib/vtls/gtls.c
index d64f95d..c54dfc1 100644
--- a/Utilities/cmcurl/lib/vtls/gtls.c
+++ b/Utilities/cmcurl/lib/vtls/gtls.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,12 +32,14 @@
 
 #ifdef USE_GNUTLS
 
+#include <gnutls/abstract.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 
 #ifdef USE_GNUTLS_NETTLE
 #include <gnutls/crypto.h>
 #include <nettle/md5.h>
+#include <nettle/sha2.h>
 #else
 #include <gcrypt.h>
 #endif
@@ -52,9 +54,8 @@
 #include "select.h"
 #include "rawstr.h"
 #include "warnless.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "x509asn1.h"
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -91,14 +92,23 @@ static bool gtls_inited = FALSE;
 #    define GNUTLS_MAPS_WINSOCK_ERRORS 1
 #  endif
 
-#  ifdef USE_NGHTTP2
-#    undef HAS_ALPN
-#    if (GNUTLS_VERSION_NUMBER >= 0x030200)
-#      define HAS_ALPN
-#    endif
+#  if (GNUTLS_VERSION_NUMBER >= 0x030200)
+#    define HAS_ALPN
+#  endif
+
+#  if (GNUTLS_VERSION_NUMBER >= 0x03020d)
+#    define HAS_OCSP
+#  endif
+
+#  if (GNUTLS_VERSION_NUMBER >= 0x030306)
+#    define HAS_CAPATH
 #  endif
 #endif
 
+#ifdef HAS_OCSP
+# include <gnutls/ocsp.h>
+#endif
+
 /*
  * Custom push and pull callback functions used by GNU TLS to read and write
  * to the socket.  These functions are simple wrappers to send() and recv()
@@ -203,7 +213,7 @@ static void showtime(struct SessionHandle *data,
 
   snprintf(data->state.buffer,
            BUFSIZE,
-           "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT\n",
+           "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
            text,
            Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
            tm->tm_mday,
@@ -222,7 +232,7 @@ static gnutls_datum_t load_file (const char *file)
   long filelen;
   void *ptr;
 
-  if(!(f = fopen(file, "r")))
+  if(!(f = fopen(file, "rb")))
     return loaded_file;
   if(fseek(f, 0, SEEK_END) != 0
      || (filelen = ftell(f)) < 0
@@ -306,8 +316,6 @@ static CURLcode handshake(struct connectdata *conn,
         gnutls_record_get_direction(session)?
         ssl_connect_2_writing:ssl_connect_2_reading;
       continue;
-      if(nonblocking)
-        return CURLE_OK;
     }
     else if((rc < 0) && !gnutls_error_is_fatal(rc)) {
       const char *strerr = NULL;
@@ -320,7 +328,8 @@ static CURLcode handshake(struct connectdata *conn,
       if(strerr == NULL)
         strerr = gnutls_strerror(rc);
 
-      failf(data, "gnutls_handshake() warning: %s", strerr);
+      infof(data, "gnutls_handshake() warning: %s\n", strerr);
+      continue;
     }
     else if(rc < 0) {
       const char *strerr = NULL;
@@ -393,10 +402,6 @@ gtls_connect_step1(struct connectdata *conn,
   const char* prioritylist;
   const char *err = NULL;
 #endif
-#ifdef HAS_ALPN
-  int protocols_size = 2;
-  gnutls_datum_t protocols[2];
-#endif
 
   if(conn->ssl[sockindex].state == ssl_connection_complete)
     /* to make us tolerant against being called more than once for the
@@ -464,6 +469,24 @@ gtls_connect_step1(struct connectdata *conn,
             rc, data->set.ssl.CAfile);
   }
 
+#ifdef HAS_CAPATH
+  if(data->set.ssl.CApath) {
+    /* set the trusted CA cert directory */
+    rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
+                                                data->set.ssl.CApath,
+                                                GNUTLS_X509_FMT_PEM);
+    if(rc < 0) {
+      infof(data, "error reading ca cert file %s (%s)\n",
+            data->set.ssl.CAfile, gnutls_strerror(rc));
+      if(data->set.ssl.verifypeer)
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+    else
+      infof(data, "found %d certificates in %s\n",
+            rc, data->set.ssl.CApath);
+  }
+#endif
+
   if(data->set.ssl.CRLfile) {
     /* set the CRL list file */
     rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
@@ -610,19 +633,25 @@ gtls_connect_step1(struct connectdata *conn,
 #endif
 
 #ifdef HAS_ALPN
-  if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
-    if(data->set.ssl_enable_alpn) {
-      protocols[0].data = NGHTTP2_PROTO_VERSION_ID;
-      protocols[0].size = NGHTTP2_PROTO_VERSION_ID_LEN;
-      protocols[1].data = ALPN_HTTP_1_1;
-      protocols[1].size = ALPN_HTTP_1_1_LENGTH;
-      gnutls_alpn_set_protocols(session, protocols, protocols_size, 0);
-      infof(data, "ALPN, offering %s, %s\n", NGHTTP2_PROTO_VERSION_ID,
-            ALPN_HTTP_1_1);
-    }
-    else {
-      infof(data, "SSL, can't negotiate HTTP/2.0 without ALPN\n");
+  if(data->set.ssl_enable_alpn) {
+    int cur = 0;
+    gnutls_datum_t protocols[2];
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
+      protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID;
+      protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN;
+      cur++;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
     }
+#endif
+
+    protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
+    protocols[cur].size = ALPN_HTTP_1_1_LENGTH;
+    cur++;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    gnutls_alpn_set_protocols(session, protocols, cur, 0);
   }
 #endif
 
@@ -644,13 +673,21 @@ gtls_connect_step1(struct connectdata *conn,
   if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
     rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
                                 conn->ssl[sockindex].srp_client_cred);
-    if(rc != GNUTLS_E_SUCCESS)
+    if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
   }
   else
 #endif
+  {
     rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
                                 conn->ssl[sockindex].cred);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
 
   /* set the connection handle (file descriptor for the socket) */
   gnutls_transport_set_ptr(session,
@@ -663,6 +700,16 @@ gtls_connect_step1(struct connectdata *conn,
   /* lowat must be set to zero when using custom push and pull functions. */
   gnutls_transport_set_lowat(session, 0);
 
+#ifdef HAS_OCSP
+  if(data->set.ssl.verifystatus) {
+    rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif
+
   /* This might be a reconnect, so we check for a session ID in the cache
      to speed up things */
 
@@ -677,6 +724,62 @@ gtls_connect_step1(struct connectdata *conn,
   return CURLE_OK;
 }
 
+static CURLcode pkp_pin_peer_pubkey(gnutls_x509_crt_t cert,
+                                    const char *pinnedpubkey)
+{
+  /* Scratch */
+  size_t len1 = 0, len2 = 0;
+  unsigned char *buff1 = NULL;
+
+  gnutls_pubkey_t key = NULL;
+
+  /* Result is returned to caller */
+  int ret = 0;
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+  /* if a path wasn't specified, don't pin */
+  if(NULL == pinnedpubkey)
+    return CURLE_OK;
+
+  if(NULL == cert)
+    return result;
+
+  do {
+    /* Begin Gyrations to get the public key     */
+    gnutls_pubkey_init(&key);
+
+    ret = gnutls_pubkey_import_x509(key, cert, 0);
+    if(ret < 0)
+      break; /* failed */
+
+    ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
+    if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
+      break; /* failed */
+
+    buff1 = malloc(len1);
+    if(NULL == buff1)
+      break; /* failed */
+
+    len2 = len1;
+
+    ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
+    if(ret < 0 || len1 != len2)
+      break; /* failed */
+
+    /* End Gyrations */
+
+    /* The one good exit point */
+    result = Curl_pin_peer_pubkey(pinnedpubkey, buff1, len1);
+  } while(0);
+
+  if(NULL != key)
+    gnutls_pubkey_deinit(key);
+
+  Curl_safefree(buff1);
+
+  return result;
+}
+
 static Curl_recv gtls_recv;
 static Curl_send gtls_send;
 
@@ -686,8 +789,8 @@ gtls_connect_step3(struct connectdata *conn,
 {
   unsigned int cert_list_size;
   const gnutls_datum_t *chainp;
-  unsigned int verify_status;
-  gnutls_x509_crt_t x509_cert,x509_issuer;
+  unsigned int verify_status = 0;
+  gnutls_x509_crt_t x509_cert, x509_issuer;
   gnutls_datum_t issuerp;
   char certbuf[256] = ""; /* big enough? */
   size_t size;
@@ -698,13 +801,23 @@ gtls_connect_step3(struct connectdata *conn,
   struct SessionHandle *data = conn->data;
   gnutls_session_t session = conn->ssl[sockindex].session;
   int rc;
-  int incache;
+  bool incache;
   void *ssl_sessionid;
 #ifdef HAS_ALPN
   gnutls_datum_t proto;
 #endif
   CURLcode result = CURLE_OK;
 
+  gnutls_protocol_t version = gnutls_protocol_get_version(session);
+
+  /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
+  ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
+                                     gnutls_cipher_get(session),
+                                     gnutls_mac_get(session));
+
+  infof(data, "SSL connection using %s / %s\n",
+        gnutls_protocol_get_name(version), ptr);
+
   /* This function will return the peer's raw certificate (chain) as sent by
      the peer. These certificates are in raw format (DER encoded for
      X.509). In case of a X.509 then a certificate list may be present. The
@@ -735,6 +848,23 @@ gtls_connect_step3(struct connectdata *conn,
     infof(data, "\t common name: WARNING couldn't obtain\n");
   }
 
+  if(data->set.ssl.certinfo && chainp) {
+    unsigned int i;
+
+    result = Curl_ssl_init_certinfo(data, cert_list_size);
+    if(result)
+      return result;
+
+    for(i = 0; i < cert_list_size; i++) {
+      const char *beg = (const char *) chainp[i].data;
+      const char *end = beg + chainp[i].size;
+
+      result = Curl_extract_certinfo(conn, i, beg, end);
+      if(result)
+        return result;
+    }
+  }
+
   if(data->set.ssl.verifypeer) {
     /* This function will try to verify the peer's certificate and return its
        status (trusted, invalid etc.). The value of status should be one or
@@ -766,6 +896,111 @@ gtls_connect_step3(struct connectdata *conn,
   else
     infof(data, "\t server certificate verification SKIPPED\n");
 
+#ifdef HAS_OCSP
+  if(data->set.ssl.verifystatus) {
+    if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
+      gnutls_datum_t status_request;
+      gnutls_ocsp_resp_t ocsp_resp;
+
+      gnutls_ocsp_cert_status_t status;
+      gnutls_x509_crl_reason_t reason;
+
+      rc = gnutls_ocsp_status_request_get(session, &status_request);
+
+      infof(data, "\t server certificate status verification FAILED\n");
+
+      if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+        failf(data, "No OCSP response received");
+        return CURLE_SSL_INVALIDCERTSTATUS;
+      }
+
+      if(rc < 0) {
+        failf(data, "Invalid OCSP response received");
+        return CURLE_SSL_INVALIDCERTSTATUS;
+      }
+
+      gnutls_ocsp_resp_init(&ocsp_resp);
+
+      rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
+      if(rc < 0) {
+        failf(data, "Invalid OCSP response received");
+        return CURLE_SSL_INVALIDCERTSTATUS;
+      }
+
+      rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
+                                       &status, NULL, NULL, NULL, &reason);
+
+      switch(status) {
+      case GNUTLS_OCSP_CERT_GOOD:
+        break;
+
+      case GNUTLS_OCSP_CERT_REVOKED: {
+        const char *crl_reason;
+
+        switch(reason) {
+          default:
+          case GNUTLS_X509_CRLREASON_UNSPECIFIED:
+            crl_reason = "unspecified reason";
+            break;
+
+          case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
+            crl_reason = "private key compromised";
+            break;
+
+          case GNUTLS_X509_CRLREASON_CACOMPROMISE:
+            crl_reason = "CA compromised";
+            break;
+
+          case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
+            crl_reason = "affiliation has changed";
+            break;
+
+          case GNUTLS_X509_CRLREASON_SUPERSEDED:
+            crl_reason = "certificate superseded";
+            break;
+
+          case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
+            crl_reason = "operation has ceased";
+            break;
+
+          case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
+            crl_reason = "certificate is on hold";
+            break;
+
+          case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
+            crl_reason = "will be removed from delta CRL";
+            break;
+
+          case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
+            crl_reason = "privilege withdrawn";
+            break;
+
+          case GNUTLS_X509_CRLREASON_AACOMPROMISE:
+            crl_reason = "AA compromised";
+            break;
+        }
+
+        failf(data, "Server certificate was revoked: %s", crl_reason);
+        break;
+      }
+
+      default:
+      case GNUTLS_OCSP_CERT_UNKNOWN:
+        failf(data, "Server certificate status is unknown");
+        break;
+      }
+
+      gnutls_ocsp_resp_deinit(ocsp_resp);
+
+      return CURLE_SSL_INVALIDCERTSTATUS;
+    }
+    else
+      infof(data, "\t server certificate status verification OK\n");
+  }
+  else
+    infof(data, "\t server certificate status verification SKIPPED\n");
+#endif
+
   /* initialize an X.509 certificate structure. */
   gnutls_x509_crt_init(&x509_cert);
 
@@ -778,14 +1013,16 @@ gtls_connect_step3(struct connectdata *conn,
     gnutls_x509_crt_init(&x509_issuer);
     issuerp = load_file(data->set.ssl.issuercert);
     gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
-    rc = gnutls_x509_crt_check_issuer(x509_cert,x509_issuer);
+    rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
+    gnutls_x509_crt_deinit(x509_issuer);
     unload_file(issuerp);
     if(rc <= 0) {
       failf(data, "server certificate issuer check failed (IssuerCert: %s)",
             data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
+      gnutls_x509_crt_deinit(x509_cert);
       return CURLE_SSL_ISSUER_ERROR;
     }
-    infof(data,"\t server certificate issuer check OK (Issuer Cert: %s)\n",
+    infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n",
           data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
   }
 
@@ -868,6 +1105,7 @@ gtls_connect_step3(struct connectdata *conn,
   if(certclock == (time_t)-1) {
     if(data->set.ssl.verifypeer) {
       failf(data, "server cert expiration date verify failed");
+      gnutls_x509_crt_deinit(x509_cert);
       return CURLE_SSL_CONNECT_ERROR;
     }
     else
@@ -877,6 +1115,7 @@ gtls_connect_step3(struct connectdata *conn,
     if(certclock < time(NULL)) {
       if(data->set.ssl.verifypeer) {
         failf(data, "server certificate expiration date has passed.");
+        gnutls_x509_crt_deinit(x509_cert);
         return CURLE_PEER_FAILED_VERIFICATION;
       }
       else
@@ -891,6 +1130,7 @@ gtls_connect_step3(struct connectdata *conn,
   if(certclock == (time_t)-1) {
     if(data->set.ssl.verifypeer) {
       failf(data, "server cert activation date verify failed");
+      gnutls_x509_crt_deinit(x509_cert);
       return CURLE_SSL_CONNECT_ERROR;
     }
     else
@@ -900,6 +1140,7 @@ gtls_connect_step3(struct connectdata *conn,
     if(certclock > time(NULL)) {
       if(data->set.ssl.verifypeer) {
         failf(data, "server certificate not activated yet.");
+        gnutls_x509_crt_deinit(x509_cert);
         return CURLE_PEER_FAILED_VERIFICATION;
       }
       else
@@ -909,9 +1150,18 @@ gtls_connect_step3(struct connectdata *conn,
       infof(data, "\t server certificate activation date OK\n");
   }
 
+  ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+  if(ptr) {
+    result = pkp_pin_peer_pubkey(x509_cert, ptr);
+    if(result != CURLE_OK) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      gnutls_x509_crt_deinit(x509_cert);
+      return result;
+    }
+  }
+
   /* Show:
 
-  - ciphers used
   - subject
   - start date
   - expire date
@@ -951,14 +1201,6 @@ gtls_connect_step3(struct connectdata *conn,
   /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
   infof(data, "\t compression: %s\n", ptr);
 
-  /* the name of the cipher used. ie 3DES. */
-  ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
-  infof(data, "\t cipher: %s\n", ptr);
-
-  /* the MAC algorithms name. ie SHA1 */
-  ptr = gnutls_mac_get_name(gnutls_mac_get(session));
-  infof(data, "\t MAC: %s\n", ptr);
-
 #ifdef HAS_ALPN
   if(data->set.ssl_enable_alpn) {
     rc = gnutls_alpn_get_selected_protocol(session, &proto);
@@ -966,19 +1208,21 @@ gtls_connect_step3(struct connectdata *conn,
       infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
           proto.data);
 
+#ifdef USE_NGHTTP2
       if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN &&
-        memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
-        NGHTTP2_PROTO_VERSION_ID_LEN) == 0) {
-        conn->negnpn = NPN_HTTP2;
+         !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
+                 NGHTTP2_PROTO_VERSION_ID_LEN)) {
+        conn->negnpn = CURL_HTTP_VERSION_2_0;
       }
-      else if(proto.size == ALPN_HTTP_1_1_LENGTH && memcmp(ALPN_HTTP_1_1,
-          proto.data, ALPN_HTTP_1_1_LENGTH) == 0) {
-        conn->negnpn = NPN_HTTP1_1;
+      else
+#endif
+      if(proto.size == ALPN_HTTP_1_1_LENGTH &&
+         !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
       }
     }
-    else {
+    else
       infof(data, "ALPN, server did not agree to a protocol\n");
-    }
   }
 #endif
 
@@ -1079,12 +1323,12 @@ Curl_gtls_connect(struct connectdata *conn,
                   int sockindex)
 
 {
-  CURLcode retcode;
+  CURLcode result;
   bool done = FALSE;
 
-  retcode = gtls_connect_common(conn, sockindex, FALSE, &done);
-  if(retcode)
-    return retcode;
+  result = gtls_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
 
   DEBUGASSERT(done);
 
@@ -1110,12 +1354,6 @@ static ssize_t gtls_send(struct connectdata *conn,
   return rc;
 }
 
-void Curl_gtls_close_all(struct SessionHandle *data)
-{
-  /* FIX: make the OpenSSL code more generic and use parts of it here */
-  (void)data;
-}
-
 static void close_one(struct connectdata *conn,
                       int idx)
 {
@@ -1232,10 +1470,10 @@ static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
   if(ret == GNUTLS_E_REHANDSHAKE) {
     /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
        proper way" takes a whole lot of work. */
-    CURLcode rc = handshake(conn, num, FALSE, FALSE);
-    if(rc)
+    CURLcode result = handshake(conn, num, FALSE, FALSE);
+    if(result)
       /* handshake() writes error message on its own */
-      *curlcode = rc;
+      *curlcode = result;
     else
       *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
     return -1;
@@ -1320,4 +1558,32 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
 #endif
 }
 
+void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum, /* output */
+                      size_t sha256len)
+{
+#if defined(USE_GNUTLS_NETTLE)
+  struct sha256_ctx SHA256pw;
+  sha256_init(&SHA256pw);
+  sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
+  sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
+#elif defined(USE_GNUTLS)
+  gcry_md_hd_t SHA256pw;
+  gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0);
+  gcry_md_write(SHA256pw, tmp, tmplen);
+  memcpy(sha256sum, gcry_md_read (SHA256pw, 0), sha256len);
+  gcry_md_close(SHA256pw);
+#endif
+}
+
+bool Curl_gtls_cert_status_request(void)
+{
+#ifdef HAS_OCSP
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
 #endif /* USE_GNUTLS */
diff --git a/Utilities/cmcurl/lib/vtls/gtls.h b/Utilities/cmcurl/lib/vtls/gtls.h
index cd6152c..0afd9b9 100644
--- a/Utilities/cmcurl/lib/vtls/gtls.h
+++ b/Utilities/cmcurl/lib/vtls/gtls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,10 +35,6 @@ CURLcode Curl_gtls_connect_nonblocking(struct connectdata *conn,
                                        int sockindex,
                                        bool *done);
 
-/* tell GnuTLS to close down all open information regarding connections (and
-   thus session ID caching etc) */
-void Curl_gtls_close_all(struct SessionHandle *data);
-
  /* close a SSL connection */
 void Curl_gtls_close(struct connectdata *conn, int sockindex);
 
@@ -52,9 +48,21 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
                       size_t tmplen,
                       unsigned char *md5sum, /* output */
                       size_t md5len);
+void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum, /* output */
+                      size_t sha256len);
 
-/* this backend provides these functions: */
-#define have_curlssl_md5sum 1
+bool Curl_gtls_cert_status_request(void);
+
+/* Set the API backend definition to GnuTLS */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_GNUTLS
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
 
 /* API setup for GnuTLS */
 #define curlssl_init Curl_gtls_init
@@ -62,18 +70,19 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
 #define curlssl_connect Curl_gtls_connect
 #define curlssl_connect_nonblocking Curl_gtls_connect_nonblocking
 #define curlssl_session_free(x)  Curl_gtls_session_free(x)
-#define curlssl_close_all Curl_gtls_close_all
+#define curlssl_close_all(x) ((void)x)
 #define curlssl_close Curl_gtls_close
 #define curlssl_shutdown(x,y) Curl_gtls_shutdown(x,y)
-#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN)
-#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN)
-#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
 #define curlssl_version Curl_gtls_version
-#define curlssl_check_cxn(x) (x=x, -1)
-#define curlssl_data_pending(x,y) (x=x, y=y, 0)
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
 #define curlssl_random(x,y,z) Curl_gtls_random(x,y,z)
 #define curlssl_md5sum(a,b,c,d) Curl_gtls_md5sum(a,b,c,d)
-#define CURL_SSL_BACKEND CURLSSLBACKEND_GNUTLS
+#define curlssl_sha256sum(a,b,c,d) Curl_gtls_sha256sum(a,b,c,d)
+#define curlssl_cert_status_request() Curl_gtls_cert_status_request()
 
 #endif /* USE_GNUTLS */
 #endif /* HEADER_CURL_GTLS_H */
diff --git a/Utilities/cmcurl/lib/vtls/nss.c b/Utilities/cmcurl/lib/vtls/nss.c
index 83b3e32..91727c7 100644
--- a/Utilities/cmcurl/lib/vtls/nss.c
+++ b/Utilities/cmcurl/lib/vtls/nss.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -38,10 +38,7 @@
 #include "select.h"
 #include "vtls.h"
 #include "llist.h"
-
-#define _MPRINTF_REPLACE /* use the internal *printf() functions */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "nssg.h"
 #include <nspr.h>
 #include <nss.h>
@@ -59,13 +56,20 @@
 #include <base64.h>
 #include <cert.h>
 #include <prerror.h>
+#include <keyhi.h>        /* for SECKEY_DestroyPublicKey() */
+
+#define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH)
+
+#if NSSVERNUM >= 0x030f00 /* 3.15.0 */
+#include <ocsp.h>
+#endif
 
-#include "curl_memory.h"
 #include "rawstr.h"
 #include "warnless.h"
 #include "x509asn1.h"
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #define SSL_DIR "/etc/pki/nssdb"
@@ -343,7 +347,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
   CK_BBOOL ckfalse = CK_FALSE;
   CK_ATTRIBUTE attrs[/* max count of attributes */ 4];
   int attr_cnt = 0;
-  CURLcode err = (cacert)
+  CURLcode result = (cacert)
     ? CURLE_SSL_CACERT_BADFILE
     : CURLE_SSL_CERTPROBLEM;
 
@@ -355,7 +359,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
   slot = PK11_FindSlotByName(slot_name);
   free(slot_name);
   if(!slot)
-    return err;
+    return result;
 
   PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class));
   PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
@@ -370,7 +374,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
   obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE);
   PK11_FreeSlot(slot);
   if(!obj)
-    return err;
+    return result;
 
   if(!Curl_llist_insert_next(ssl->obj_list, ssl->obj_list->tail, obj)) {
     PK11_DestroyGenericObject(obj);
@@ -405,16 +409,16 @@ static void nss_destroy_crl_item(void *user, void *ptr)
 static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
                               const char *filename, PRBool cacert)
 {
-  CURLcode err = (cacert)
+  CURLcode result = (cacert)
     ? CURLE_SSL_CACERT_BADFILE
     : CURLE_SSL_CERTPROBLEM;
 
   /* libnsspem.so leaks memory if the requested file does not exist.  For more
    * details, go to <https://bugzilla.redhat.com/734760>. */
   if(is_file(filename))
-    err = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);
+    result = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);
 
-  if(CURLE_OK == err && !cacert) {
+  if(!result && !cacert) {
     /* we have successfully loaded a client certificate */
     CERTCertificate *cert;
     char *nickname = NULL;
@@ -436,7 +440,7 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
     }
   }
 
-  return err;
+  return result;
 }
 
 /* add given CRL to cache if it is not already there */
@@ -448,7 +452,7 @@ static CURLcode nss_cache_crl(SECItem *crl_der)
     /* CRL already cached */
     SEC_DestroyCrl(crl);
     SECITEM_FreeItem(crl_der, PR_TRUE);
-    return CURLE_SSL_CRL_BADFILE;
+    return CURLE_OK;
   }
 
   /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */
@@ -542,14 +546,15 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
 {
   PK11SlotInfo *slot;
   SECStatus status;
-  CURLcode rv;
+  CURLcode result;
   struct ssl_connect_data *ssl = conn->ssl;
+
   (void)sockindex; /* unused */
 
-  rv = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
-  if(CURLE_OK != rv) {
+  result = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
+  if(result) {
     PR_SetError(SEC_ERROR_BAD_KEY, 0);
-    return rv;
+    return result;
   }
 
   slot = PK11_FindSlotByName("PEM Token #1");
@@ -563,9 +568,8 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
   status = PK11_Authenticate(slot, PR_TRUE,
                              conn->data->set.str[STRING_KEY_PASSWD]);
   PK11_FreeSlot(slot);
-  return (SECSuccess == status)
-    ? CURLE_OK
-    : CURLE_SSL_CERTPROBLEM;
+
+  return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM;
 }
 
 static int display_error(struct connectdata *conn, PRInt32 err,
@@ -588,35 +592,35 @@ static CURLcode cert_stuff(struct connectdata *conn, int sockindex,
                            char *cert_file, char *key_file)
 {
   struct SessionHandle *data = conn->data;
-  CURLcode rv;
+  CURLcode result;
 
   if(cert_file) {
-    rv = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE);
-    if(CURLE_OK != rv) {
+    result = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE);
+    if(result) {
       const PRErrorCode err = PR_GetError();
       if(!display_error(conn, err, cert_file)) {
         const char *err_name = nss_error_to_name(err);
         failf(data, "unable to load client cert: %d (%s)", err, err_name);
       }
 
-      return rv;
+      return result;
     }
   }
 
   if(key_file || (is_file(cert_file))) {
     if(key_file)
-      rv = nss_load_key(conn, sockindex, key_file);
+      result = nss_load_key(conn, sockindex, key_file);
     else
       /* In case the cert file also has the key */
-      rv = nss_load_key(conn, sockindex, cert_file);
-    if(CURLE_OK != rv) {
+      result = nss_load_key(conn, sockindex, cert_file);
+    if(result) {
       const PRErrorCode err = PR_GetError();
       if(!display_error(conn, err, key_file)) {
         const char *err_name = nss_error_to_name(err);
         failf(data, "unable to load client key: %d (%s)", err, err_name);
       }
 
-      return rv;
+      return result;
     }
   }
 
@@ -626,6 +630,7 @@ static CURLcode cert_stuff(struct connectdata *conn, int sockindex,
 static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg)
 {
   (void)slot; /* unused */
+
   if(retry || NULL == arg)
     return NULL;
   else
@@ -638,6 +643,34 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
                                     PRBool isServer)
 {
   struct connectdata *conn = (struct connectdata *)arg;
+
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  if(conn->data->set.ssl.verifystatus) {
+    SECStatus cacheResult;
+
+    const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
+    if(!csa) {
+      failf(conn->data, "Invalid OCSP response");
+      return SECFailure;
+    }
+
+    if(csa->len == 0) {
+      failf(conn->data, "No OCSP response received");
+      return SECFailure;
+    }
+
+    cacheResult = CERT_CacheOCSPResponseFromSideChannel(
+      CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd),
+      PR_Now(), &csa->items[0], arg
+    );
+
+    if(cacheResult != SECSuccess) {
+      failf(conn->data, "Invalid OCSP response");
+      return cacheResult;
+    }
+  }
+#endif
+
   if(!conn->data->set.ssl.verifypeer) {
     infof(conn->data, "skipping SSL peer certificate verification\n");
     return SECSuccess;
@@ -651,7 +684,6 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
  */
 static void HandshakeCallback(PRFileDesc *sock, void *arg)
 {
-#ifdef USE_NGHTTP2
   struct connectdata *conn = (struct connectdata*) arg;
   unsigned int buflenmax = 50;
   unsigned char buf[50];
@@ -665,36 +697,94 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
   if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) {
 
     switch(state) {
-      case SSL_NEXT_PROTO_NO_SUPPORT:
-      case SSL_NEXT_PROTO_NO_OVERLAP:
-        infof(conn->data, "TLS, neither ALPN nor NPN succeeded\n");
-        return;
+    case SSL_NEXT_PROTO_NO_SUPPORT:
+    case SSL_NEXT_PROTO_NO_OVERLAP:
+      infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n");
+      return;
 #ifdef SSL_ENABLE_ALPN
-      case SSL_NEXT_PROTO_SELECTED:
-        infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf);
-        break;
+    case SSL_NEXT_PROTO_SELECTED:
+      infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf);
+      break;
 #endif
-      case SSL_NEXT_PROTO_NEGOTIATED:
-        infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf);
-        break;
+    case SSL_NEXT_PROTO_NEGOTIATED:
+      infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf);
+      break;
     }
 
+#ifdef USE_NGHTTP2
     if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN &&
-       memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)
-       == 0) {
-      conn->negnpn = NPN_HTTP2;
+       !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) {
+      conn->negnpn = CURL_HTTP_VERSION_2_0;
     }
-    else if(buflen == ALPN_HTTP_1_1_LENGTH && memcmp(ALPN_HTTP_1_1, buf,
-                                                     ALPN_HTTP_1_1_LENGTH)) {
-      conn->negnpn = NPN_HTTP1_1;
+    else
+#endif
+    if(buflen == ALPN_HTTP_1_1_LENGTH &&
+       !memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
+      conn->negnpn = CURL_HTTP_VERSION_1_1;
     }
   }
-#else
-  (void)sock;
-  (void)arg;
-#endif
 }
 
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data,
+                                       PRBool *canFalseStart)
+{
+  struct connectdata *conn = client_data;
+  struct SessionHandle *data = conn->data;
+
+  SSLChannelInfo channelInfo;
+  SSLCipherSuiteInfo cipherInfo;
+
+  SECStatus rv;
+  PRBool negotiatedExtension;
+
+  *canFalseStart = PR_FALSE;
+
+  if(SSL_GetChannelInfo(sock, &channelInfo, sizeof(channelInfo)) != SECSuccess)
+    return SECFailure;
+
+  if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
+                            sizeof(cipherInfo)) != SECSuccess)
+    return SECFailure;
+
+  /* Prevent version downgrade attacks from TLS 1.2, and avoid False Start for
+   * TLS 1.3 and later. See https://bugzilla.mozilla.org/show_bug.cgi?id=861310
+   */
+  if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2)
+    goto end;
+
+  /* Only allow ECDHE key exchange algorithm.
+   * See https://bugzilla.mozilla.org/show_bug.cgi?id=952863 */
+  if(cipherInfo.keaType != ssl_kea_ecdh)
+    goto end;
+
+  /* Prevent downgrade attacks on the symmetric cipher. We do not allow CBC
+   * mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt
+   * design. See https://bugzilla.mozilla.org/show_bug.cgi?id=1109766 */
+  if(cipherInfo.symCipher != ssl_calg_aes_gcm)
+    goto end;
+
+  /* Enforce ALPN or NPN to do False Start, as an indicator of server
+   * compatibility. */
+  rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn,
+                                        &negotiatedExtension);
+  if(rv != SECSuccess || !negotiatedExtension) {
+    rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn,
+                                          &negotiatedExtension);
+  }
+
+  if(rv != SECSuccess || !negotiatedExtension)
+    goto end;
+
+  *canFalseStart = PR_TRUE;
+
+  infof(data, "Trying TLS False Start\n");
+
+end:
+  return SECSuccess;
+}
+#endif
+
 static void display_cert_info(struct SessionHandle *data,
                               CERTCertificate *cert)
 {
@@ -723,8 +813,9 @@ static void display_cert_info(struct SessionHandle *data,
   PR_Free(common_name);
 }
 
-static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
+static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
 {
+  CURLcode result = CURLE_OK;
   SSLChannelInfo channel;
   SSLCipherSuiteInfo suite;
   CERTCertificate *cert;
@@ -743,7 +834,6 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
   }
 
   cert = SSL_PeerCertificate(sock);
-
   if(cert) {
     infof(conn->data, "Server certificate:\n");
 
@@ -768,21 +858,29 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
           cert2 = cert3;
         }
       }
-      Curl_ssl_init_certinfo(conn->data, i);
-      for(i = 0; cert; cert = cert2) {
-        Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data,
-                              (char *)cert->derCert.data + cert->derCert.len);
-        if(cert->isRoot) {
+
+      result = Curl_ssl_init_certinfo(conn->data, i);
+      if(!result) {
+        for(i = 0; cert; cert = cert2) {
+          result = Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data,
+                                         (char *)cert->derCert.data +
+                                                 cert->derCert.len);
+          if(result)
+            break;
+
+          if(cert->isRoot) {
+            CERT_DestroyCertificate(cert);
+            break;
+          }
+
+          cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
           CERT_DestroyCertificate(cert);
-          break;
         }
-        cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
-        CERT_DestroyCertificate(cert);
       }
     }
   }
 
-  return;
+  return result;
 }
 
 static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
@@ -820,7 +918,7 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
 static SECStatus check_issuer_cert(PRFileDesc *sock,
                                    char *issuer_nickname)
 {
-  CERTCertificate *cert,*cert_issuer,*issuer;
+  CERTCertificate *cert, *cert_issuer, *issuer;
   SECStatus res=SECSuccess;
   void *proto_win = NULL;
 
@@ -831,7 +929,7 @@ static SECStatus check_issuer_cert(PRFileDesc *sock,
   */
 
   cert = SSL_PeerCertificate(sock);
-  cert_issuer = CERT_FindCertIssuer(cert,PR_Now(),certUsageObjectSigner);
+  cert_issuer = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner);
 
   proto_win = SSL_RevealPinArg(sock);
   issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
@@ -848,6 +946,53 @@ static SECStatus check_issuer_cert(PRFileDesc *sock,
   return res;
 }
 
+static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
+                                const char *pinnedpubkey)
+{
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+  struct SessionHandle *data = connssl->data;
+  CERTCertificate *cert;
+
+  if(!pinnedpubkey)
+    /* no pinned public key specified */
+    return CURLE_OK;
+
+  /* get peer certificate */
+  cert = SSL_PeerCertificate(connssl->handle);
+  if(cert) {
+    /* extract public key from peer certificate */
+    SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
+    if(pubkey) {
+      /* encode the public key as DER */
+      SECItem *cert_der = PK11_DEREncodePublicKey(pubkey);
+      if(cert_der) {
+        /* compare the public key with the pinned public key */
+        result = Curl_pin_peer_pubkey(pinnedpubkey,
+                                      cert_der->data,
+                                      cert_der->len);
+        SECITEM_FreeItem(cert_der, PR_TRUE);
+      }
+      SECKEY_DestroyPublicKey(pubkey);
+    }
+    CERT_DestroyCertificate(cert);
+  }
+
+  /* report the resulting status */
+  switch(result) {
+  case CURLE_OK:
+    infof(data, "pinned public key verified successfully!\n");
+    break;
+  case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
+    failf(data, "failed to verify pinned public key");
+    break;
+  default:
+    /* OOM, etc. */
+    break;
+  }
+
+  return result;
+}
+
 /**
  *
  * Callback to pick the SSL client certificate.
@@ -935,36 +1080,6 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
   return SECSuccess;
 }
 
-/* This function is supposed to decide, which error codes should be used
- * to conclude server is TLS intolerant.
- *
- * taken from xulrunner - nsNSSIOLayer.cpp
- */
-static PRBool
-isTLSIntoleranceError(PRInt32 err)
-{
-  switch (err) {
-  case SSL_ERROR_BAD_MAC_ALERT:
-  case SSL_ERROR_BAD_MAC_READ:
-  case SSL_ERROR_HANDSHAKE_FAILURE_ALERT:
-  case SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT:
-  case SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE:
-  case SSL_ERROR_ILLEGAL_PARAMETER_ALERT:
-  case SSL_ERROR_NO_CYPHER_OVERLAP:
-  case SSL_ERROR_BAD_SERVER:
-  case SSL_ERROR_BAD_BLOCK_PADDING:
-  case SSL_ERROR_UNSUPPORTED_VERSION:
-  case SSL_ERROR_PROTOCOL_VERSION_ALERT:
-  case SSL_ERROR_RX_MALFORMED_FINISHED:
-  case SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE:
-  case SSL_ERROR_DECODE_ERROR_ALERT:
-  case SSL_ERROR_RX_UNKNOWN_ALERT:
-    return PR_TRUE;
-  default:
-    return PR_FALSE;
-  }
-}
-
 /* update blocking direction in case of PR_WOULD_BLOCK_ERROR */
 static void nss_update_connecting_state(ssl_connect_state state, void *secret)
 {
@@ -1019,6 +1134,7 @@ static PRStatus nspr_io_close(PRFileDesc *fd)
   return close_fn(fd);
 }
 
+/* data might be NULL */
 static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
 {
   NSSInitParameters initparams;
@@ -1056,11 +1172,12 @@ static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
   return CURLE_SSL_CACERT_BADFILE;
 }
 
+/* data might be NULL */
 static CURLcode nss_init(struct SessionHandle *data)
 {
   char *cert_dir;
   struct_stat st;
-  CURLcode rv;
+  CURLcode result;
 
   if(initialized)
     return CURLE_OK;
@@ -1102,14 +1219,15 @@ static CURLcode nss_init(struct SessionHandle *data)
     nspr_io_methods.close = nspr_io_close;
   }
 
-  rv = nss_init_core(data, cert_dir);
-  if(rv)
-    return rv;
+  result = nss_init_core(data, cert_dir);
+  if(result)
+    return result;
 
   if(num_enabled_ciphers() == 0)
     NSS_SetDomesticPolicy();
 
   initialized = 1;
+
   return CURLE_OK;
 }
 
@@ -1133,20 +1251,22 @@ int Curl_nss_init(void)
   return 1;
 }
 
+/* data might be NULL */
 CURLcode Curl_nss_force_init(struct SessionHandle *data)
 {
-  CURLcode rv;
+  CURLcode result;
   if(!nss_initlock) {
-    failf(data,
-          "unable to initialize NSS, curl_global_init() should have been "
-          "called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
+    if(data)
+      failf(data, "unable to initialize NSS, curl_global_init() should have "
+                  "been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
     return CURLE_FAILED_INIT;
   }
 
   PR_Lock(nss_initlock);
-  rv = nss_init(data);
+  result = nss_init(data);
   PR_Unlock(nss_initlock);
-  return rv;
+
+  return result;
 }
 
 /* Global cleanup */
@@ -1229,10 +1349,8 @@ void Curl_nss_close(struct connectdata *conn, int sockindex)
        * authentication data from a previous connection. */
       SSL_InvalidateSession(connssl->handle);
 
-    if(connssl->client_nickname != NULL) {
-      free(connssl->client_nickname);
-      connssl->client_nickname = NULL;
-    }
+    free(connssl->client_nickname);
+    connssl->client_nickname = NULL;
     /* destroy all NSS objects in order to avoid failure of NSS shutdown */
     Curl_llist_destroy(connssl->obj_list, NULL);
     connssl->obj_list = NULL;
@@ -1243,16 +1361,6 @@ void Curl_nss_close(struct connectdata *conn, int sockindex)
   }
 }
 
-/*
- * This function is called when the 'data' struct is going away. Close
- * down everything and free all resources!
- */
-int Curl_nss_close_all(struct SessionHandle *data)
-{
-  (void)data;
-  return 0;
-}
-
 /* return true if NSS can provide error code (and possibly msg) for the
    error */
 static bool is_nss_error(CURLcode err)
@@ -1295,9 +1403,9 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
   const char *capath = data->set.ssl.CApath;
 
   if(cafile) {
-    CURLcode rv = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
-    if(CURLE_OK != rv)
-      return rv;
+    CURLcode result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
+    if(result)
+      return result;
   }
 
   if(capath) {
@@ -1342,18 +1450,11 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
 static CURLcode nss_init_sslver(SSLVersionRange *sslver,
                                 struct SessionHandle *data)
 {
-  switch (data->set.ssl.version) {
+  switch(data->set.ssl.version) {
   default:
   case CURL_SSLVERSION_DEFAULT:
-    sslver->min = SSL_LIBRARY_VERSION_3_0;
-    if(data->state.ssl_connect_retry) {
-      infof(data, "TLS disabled due to previous handshake failure\n");
-      sslver->max = SSL_LIBRARY_VERSION_3_0;
-      return CURLE_OK;
-    }
-  /* intentional fall-through to default to highest TLS version if possible */
-
   case CURL_SSLVERSION_TLSv1:
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
 #ifdef SSL_LIBRARY_VERSION_TLS_1_2
     sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
 #elif defined SSL_LIBRARY_VERSION_TLS_1_1
@@ -1403,12 +1504,8 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
                                  struct SessionHandle *data,
                                  CURLcode curlerr)
 {
-  SSLVersionRange sslver;
   PRErrorCode err = 0;
 
-  /* reset the flag to avoid an infinite loop */
-  data->state.ssl_connect_retry = FALSE;
-
   if(is_nss_error(curlerr)) {
     /* read NSPR error code */
     err = PR_GetError();
@@ -1426,17 +1523,6 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
   Curl_llist_destroy(connssl->obj_list, NULL);
   connssl->obj_list = NULL;
 
-  if(connssl->handle
-      && (SSL_VersionRangeGet(connssl->handle, &sslver) == SECSuccess)
-      && (sslver.min == SSL_LIBRARY_VERSION_3_0)
-      && (sslver.max != SSL_LIBRARY_VERSION_3_0)
-      && isTLSIntoleranceError(err)) {
-    /* schedule reconnect through Curl_retry_request() */
-    data->state.ssl_connect_retry = TRUE;
-    infof(data, "Error in TLS handshake, trying SSLv3...\n");
-    return CURLE_OK;
-  }
-
   return curlerr;
 }
 
@@ -1464,27 +1550,13 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   struct SessionHandle *data = conn->data;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  CURLcode curlerr;
+  CURLcode result;
 
   SSLVersionRange sslver = {
     SSL_LIBRARY_VERSION_TLS_1_0,  /* min */
     SSL_LIBRARY_VERSION_TLS_1_0   /* max */
   };
 
-#ifdef USE_NGHTTP2
-#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN)
-  unsigned int alpn_protos_len = NGHTTP2_PROTO_VERSION_ID_LEN +
-      ALPN_HTTP_1_1_LENGTH + 2;
-  unsigned char alpn_protos[NGHTTP2_PROTO_VERSION_ID_LEN + ALPN_HTTP_1_1_LENGTH
-      + 2];
-  int cur = 0;
-#endif
-#endif
-
-
-  if(connssl->state == ssl_connection_complete)
-    return CURLE_OK;
-
   connssl->data = data;
 
   /* list of all NSS objects we need to destroy in Curl_nss_close() */
@@ -1494,13 +1566,13 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
 
   /* FIXME. NSS doesn't support multiple databases open at the same time. */
   PR_Lock(nss_initlock);
-  curlerr = nss_init(conn->data);
-  if(CURLE_OK != curlerr) {
+  result = nss_init(conn->data);
+  if(result) {
     PR_Unlock(nss_initlock);
     goto error;
   }
 
-  curlerr = CURLE_SSL_CONNECT_ERROR;
+  result = CURLE_SSL_CONNECT_ERROR;
 
   if(!mod) {
     char *configstring = aprintf("library=%s name=PEM", pem_library);
@@ -1517,7 +1589,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
         mod = NULL;
       }
       infof(data, "WARNING: failed to load NSS PEM library %s. Using "
-            "OpenSSL PEM certificates will not work.\n", pem_library);
+                  "OpenSSL PEM certificates will not work.\n", pem_library);
     }
   }
 
@@ -1560,12 +1632,9 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
     infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
 #endif
 
-  /* reset the flag to avoid an infinite loop */
-  data->state.ssl_connect_retry = FALSE;
-
   if(data->set.ssl.cipher_list) {
     if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
-      curlerr = CURLE_SSL_CIPHER;
+      result = CURLE_SSL_CIPHER;
       goto error;
     }
   }
@@ -1587,16 +1656,16 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
 
   if(data->set.ssl.verifypeer) {
     const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
-    if(CURLE_OK != rv) {
-      curlerr = rv;
+    if(rv) {
+      result = rv;
       goto error;
     }
   }
 
   if(data->set.ssl.CRLfile) {
     const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile);
-    if(CURLE_OK != rv) {
-      curlerr = rv;
+    if(rv) {
+      result = rv;
       goto error;
     }
     infof(data, "  CRLfile: %s\n", data->set.ssl.CRLfile);
@@ -1611,9 +1680,9 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
     else {
       CURLcode rv = cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
                                data->set.str[STRING_KEY]);
-      if(CURLE_OK != rv) {
+      if(rv) {
         /* failf() is already done in cert_stuff() */
-        curlerr = rv;
+        result = rv;
         goto error;
       }
     }
@@ -1626,7 +1695,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
 
   if(SSL_GetClientAuthDataHook(model, SelectClientCert,
                                (void *)connssl) != SECSuccess) {
-    curlerr = CURLE_SSL_CERTPROBLEM;
+    result = CURLE_SSL_CERTPROBLEM;
     goto error;
   }
 
@@ -1667,42 +1736,57 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
     SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
   }
 
-#ifdef USE_NGHTTP2
-  if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  if(data->set.ssl.verifystatus) {
+    if(SSL_OptionSet(connssl->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
+        != SECSuccess)
+      goto error;
+  }
+#endif
+
 #ifdef SSL_ENABLE_NPN
-    if(data->set.ssl_enable_npn) {
-      if(SSL_OptionSet(connssl->handle, SSL_ENABLE_NPN, PR_TRUE) != SECSuccess)
-        goto error;
-    }
+  if(SSL_OptionSet(connssl->handle, SSL_ENABLE_NPN, data->set.ssl_enable_npn
+        ? PR_TRUE : PR_FALSE) != SECSuccess)
+    goto error;
 #endif
 
 #ifdef SSL_ENABLE_ALPN
-    if(data->set.ssl_enable_alpn) {
-      if(SSL_OptionSet(connssl->handle, SSL_ENABLE_ALPN, PR_TRUE)
-          != SECSuccess)
-        goto error;
-    }
+  if(SSL_OptionSet(connssl->handle, SSL_ENABLE_ALPN, data->set.ssl_enable_alpn
+        ? PR_TRUE : PR_FALSE) != SECSuccess)
+    goto error;
+#endif
+
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+  if(data->set.ssl.falsestart) {
+    if(SSL_OptionSet(connssl->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
+        != SECSuccess)
+      goto error;
+
+    if(SSL_SetCanFalseStartCallback(connssl->handle, CanFalseStartCallback,
+        conn) != SECSuccess)
+      goto error;
+  }
 #endif
 
 #if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN)
-    if(data->set.ssl_enable_npn || data->set.ssl_enable_alpn) {
-      alpn_protos[cur] = NGHTTP2_PROTO_VERSION_ID_LEN;
-      cur++;
-      memcpy(&alpn_protos[cur], NGHTTP2_PROTO_VERSION_ID,
+  if(data->set.ssl_enable_npn || data->set.ssl_enable_alpn) {
+    int cur = 0;
+    unsigned char protocols[128];
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
+      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
+      memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
           NGHTTP2_PROTO_VERSION_ID_LEN);
       cur += NGHTTP2_PROTO_VERSION_ID_LEN;
-      alpn_protos[cur] = ALPN_HTTP_1_1_LENGTH;
-      cur++;
-      memcpy(&alpn_protos[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
-
-      if(SSL_SetNextProtoNego(connssl->handle, alpn_protos, alpn_protos_len)
-          != SECSuccess)
-        goto error;
-    }
-    else {
-      infof(data, "SSL, can't negotiate HTTP/2.0 with neither NPN nor ALPN\n");
     }
 #endif
+    protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
+    memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
+    cur += ALPN_HTTP_1_1_LENGTH;
+
+    if(SSL_SetNextProtoNego(connssl->handle, protocols, cur) != SECSuccess)
+      goto error;
   }
 #endif
 
@@ -1718,21 +1802,21 @@ error:
   if(model)
     PR_Close(model);
 
-  return nss_fail_connect(connssl, data, curlerr);
+  return nss_fail_connect(connssl, data, result);
 }
 
 static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   struct SessionHandle *data = conn->data;
-  CURLcode curlerr = CURLE_SSL_CONNECT_ERROR;
+  CURLcode result = CURLE_SSL_CONNECT_ERROR;
   PRUint32 timeout;
 
   /* check timeout situation */
   const long time_left = Curl_timeleft(data, NULL, TRUE);
   if(time_left < 0L) {
     failf(data, "timed out before SSL handshake");
-    curlerr = CURLE_OPERATION_TIMEDOUT;
+    result = CURLE_OPERATION_TIMEDOUT;
     goto error;
   }
 
@@ -1743,17 +1827,15 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
       /* blocking direction is updated by nss_update_connecting_state() */
       return CURLE_AGAIN;
     else if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
-      curlerr = CURLE_PEER_FAILED_VERIFICATION;
+      result = CURLE_PEER_FAILED_VERIFICATION;
     else if(conn->data->set.ssl.certverifyresult!=0)
-      curlerr = CURLE_SSL_CACERT;
+      result = CURLE_SSL_CACERT;
     goto error;
   }
 
-  connssl->state = ssl_connection_complete;
-  conn->recv[sockindex] = nss_recv;
-  conn->send[sockindex] = nss_send;
-
-  display_conn_info(conn, connssl->handle);
+  result = display_conn_info(conn, connssl->handle);
+  if(result)
+    goto error;
 
   if(data->set.str[STRING_SSL_ISSUERCERT]) {
     SECStatus ret = SECFailure;
@@ -1765,8 +1847,8 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
     }
 
     if(SECFailure == ret) {
-      infof(data,"SSL certificate issuer check failed\n");
-      curlerr = CURLE_SSL_ISSUER_ERROR;
+      infof(data, "SSL certificate issuer check failed\n");
+      result = CURLE_SSL_ISSUER_ERROR;
       goto error;
     }
     else {
@@ -1774,10 +1856,15 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
     }
   }
 
+  result = cmp_peer_pubkey(connssl, data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
+  if(result)
+    /* status already printed */
+    goto error;
+
   return CURLE_OK;
 
 error:
-  return nss_fail_connect(connssl, data, curlerr);
+  return nss_fail_connect(connssl, data, result);
 }
 
 static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
@@ -1786,26 +1873,29 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   struct SessionHandle *data = conn->data;
   const bool blocking = (done == NULL);
-  CURLcode rv;
+  CURLcode result;
+
+  if(connssl->state == ssl_connection_complete)
+    return CURLE_OK;
 
   if(connssl->connecting_state == ssl_connect_1) {
-    rv = nss_setup_connect(conn, sockindex);
-    if(rv)
+    result = nss_setup_connect(conn, sockindex);
+    if(result)
       /* we do not expect CURLE_AGAIN from nss_setup_connect() */
-      return rv;
+      return result;
 
     if(!blocking) {
       /* in non-blocking mode, set NSS non-blocking mode before handshake */
-      rv = nss_set_nonblock(connssl, data);
-      if(rv)
-        return rv;
+      result = nss_set_nonblock(connssl, data);
+      if(result)
+        return result;
     }
 
     connssl->connecting_state = ssl_connect_2;
   }
 
-  rv = nss_do_connect(conn, sockindex);
-  switch(rv) {
+  result = nss_do_connect(conn, sockindex);
+  switch(result) {
   case CURLE_OK:
     break;
   case CURLE_AGAIN:
@@ -1814,20 +1904,26 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
       return CURLE_OK;
     /* fall through */
   default:
-    return rv;
+    return result;
   }
 
   if(blocking) {
     /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
-    rv = nss_set_nonblock(connssl, data);
-    if(rv)
-      return rv;
+    result = nss_set_nonblock(connssl, data);
+    if(result)
+      return result;
   }
   else
     /* signal completed SSL handshake */
     *done = TRUE;
 
-  connssl->connecting_state = ssl_connect_done;
+  connssl->state = ssl_connection_complete;
+  conn->recv[sockindex] = nss_recv;
+  conn->send[sockindex] = nss_send;
+
+  /* ssl_connect_done is never used outside, go back to the initial state */
+  connssl->connecting_state = ssl_connect_1;
+
   return CURLE_OK;
 }
 
@@ -1866,8 +1962,10 @@ static ssize_t nss_send(struct connectdata *conn,  /* connection data */
         ? CURLE_SSL_CERTPROBLEM
         : CURLE_SEND_ERROR;
     }
+
     return -1;
   }
+
   return rc; /* number of bytes */
 }
 
@@ -1897,8 +1995,10 @@ static ssize_t nss_recv(struct connectdata * conn, /* connection data */
         ? CURLE_SSL_CERTPROBLEM
         : CURLE_RECV_ERROR;
     }
+
     return -1;
   }
+
   return nread;
 }
 
@@ -1907,6 +2007,7 @@ size_t Curl_nss_version(char *buffer, size_t size)
   return snprintf(buffer, size, "NSS/%s", NSS_VERSION);
 }
 
+/* data might be NULL */
 int Curl_nss_seed(struct SessionHandle *data)
 {
   /* make sure that NSS is initialized */
@@ -1918,13 +2019,12 @@ int Curl_nss_random(struct SessionHandle *data,
                     unsigned char *entropy,
                     size_t length)
 {
-  if(data)
-    Curl_nss_seed(data);  /* Initiate the seed if not already done */
-  if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length))) {
-    /* no way to signal a failure from here, we have to abort */
-    failf(data, "PK11_GenerateRandom() failed, calling abort()...");
-    abort();
-  }
+  Curl_nss_seed(data);  /* Initiate the seed if not already done */
+
+  if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length)))
+    /* signal a failure */
+    return -1;
+
   return 0;
 }
 
@@ -1935,9 +2035,40 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
 {
   PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
   unsigned int MD5out;
+
   PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen));
   PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len));
   PK11_DestroyContext(MD5pw, PR_TRUE);
 }
 
+void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
+                     size_t tmplen,
+                     unsigned char *sha256sum, /* output */
+                     size_t sha256len)
+{
+  PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
+  unsigned int SHA256out;
+
+  PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen));
+  PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len));
+  PK11_DestroyContext(SHA256pw, PR_TRUE);
+}
+
+bool Curl_nss_cert_status_request(void)
+{
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+bool Curl_nss_false_start(void) {
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
 #endif /* USE_NSS */
diff --git a/Utilities/cmcurl/lib/vtls/nssg.h b/Utilities/cmcurl/lib/vtls/nssg.h
index 311f873..5fd7275 100644
--- a/Utilities/cmcurl/lib/vtls/nssg.h
+++ b/Utilities/cmcurl/lib/vtls/nssg.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -37,10 +37,6 @@ CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn,
 /* close a SSL connection */
 void Curl_nss_close(struct connectdata *conn, int sockindex);
 
-/* tell NSS to close down all open information regarding connections (and
-   thus session ID caching etc) */
-int Curl_nss_close_all(struct SessionHandle *data);
-
 int Curl_nss_init(void);
 void Curl_nss_cleanup(void);
 
@@ -60,8 +56,23 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
                      unsigned char *md5sum, /* output */
                      size_t md5len);
 
-/* this backend provides these functions: */
-#define have_curlssl_md5sum 1
+void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
+                     size_t tmplen,
+                     unsigned char *sha256sum, /* output */
+                     size_t sha256len);
+
+bool Curl_nss_cert_status_request(void);
+
+bool Curl_nss_false_start(void);
+
+/* Set the API backend definition to NSS */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_NSS
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
 
 /* API setup for NSS */
 #define curlssl_init Curl_nss_init
@@ -71,19 +82,21 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
 
 /* NSS has its own session ID cache */
 #define curlssl_session_free(x) Curl_nop_stmt
-#define curlssl_close_all Curl_nss_close_all
+#define curlssl_close_all(x) ((void)x)
 #define curlssl_close Curl_nss_close
 /* NSS has no shutdown function provided and thus always fail */
-#define curlssl_shutdown(x,y) (x=x, y=y, 1)
-#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN)
-#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN)
-#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
+#define curlssl_shutdown(x,y) ((void)x, (void)y, 1)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
 #define curlssl_version Curl_nss_version
 #define curlssl_check_cxn(x) Curl_nss_check_cxn(x)
-#define curlssl_data_pending(x,y) (x=x, y=y, 0)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
 #define curlssl_random(x,y,z) Curl_nss_random(x,y,z)
 #define curlssl_md5sum(a,b,c,d) Curl_nss_md5sum(a,b,c,d)
-#define CURL_SSL_BACKEND CURLSSLBACKEND_NSS
+#define curlssl_sha256sum(a,b,c,d) Curl_nss_sha256sum(a,b,c,d)
+#define curlssl_cert_status_request() Curl_nss_cert_status_request()
+#define curlssl_false_start() Curl_nss_false_start()
 
 #endif /* USE_NSS */
 #endif /* HEADER_CURL_NSSG_H */
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index da92854..90e4c2b 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,6 +32,8 @@
 
 #include "curl_setup.h"
 
+#ifdef USE_OPENSSL
+
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif
@@ -49,13 +51,9 @@
 #include "vtls.h"
 #include "rawstr.h"
 #include "hostcheck.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use the internal *printf() functions */
-#include <curl/mprintf.h>
-
-#ifdef USE_SSLEAY
-
-#ifdef USE_OPENSSL
+#include <openssl/ssl.h>
 #include <openssl/rand.h>
 #include <openssl/x509v3.h>
 #include <openssl/dsa.h>
@@ -63,36 +61,29 @@
 #include <openssl/err.h>
 #include <openssl/md5.h>
 #include <openssl/conf.h>
-#else
-#include <rand.h>
-#include <x509v3.h>
-#include <md5.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+#ifdef HAVE_OPENSSL_PKCS12_H
+#include <openssl/pkcs12.h>
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_IS_BORINGSSL)
+#include <openssl/ocsp.h>
 #endif
 
 #include "warnless.h"
-#include "curl_memory.h"
 #include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */
 
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 #ifndef OPENSSL_VERSION_NUMBER
 #error "OPENSSL_VERSION_NUMBER not defined"
 #endif
 
-#if OPENSSL_VERSION_NUMBER >= 0x0090581fL
-#define HAVE_SSL_GET1_SESSION 1
-#else
-#undef HAVE_SSL_GET1_SESSION
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x00904100L
-#define HAVE_USERDATA_IN_PWD_CALLBACK 1
-#else
-#undef HAVE_USERDATA_IN_PWD_CALLBACK
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x00907001L
+#if OPENSSL_VERSION_NUMBER >= 0x00907001L && !defined(OPENSSL_IS_BORINGSSL)
 /* ENGINE_load_private_key() takes four arguments */
 #define HAVE_ENGINE_LOAD_FOUR_ARGS
 #include <openssl/ui.h>
@@ -101,18 +92,16 @@
 #undef HAVE_ENGINE_LOAD_FOUR_ARGS
 #endif
 
-#if (OPENSSL_VERSION_NUMBER >= 0x00903001L) && defined(HAVE_OPENSSL_PKCS12_H)
-/* OpenSSL has PKCS 12 support */
+#if (OPENSSL_VERSION_NUMBER >= 0x00903001L) && \
+    defined(HAVE_OPENSSL_PKCS12_H) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+/* OpenSSL has PKCS 12 support, BoringSSL does not */
 #define HAVE_PKCS12_SUPPORT
 #else
-/* OpenSSL/SSLEay does not have PKCS12 support */
+/* OpenSSL does not have PKCS12 support */
 #undef HAVE_PKCS12_SUPPORT
 #endif
 
-#if OPENSSL_VERSION_NUMBER >= 0x00906001L
-#define HAVE_ERR_ERROR_STRING_N 1
-#endif
-
 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
 #define SSL_METHOD_QUAL const
 #else
@@ -126,15 +115,32 @@
 #define X509_STORE_set_flags(x,y) Curl_nop_stmt
 #endif
 
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+#ifdef OPENSSL_IS_BORINGSSL
+/* BoringSSL has no ERR_remove_state() */
+#define ERR_remove_state(x)
+#elif (OPENSSL_VERSION_NUMBER >= 0x10000000L)
 #define HAVE_ERR_REMOVE_THREAD_STATE 1
 #endif
 
-#ifndef HAVE_SSLV2_CLIENT_METHOD
+#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \
+  OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */
 #undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */
 #define OPENSSL_NO_SSL2
 #endif
 
+#if defined(OPENSSL_IS_BORINGSSL)
+#define NO_RAND_SEED 1
+/* In BoringSSL OpenSSL_add_all_algorithms does nothing */
+#define OpenSSL_add_all_algorithms()
+/* BoringSSL does not have CONF_modules_load_file */
+#define CONF_modules_load_file(a,b,c)
+#endif
+
+#if (OPENSSL_VERSION_NUMBER < 0x0090808fL) || defined(OPENSSL_IS_BORINGSSL)
+/* not present in BoringSSL  or older OpenSSL */
+#define OPENSSL_load_builtin_modules(x)
+#endif
+
 /*
  * Number of bytes to read from the random number seed file. This must be
  * a finite value (because some entropy "files" like /dev/urandom have
@@ -143,18 +149,8 @@
  */
 #define RAND_LOAD_LENGTH 1024
 
-#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
-static char global_passwd[64];
-#endif
-
-static int passwd_callback(char *buf, int num, int encrypting
-#ifdef HAVE_USERDATA_IN_PWD_CALLBACK
-                           /* This was introduced in 0.9.4, we can set this
-                              using SSL_CTX_set_default_passwd_cb_userdata()
-                              */
-                           , void *global_passwd
-#endif
-                           )
+static int passwd_callback(char *buf, int num, int encrypting,
+                           void *global_passwd)
 {
   DEBUGASSERT(0 == encrypting);
 
@@ -175,6 +171,7 @@ static int passwd_callback(char *buf, int num, int encrypting
  * pass in an argument that is never used.
  */
 
+#ifndef NO_RAND_SEED
 #ifdef HAVE_RAND_STATUS
 #define seed_enough(x) rand_enough()
 static bool rand_enough(void)
@@ -259,7 +256,7 @@ static int ossl_seed(struct SessionHandle *data)
   return nread;
 }
 
-static int Curl_ossl_seed(struct SessionHandle *data)
+static void Curl_ossl_seed(struct SessionHandle *data)
 {
   /* we have the "SSL is seeded" boolean static to prevent multiple
      time-consuming seedings in vain */
@@ -270,8 +267,11 @@ static int Curl_ossl_seed(struct SessionHandle *data)
     ossl_seed(data);
     ssl_seeded = TRUE;
   }
-  return 0;
 }
+#else
+/* BoringSSL needs no seeding */
+#define Curl_ossl_seed(x)
+#endif
 
 
 #ifndef SSL_FILETYPE_ENGINE
@@ -308,8 +308,7 @@ static int ssl_ui_reader(UI *ui, UI_STRING *uis)
   case UIT_PROMPT:
   case UIT_VERIFY:
     password = (const char*)UI_get0_user_data(ui);
-    if(NULL != password &&
-       UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD) {
+    if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
       UI_set_result(ui, uis, password);
       return 1;
     }
@@ -327,8 +326,8 @@ static int ssl_ui_writer(UI *ui, UI_STRING *uis)
   switch(UI_get_string_type(uis)) {
   case UIT_PROMPT:
   case UIT_VERIFY:
-    if(NULL != UI_get0_user_data(ui) &&
-       UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD) {
+    if(UI_get0_user_data(ui) &&
+       (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
       return 1;
     }
   default:
@@ -350,43 +349,29 @@ int cert_stuff(struct connectdata *conn,
 
   int file_type = do_file_type(cert_type);
 
-  if(cert_file != NULL || file_type == SSL_FILETYPE_ENGINE) {
+  if(cert_file || (file_type == SSL_FILETYPE_ENGINE)) {
     SSL *ssl;
     X509 *x509;
     int cert_done = 0;
 
     if(data->set.str[STRING_KEY_PASSWD]) {
-#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
-      /*
-       * If password has been given, we store that in the global
-       * area (*shudder*) for a while:
-       */
-      size_t len = strlen(data->set.str[STRING_KEY_PASSWD]);
-      if(len < sizeof(global_passwd))
-        memcpy(global_passwd, data->set.str[STRING_KEY_PASSWD], len+1);
-      else
-        global_passwd[0] = '\0';
-#else
-      /*
-       * We set the password in the callback userdata
-       */
+      /* set the password in the callback userdata */
       SSL_CTX_set_default_passwd_cb_userdata(ctx,
                                              data->set.str[STRING_KEY_PASSWD]);
-#endif
       /* Set passwd callback: */
       SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
     }
 
 
-#define SSL_CLIENT_CERT_ERR \
-    "unable to use client certificate (no key found or wrong pass phrase?)"
-
     switch(file_type) {
     case SSL_FILETYPE_PEM:
       /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
       if(SSL_CTX_use_certificate_chain_file(ctx,
                                             cert_file) != 1) {
-        failf(data, SSL_CLIENT_CERT_ERR);
+        failf(data,
+              "could not load PEM client certificate, OpenSSL error %s, "
+              "(no key found, wrong pass phrase, or wrong file format?)",
+              ERR_error_string(ERR_get_error(), NULL) );
         return 0;
       }
       break;
@@ -398,7 +383,10 @@ int cert_stuff(struct connectdata *conn,
       if(SSL_CTX_use_certificate_file(ctx,
                                       cert_file,
                                       file_type) != 1) {
-        failf(data, SSL_CLIENT_CERT_ERR);
+        failf(data,
+              "could not load ASN1 client certificate, OpenSSL error %s, "
+              "(no key found, wrong pass phrase, or wrong file format?)",
+              ERR_error_string(ERR_get_error(), NULL) );
         return 0;
       }
       break;
@@ -464,7 +452,7 @@ int cert_stuff(struct connectdata *conn,
       STACK_OF(X509) *ca = NULL;
       int i;
 
-      f = fopen(cert_file,"rb");
+      f = fopen(cert_file, "rb");
       if(!f) {
         failf(data, "could not open PKCS12 file '%s'", cert_file);
         return 0;
@@ -473,7 +461,7 @@ int cert_stuff(struct connectdata *conn,
       fclose(f);
 
       if(!p12) {
-        failf(data, "error reading PKCS12 file '%s'", cert_file );
+        failf(data, "error reading PKCS12 file '%s'", cert_file);
         return 0;
       }
 
@@ -491,7 +479,9 @@ int cert_stuff(struct connectdata *conn,
       PKCS12_free(p12);
 
       if(SSL_CTX_use_certificate(ctx, x509) != 1) {
-        failf(data, SSL_CLIENT_CERT_ERR);
+        failf(data,
+              "could not load PKCS12 client certificate, OpenSSL error %s",
+              ERR_error_string(ERR_get_error(), NULL) );
         goto fail;
       }
 
@@ -556,7 +546,7 @@ int cert_stuff(struct connectdata *conn,
     case SSL_FILETYPE_PEM:
       if(cert_done)
         break;
-      if(key_file == NULL)
+      if(!key_file)
         /* cert & key can only be in PEM case in the same file */
         key_file=cert_file;
     case SSL_FILETYPE_ASN1:
@@ -574,7 +564,7 @@ int cert_stuff(struct connectdata *conn,
 #ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
           UI_METHOD *ui_method =
             UI_create_method((char *)"cURL user interface");
-          if(NULL == ui_method) {
+          if(!ui_method) {
             failf(data, "unable do create OpenSSL user-interface method");
             return 0;
           }
@@ -585,7 +575,7 @@ int cert_stuff(struct connectdata *conn,
 #endif
           /* the typecast below was added to please mingw32 */
           priv_key = (EVP_PKEY *)
-            ENGINE_load_private_key(data->state.engine,key_file,
+            ENGINE_load_private_key(data->state.engine, key_file,
 #ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
                                     ui_method,
 #endif
@@ -626,8 +616,8 @@ int cert_stuff(struct connectdata *conn,
     }
 
     ssl=SSL_new(ctx);
-    if(NULL == ssl) {
-      failf(data,"unable to create an SSL structure");
+    if(!ssl) {
+      failf(data, "unable to create an SSL structure");
       return 0;
     }
 
@@ -635,9 +625,9 @@ int cert_stuff(struct connectdata *conn,
 
     /* This version was provided by Evan Jordan and is supposed to not
        leak memory as the previous version: */
-    if(x509 != NULL) {
+    if(x509) {
       EVP_PKEY *pktmp = X509_get_pubkey(x509);
-      EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));
+      EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl));
       EVP_PKEY_free(pktmp);
     }
 
@@ -653,10 +643,6 @@ int cert_stuff(struct connectdata *conn,
       failf(data, "Private key does not match the certificate public key");
       return 0;
     }
-#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
-    /* erase it now */
-    memset(global_passwd, 0, sizeof(global_passwd));
-#endif
   }
   return 1;
 }
@@ -691,36 +677,17 @@ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
 #endif
 }
 
-static
-int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
-{
-  X509 *err_cert;
-  char buf[256];
-
-  err_cert=X509_STORE_CTX_get_current_cert(ctx);
-  (void)x509_name_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
-  return ok;
-}
-
 /* Return error string for last OpenSSL error
  */
 static char *SSL_strerror(unsigned long error, char *buf, size_t size)
 {
-#ifdef HAVE_ERR_ERROR_STRING_N
   /* OpenSSL 0.9.6 and later has a function named
-     ERRO_error_string_n() that takes the size of the buffer as a
+     ERR_error_string_n() that takes the size of the buffer as a
      third argument */
   ERR_error_string_n(error, buf, size);
-#else
-  (void) size;
-  ERR_error_string(error, buf);
-#endif
   return buf;
 }
 
-#endif /* USE_SSLEAY */
-
-#ifdef USE_SSLEAY
 /**
  * Global SSL init
  *
@@ -729,6 +696,8 @@ static char *SSL_strerror(unsigned long error, char *buf, size_t size)
  */
 int Curl_ossl_init(void)
 {
+  OPENSSL_load_builtin_modules();
+
 #ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
   ENGINE_load_builtin_engines();
 #endif
@@ -749,17 +718,19 @@ int Curl_ossl_init(void)
      calls CONF_modules_load_file() and we use that instead and we ignore
      its return code! */
 
-  (void)CONF_modules_load_file(NULL, NULL,
-                               CONF_MFLAGS_DEFAULT_SECTION|
-                               CONF_MFLAGS_IGNORE_MISSING_FILE);
+  /* CONF_MFLAGS_DEFAULT_SECTION introduced some time between 0.9.8b and
+     0.9.8e */
+#ifndef CONF_MFLAGS_DEFAULT_SECTION
+#define CONF_MFLAGS_DEFAULT_SECTION 0x0
+#endif
+
+  CONF_modules_load_file(NULL, NULL,
+                         CONF_MFLAGS_DEFAULT_SECTION|
+                         CONF_MFLAGS_IGNORE_MISSING_FILE);
 
   return 1;
 }
 
-#endif /* USE_SSLEAY */
-
-#ifdef USE_SSLEAY
-
 /* Global cleanup */
 void Curl_ossl_cleanup(void)
 {
@@ -814,7 +785,7 @@ int Curl_ossl_check_cxn(struct connectdata *conn)
  */
 CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
 {
-#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
   ENGINE *e;
 
 #if OPENSSL_VERSION_NUMBER >= 0x00909000L
@@ -862,7 +833,7 @@ CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
 #ifdef HAVE_OPENSSL_ENGINE_H
   if(data->state.engine) {
     if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
-      infof(data,"set default crypto engine '%s'\n",
+      infof(data, "set default crypto engine '%s'\n",
             ENGINE_get_id(data->state.engine));
     }
     else {
@@ -882,7 +853,7 @@ CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
 struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
 {
   struct curl_slist *list = NULL;
-#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
   struct curl_slist *beg;
   ENGINE *e;
 
@@ -1031,7 +1002,7 @@ void Curl_ossl_session_free(void *ptr)
  * This function is called when the 'data' struct is going away. Close
  * down everything and free all resources!
  */
-int Curl_ossl_close_all(struct SessionHandle *data)
+void Curl_ossl_close_all(struct SessionHandle *data)
 {
 #ifdef HAVE_OPENSSL_ENGINE_H
   if(data->state.engine) {
@@ -1042,7 +1013,6 @@ int Curl_ossl_close_all(struct SessionHandle *data)
 #else
   (void)data;
 #endif
-  return 0;
 }
 
 static int asn1_output(const ASN1_UTCTIME *tm,
@@ -1052,7 +1022,7 @@ static int asn1_output(const ASN1_UTCTIME *tm,
   const char *asn1_string;
   int gmt=FALSE;
   int i;
-  int year=0,month=0,day=0,hour=0,minute=0,second=0;
+  int year=0, month=0, day=0, hour=0, minute=0, second=0;
 
   i=tm->length;
   asn1_string=(const char *)tm->data;
@@ -1112,8 +1082,7 @@ static int asn1_output(const ASN1_UTCTIME *tm,
    in the certificate and must exactly match the IP in the URI.
 
 */
-static CURLcode verifyhost(struct connectdata *conn,
-                           X509 *server_cert)
+static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
 {
   int matched = -1; /* -1 is no alternative match yet, 1 means match and 0
                        means mismatch */
@@ -1126,7 +1095,7 @@ static CURLcode verifyhost(struct connectdata *conn,
 #else
   struct in_addr addr;
 #endif
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
 
 #ifdef ENABLE_IPV6
   if(conn->bits.ipv6_ip &&
@@ -1207,19 +1176,19 @@ static CURLcode verifyhost(struct connectdata *conn,
     infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
     failf(data, "SSL: no alternative certificate subject name matches "
           "target host name '%s'", conn->host.dispname);
-    res = CURLE_PEER_FAILED_VERIFICATION;
+    result = CURLE_PEER_FAILED_VERIFICATION;
   }
   else {
     /* we have to look to the last occurrence of a commonName in the
        distinguished one to get the most significant one. */
-    int j,i=-1 ;
+    int j, i=-1;
 
 /* The following is done because of a bug in 0.9.6b */
 
     unsigned char *nulstr = (unsigned char *)"";
     unsigned char *peer_CN = nulstr;
 
-    X509_NAME *name = X509_get_subject_name(server_cert) ;
+    X509_NAME *name = X509_get_subject_name(server_cert);
     if(name)
       while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i))>=0)
         i=j;
@@ -1229,7 +1198,8 @@ static CURLcode verifyhost(struct connectdata *conn,
        UTF8 etc. */
 
     if(i>=0) {
-      ASN1_STRING *tmp = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
+      ASN1_STRING *tmp =
+        X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
 
       /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
          is already UTF-8 encoded. We check for this case and copy the raw
@@ -1254,7 +1224,7 @@ static CURLcode verifyhost(struct connectdata *conn,
           /* there was a terminating zero before the end of string, this
              cannot match and we return failure! */
           failf(data, "SSL: illegal cert name field");
-          res = CURLE_PEER_FAILED_VERIFICATION;
+          result = CURLE_PEER_FAILED_VERIFICATION;
         }
       }
     }
@@ -1271,18 +1241,18 @@ static CURLcode verifyhost(struct connectdata *conn,
       }
     }
 
-    if(res)
+    if(result)
       /* error already detected, pass through */
       ;
     else if(!peer_CN) {
       failf(data,
             "SSL: unable to obtain common name from peer certificate");
-      res = CURLE_PEER_FAILED_VERIFICATION;
+      result = CURLE_PEER_FAILED_VERIFICATION;
     }
     else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
       failf(data, "SSL: certificate subject name '%s' does not match "
             "target host name '%s'", peer_CN, conn->host.dispname);
-      res = CURLE_PEER_FAILED_VERIFICATION;
+      result = CURLE_PEER_FAILED_VERIFICATION;
     }
     else {
       infof(data, "\t common name: %s (matched)\n", peer_CN);
@@ -1290,9 +1260,138 @@ static CURLcode verifyhost(struct connectdata *conn,
     if(peer_CN)
       OPENSSL_free(peer_CN);
   }
-  return res;
+
+  return result;
+}
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+static CURLcode verifystatus(struct connectdata *conn,
+                             struct ssl_connect_data *connssl)
+{
+  int i, ocsp_status;
+  const unsigned char *p;
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  OCSP_RESPONSE *rsp = NULL;
+  OCSP_BASICRESP *br = NULL;
+  X509_STORE     *st = NULL;
+  STACK_OF(X509) *ch = NULL;
+
+  long len = SSL_get_tlsext_status_ocsp_resp(connssl->handle, &p);
+
+  if(!p) {
+    failf(data, "No OCSP response received");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
+  if(!rsp) {
+    failf(data, "Invalid OCSP response");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  ocsp_status = OCSP_response_status(rsp);
+  if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+    failf(data, "Invalid OCSP response status: %s (%d)",
+          OCSP_response_status_str(ocsp_status), ocsp_status);
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  br = OCSP_response_get1_basic(rsp);
+  if(!br) {
+    failf(data, "Invalid OCSP response");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  ch = SSL_get_peer_cert_chain(connssl->handle);
+  st = SSL_CTX_get_cert_store(connssl->ctx);
+
+#if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
+     defined(LIBRESSL_VERSION_NUMBER))
+  /* The authorized responder cert in the OCSP response MUST be signed by the
+     peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert,
+     no problem, but if it's an intermediate cert OpenSSL has a bug where it
+     expects this issuer to be present in the chain embedded in the OCSP
+     response. So we add it if necessary. */
+
+  /* First make sure the peer cert chain includes both a peer and an issuer,
+     and the OCSP response contains a responder cert. */
+  if(sk_X509_num(ch) >= 2 && sk_X509_num(br->certs) >= 1) {
+    X509 *responder = sk_X509_value(br->certs, sk_X509_num(br->certs) - 1);
+
+    /* Find issuer of responder cert and add it to the OCSP response chain */
+    for(i = 0; i < sk_X509_num(ch); i++) {
+      X509 *issuer = sk_X509_value(ch, i);
+      if(X509_check_issued(issuer, responder) == X509_V_OK) {
+        if(!OCSP_basic_add1_cert(br, issuer)) {
+          failf(data, "Could not add issuer cert to OCSP response");
+          result = CURLE_SSL_INVALIDCERTSTATUS;
+          goto end;
+        }
+      }
+    }
+  }
+#endif
+
+  if(OCSP_basic_verify(br, ch, st, 0) <= 0) {
+    failf(data, "OCSP response verification failed");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  for(i = 0; i < OCSP_resp_count(br); i++) {
+    int cert_status, crl_reason;
+    OCSP_SINGLERESP *single = NULL;
+
+    ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+
+    if(!(single = OCSP_resp_get0(br, i)))
+      continue;
+
+    cert_status = OCSP_single_get0_status(single, &crl_reason, &rev,
+                                          &thisupd, &nextupd);
+
+    if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
+      failf(data, "OCSP response has expired");
+      result = CURLE_SSL_INVALIDCERTSTATUS;
+      goto end;
+    }
+
+    infof(data, "SSL certificate status: %s (%d)\n",
+          OCSP_cert_status_str(cert_status), cert_status);
+
+    switch(cert_status) {
+      case V_OCSP_CERTSTATUS_GOOD:
+        break;
+
+      case V_OCSP_CERTSTATUS_REVOKED:
+        result = CURLE_SSL_INVALIDCERTSTATUS;
+
+        failf(data, "SSL certificate revocation reason: %s (%d)",
+              OCSP_crl_reason_str(crl_reason), crl_reason);
+        goto end;
+
+      case V_OCSP_CERTSTATUS_UNKNOWN:
+        result = CURLE_SSL_INVALIDCERTSTATUS;
+        goto end;
+    }
+  }
+
+end:
+  if(br) OCSP_BASICRESP_free(br);
+  OCSP_RESPONSE_free(rsp);
+
+  return result;
 }
-#endif /* USE_SSLEAY */
+#endif
+
+#endif /* USE_OPENSSL */
 
 /* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
    and thus this cannot be done there. */
@@ -1300,6 +1399,7 @@ static CURLcode verifyhost(struct connectdata *conn,
 
 static const char *ssl_msg_type(int ssl_ver, int msg)
 {
+#ifdef SSL2_VERSION_MAJOR
   if(ssl_ver == SSL2_VERSION_MAJOR) {
     switch (msg) {
       case SSL2_MT_ERROR:
@@ -1322,7 +1422,9 @@ static const char *ssl_msg_type(int ssl_ver, int msg)
         return "Client CERT";
     }
   }
-  else if(ssl_ver == SSL3_VERSION_MAJOR) {
+  else
+#endif
+  if(ssl_ver == SSL3_VERSION_MAJOR) {
     switch (msg) {
       case SSL3_MT_HELLO_REQUEST:
         return "Hello request";
@@ -1330,8 +1432,12 @@ static const char *ssl_msg_type(int ssl_ver, int msg)
         return "Client hello";
       case SSL3_MT_SERVER_HELLO:
         return "Server hello";
+#ifdef SSL3_MT_NEWSESSION_TICKET
+      case SSL3_MT_NEWSESSION_TICKET:
+        return "Newsession Ticket";
+#endif
       case SSL3_MT_CERTIFICATE:
-        return "CERT";
+        return "Certificate";
       case SSL3_MT_SERVER_KEY_EXCHANGE:
         return "Server key exchange";
       case SSL3_MT_CLIENT_KEY_EXCHANGE:
@@ -1344,6 +1450,10 @@ static const char *ssl_msg_type(int ssl_ver, int msg)
         return "CERT verify";
       case SSL3_MT_FINISHED:
         return "Finished";
+#ifdef SSL3_MT_CERTIFICATE_STATUS
+      case SSL3_MT_CERTIFICATE_STATUS:
+        return "Certificate Status";
+#endif
     }
   }
   return "Unknown";
@@ -1351,12 +1461,22 @@ static const char *ssl_msg_type(int ssl_ver, int msg)
 
 static const char *tls_rt_type(int type)
 {
-  return (
-    type == SSL3_RT_CHANGE_CIPHER_SPEC ? "TLS change cipher, " :
-    type == SSL3_RT_ALERT              ? "TLS alert, "         :
-    type == SSL3_RT_HANDSHAKE          ? "TLS handshake, "     :
-    type == SSL3_RT_APPLICATION_DATA   ? "TLS app data, "      :
-                                         "TLS Unknown, ");
+  switch(type) {
+#ifdef SSL3_RT_HEADER
+  case SSL3_RT_HEADER:
+    return "TLS header";
+#endif
+  case SSL3_RT_CHANGE_CIPHER_SPEC:
+    return "TLS change cipher";
+  case SSL3_RT_ALERT:
+    return "TLS alert";
+  case SSL3_RT_HANDSHAKE:
+    return "TLS handshake";
+  case SSL3_RT_APPLICATION_DATA:
+    return "TLS app data";
+  default:
+    return "TLS Unknown";
+  }
 }
 
 
@@ -1364,38 +1484,77 @@ static const char *tls_rt_type(int type)
  * Our callback from the SSL/TLS layers.
  */
 static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
-                          const void *buf, size_t len, const SSL *ssl,
-                          struct connectdata *conn)
+                          const void *buf, size_t len, SSL *ssl,
+                          void *userp)
 {
   struct SessionHandle *data;
   const char *msg_name, *tls_rt_name;
   char ssl_buf[1024];
-  int  ver, msg_type, txt_len;
+  char unknown[32];
+  int msg_type, txt_len;
+  const char *verstr = NULL;
+  struct connectdata *conn = userp;
 
   if(!conn || !conn->data || !conn->data->set.fdebug ||
      (direction != 0 && direction != 1))
     return;
 
   data = conn->data;
-  ssl_ver >>= 8;
-  ver = (ssl_ver == SSL2_VERSION_MAJOR ? '2' :
-         ssl_ver == SSL3_VERSION_MAJOR ? '3' : '?');
 
-  /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
-   * always pass-up content-type as 0. But the interesting message-type
-   * is at 'buf[0]'.
-   */
-  if(ssl_ver == SSL3_VERSION_MAJOR && content_type != 0)
-    tls_rt_name = tls_rt_type(content_type);
-  else
-    tls_rt_name = "";
+  switch(ssl_ver) {
+#ifdef SSL2_VERSION /* removed in recent versions */
+  case SSL2_VERSION:
+    verstr = "SSLv2";
+    break;
+#endif
+#ifdef SSL3_VERSION
+  case SSL3_VERSION:
+    verstr = "SSLv3";
+    break;
+#endif
+  case TLS1_VERSION:
+    verstr = "TLSv1.0";
+    break;
+#ifdef TLS1_1_VERSION
+  case TLS1_1_VERSION:
+    verstr = "TLSv1.1";
+    break;
+#endif
+#ifdef TLS1_2_VERSION
+  case TLS1_2_VERSION:
+    verstr = "TLSv1.2";
+    break;
+#endif
+  case 0:
+    break;
+  default:
+    snprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
+    verstr = unknown;
+    break;
+  }
+
+  if(ssl_ver) {
+    /* the info given when the version is zero is not that useful for us */
+
+    ssl_ver >>= 8; /* check the upper 8 bits only below */
 
-  msg_type = *(char*)buf;
-  msg_name = ssl_msg_type(ssl_ver, msg_type);
+    /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
+     * always pass-up content-type as 0. But the interesting message-type
+     * is at 'buf[0]'.
+     */
+    if(ssl_ver == SSL3_VERSION_MAJOR && content_type)
+      tls_rt_name = tls_rt_type(content_type);
+    else
+      tls_rt_name = "";
 
-  txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n",
-                     ver, tls_rt_name, msg_name, msg_type);
-  Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
+    msg_type = *(char*)buf;
+    msg_name = ssl_msg_type(ssl_ver, msg_type);
+
+    txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
+                       verstr, direction?"OUT":"IN",
+                       tls_rt_name, msg_name, msg_type);
+    Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
+  }
 
   Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
              CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
@@ -1403,7 +1562,7 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
 }
 #endif
 
-#ifdef USE_SSLEAY
+#ifdef USE_OPENSSL
 /* ====================================================== */
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
@@ -1412,26 +1571,44 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
 #  define use_sni(x)  Curl_nop_stmt
 #endif
 
-#ifdef USE_NGHTTP2
-
+/* Check for OpenSSL 1.0.2 which has ALPN support. */
 #undef HAS_ALPN
-#if defined(HAVE_SSL_CTX_SET_ALPN_PROTOS) && \
-  defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L \
+    && !defined(OPENSSL_NO_TLSEXT)
 #  define HAS_ALPN 1
 #endif
 
-#if !defined(HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB) || \
-  defined(OPENSSL_NO_NEXTPROTONEG)
-#  if !defined(HAS_ALPN)
-#    error http2 builds require OpenSSL with NPN or ALPN support
-#  endif
+/* Check for OpenSSL 1.0.1 which has NPN support. */
+#undef HAS_NPN
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L \
+    && !defined(OPENSSL_NO_TLSEXT) \
+    && !defined(OPENSSL_NO_NEXTPROTONEG)
+#  define HAS_NPN 1
 #endif
 
+#ifdef HAS_NPN
 
 /*
  * in is a list of lenght prefixed strings. this function has to select
  * the protocol we want to use from the list and write its string into out.
  */
+
+static int
+select_next_protocol(unsigned char **out, unsigned char *outlen,
+                     const unsigned char *in, unsigned int inlen,
+                     const char *key, unsigned int keylen)
+{
+  unsigned int i;
+  for(i = 0; i + keylen <= inlen; i += in[i] + 1) {
+    if(memcmp(&in[i + 1], key, keylen) == 0) {
+      *out = (unsigned char *) &in[i + 1];
+      *outlen = in[i];
+      return 0;
+    }
+  }
+  return -1;
+}
+
 static int
 select_next_proto_cb(SSL *ssl,
                      unsigned char **out, unsigned char *outlen,
@@ -1439,37 +1616,43 @@ select_next_proto_cb(SSL *ssl,
                      void *arg)
 {
   struct connectdata *conn = (struct connectdata*) arg;
-  int retval = nghttp2_select_next_protocol(out, outlen, in, inlen);
+
   (void)ssl;
 
-  if(retval == 1) {
+#ifdef USE_NGHTTP2
+  if(conn->data->set.httpversion == CURL_HTTP_VERSION_2_0 &&
+     !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID,
+                           NGHTTP2_PROTO_VERSION_ID_LEN)) {
     infof(conn->data, "NPN, negotiated HTTP2 (%s)\n",
           NGHTTP2_PROTO_VERSION_ID);
-    conn->negnpn = NPN_HTTP2;
+    conn->negnpn = CURL_HTTP_VERSION_2_0;
+    return SSL_TLSEXT_ERR_OK;
   }
-  else if(retval == 0) {
+#endif
+
+  if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1,
+                           ALPN_HTTP_1_1_LENGTH)) {
     infof(conn->data, "NPN, negotiated HTTP1.1\n");
-    conn->negnpn = NPN_HTTP1_1;
-  }
-  else {
-    infof(conn->data, "NPN, no overlap, use HTTP1.1\n",
-          NGHTTP2_PROTO_VERSION_ID);
-    *out = (unsigned char*)"http/1.1";
-    *outlen = sizeof("http/1.1") - 1;
-    conn->negnpn = NPN_HTTP1_1;
+    conn->negnpn = CURL_HTTP_VERSION_1_1;
+    return SSL_TLSEXT_ERR_OK;
   }
 
+  infof(conn->data, "NPN, no overlap, use HTTP1.1\n");
+  *out = (unsigned char *)ALPN_HTTP_1_1;
+  *outlen = ALPN_HTTP_1_1_LENGTH;
+  conn->negnpn = CURL_HTTP_VERSION_1_1;
+
   return SSL_TLSEXT_ERR_OK;
 }
-#endif
+#endif /* HAS_NPN */
 
 static const char *
-get_ssl_version_txt(SSL_SESSION *session)
+get_ssl_version_txt(SSL *ssl)
 {
-  if(NULL == session)
+  if(!ssl)
     return "";
 
-  switch(session->ssl_version) {
+  switch(SSL_version(ssl)) {
 #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
   case TLS1_2_VERSION:
     return "TLSv1.2";
@@ -1486,17 +1669,14 @@ get_ssl_version_txt(SSL_SESSION *session)
   return "unknown";
 }
 
-
-static CURLcode
-ossl_connect_step1(struct connectdata *conn,
-                   int sockindex)
+static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
 {
-  CURLcode retcode = CURLE_OK;
+  CURLcode result = CURLE_OK;
   char *ciphers;
   struct SessionHandle *data = conn->data;
-  SSL_METHOD_QUAL SSL_METHOD *req_method=NULL;
-  void *ssl_sessionid=NULL;
-  X509_LOOKUP *lookup=NULL;
+  SSL_METHOD_QUAL SSL_METHOD *req_method = NULL;
+  void *ssl_sessionid = NULL;
+  X509_LOOKUP *lookup = NULL;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   long ctx_options;
@@ -1508,9 +1688,6 @@ ossl_connect_step1(struct connectdata *conn,
   struct in_addr addr;
 #endif
 #endif
-#ifdef HAS_ALPN
-  unsigned char protocols[128];
-#endif
 
   DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
 
@@ -1529,7 +1706,12 @@ ossl_connect_step1(struct connectdata *conn,
   case CURL_SSLVERSION_TLSv1_1:
   case CURL_SSLVERSION_TLSv1_2:
     /* it will be handled later with the context options */
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+    !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
+    req_method = TLS_client_method();
+#else
     req_method = SSLv23_client_method();
+#endif
     use_sni(TRUE);
     break;
   case CURL_SSLVERSION_SSLv2:
@@ -1546,6 +1728,10 @@ ossl_connect_step1(struct connectdata *conn,
     break;
 #endif
   case CURL_SSLVERSION_SSLv3:
+#ifdef OPENSSL_NO_SSL3_METHOD
+    failf(data, "OpenSSL was built without SSLv3 support");
+    return CURLE_NOT_BUILT_IN;
+#else
 #ifdef USE_TLS_SRP
     if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
       return CURLE_SSL_CONNECT_ERROR;
@@ -1553,6 +1739,7 @@ ossl_connect_step1(struct connectdata *conn,
     req_method = SSLv3_client_method();
     use_sni(FALSE);
     break;
+#endif
   }
 
   if(connssl->ctx)
@@ -1571,16 +1758,9 @@ ossl_connect_step1(struct connectdata *conn,
 
 #ifdef SSL_CTRL_SET_MSG_CALLBACK
   if(data->set.fdebug && data->set.verbose) {
-    /* the SSL trace callback is only used for verbose logging so we only
-       inform about failures of setting it */
-    if(!SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
-                               (void (*)(void))ssl_tls_trace)) {
-      infof(data, "SSL: couldn't set callback!\n");
-    }
-    else if(!SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0,
-                          conn)) {
-      infof(data, "SSL: couldn't set callback argument!\n");
-    }
+    /* the SSL trace callback is only used for verbose logging */
+    SSL_CTX_set_msg_callback(connssl->ctx, ssl_tls_trace);
+    SSL_CTX_set_msg_callback_arg(connssl->ctx, conn);
   }
 #endif
 
@@ -1593,7 +1773,7 @@ ossl_connect_step1(struct connectdata *conn,
 
      The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to
      disable "rfc4507bis session ticket support".  rfc4507bis was later turned
-     into the proper RFC5077 it seems: http://tools.ietf.org/html/rfc5077
+     into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077
 
      The enabled extension concerns the session management. I wonder how often
      libcurl stops a connection and then resumes a TLS session. also, sending
@@ -1613,7 +1793,7 @@ ossl_connect_step1(struct connectdata *conn,
      this option regardless of OpenSSL version and SSL_OP_ALL definition.
 
      OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability
-     (http://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to
+     (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to
      SSL_OP_ALL that _disables_ that work-around despite the fact that
      SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to
      keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit
@@ -1643,17 +1823,12 @@ ossl_connect_step1(struct connectdata *conn,
 #endif
 
   switch(data->set.ssl.version) {
-  case CURL_SSLVERSION_DEFAULT:
-    ctx_options |= SSL_OP_NO_SSLv2;
+  case CURL_SSLVERSION_SSLv3:
 #ifdef USE_TLS_SRP
     if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
       infof(data, "Set version TLSv1.x for SRP authorisation\n");
-      ctx_options |= SSL_OP_NO_SSLv3;
     }
 #endif
-    break;
-
-  case CURL_SSLVERSION_SSLv3:
     ctx_options |= SSL_OP_NO_SSLv2;
     ctx_options |= SSL_OP_NO_TLSv1;
 #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
@@ -1662,6 +1837,7 @@ ossl_connect_step1(struct connectdata *conn,
 #endif
     break;
 
+  case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
     ctx_options |= SSL_OP_NO_SSLv2;
     ctx_options |= SSL_OP_NO_SSLv3;
@@ -1710,33 +1886,36 @@ ossl_connect_step1(struct connectdata *conn,
 
   SSL_CTX_set_options(connssl->ctx, ctx_options);
 
-#ifdef USE_NGHTTP2
-  if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
-    if(data->set.ssl_enable_npn) {
-      SSL_CTX_set_next_proto_select_cb(connssl->ctx, select_next_proto_cb,
-          conn);
-    }
+#ifdef HAS_NPN
+  if(data->set.ssl_enable_npn)
+    SSL_CTX_set_next_proto_select_cb(connssl->ctx, select_next_proto_cb, conn);
+#endif
 
 #ifdef HAS_ALPN
-    if(data->set.ssl_enable_alpn) {
-      protocols[0] = NGHTTP2_PROTO_VERSION_ID_LEN;
-      memcpy(&protocols[1], NGHTTP2_PROTO_VERSION_ID,
-          NGHTTP2_PROTO_VERSION_ID_LEN);
+  if(data->set.ssl_enable_alpn) {
+    int cur = 0;
+    unsigned char protocols[128];
 
-      protocols[NGHTTP2_PROTO_VERSION_ID_LEN+1] = ALPN_HTTP_1_1_LENGTH;
-      memcpy(&protocols[NGHTTP2_PROTO_VERSION_ID_LEN+2], ALPN_HTTP_1_1,
-          ALPN_HTTP_1_1_LENGTH);
-
-      /* expects length prefixed preference ordered list of protocols in wire
-       * format
-       */
-      SSL_CTX_set_alpn_protos(connssl->ctx, protocols,
-          NGHTTP2_PROTO_VERSION_ID_LEN + ALPN_HTTP_1_1_LENGTH + 2);
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
+      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
 
-      infof(data, "ALPN, offering %s, %s\n", NGHTTP2_PROTO_VERSION_ID,
-            ALPN_HTTP_1_1);
+      memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
+          NGHTTP2_PROTO_VERSION_ID_LEN);
+      cur += NGHTTP2_PROTO_VERSION_ID_LEN;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
     }
 #endif
+
+    protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
+    memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
+    cur += ALPN_HTTP_1_1_LENGTH;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    /* expects length prefixed preference ordered list of protocols in wire
+     * format
+     */
+    SSL_CTX_set_alpn_protos(connssl->ctx, protocols, cur);
   }
 #endif
 
@@ -1759,6 +1938,7 @@ ossl_connect_step1(struct connectdata *conn,
     failf(data, "failed setting cipher list: %s", ciphers);
     return CURLE_SSL_CIPHER;
   }
+  infof(data, "Cipher selection: %s\n", ciphers);
 
 #ifdef USE_TLS_SRP
   if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
@@ -1768,7 +1948,7 @@ ossl_connect_step1(struct connectdata *conn,
       failf(data, "Unable to set SRP user name");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
-    if(!SSL_CTX_set_srp_password(connssl->ctx,data->set.ssl.password)) {
+    if(!SSL_CTX_set_srp_password(connssl->ctx, data->set.ssl.password)) {
       failf(data, "failed setting SRP password");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
@@ -1790,7 +1970,7 @@ ossl_connect_step1(struct connectdata *conn,
                                        data->set.str[STRING_SSL_CAPATH])) {
       if(data->set.ssl.verifypeer) {
         /* Fail if we insist on successfully verifying the server. */
-        failf(data,"error setting certificate verify locations:\n"
+        failf(data, "error setting certificate verify locations:\n"
               "  CAfile: %s\n  CApath: %s",
               data->set.str[STRING_SSL_CAFILE]?
               data->set.str[STRING_SSL_CAFILE]: "none",
@@ -1824,9 +2004,9 @@ ossl_connect_step1(struct connectdata *conn,
     lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx),
                                  X509_LOOKUP_file());
     if(!lookup ||
-       (!X509_load_crl_file(lookup,data->set.str[STRING_SSL_CRLFILE],
+       (!X509_load_crl_file(lookup, data->set.str[STRING_SSL_CRLFILE],
                             X509_FILETYPE_PEM)) ) {
-      failf(data,"error loading CRL file: %s",
+      failf(data, "error loading CRL file: %s",
             data->set.str[STRING_SSL_CRLFILE]);
       return CURLE_SSL_CRL_BADFILE;
     }
@@ -1841,21 +2021,35 @@ ossl_connect_step1(struct connectdata *conn,
           data->set.str[STRING_SSL_CRLFILE]: "none");
   }
 
+  /* Try building a chain using issuers in the trusted store first to avoid
+  problems with server-sent legacy intermediates.
+  Newer versions of OpenSSL do alternate chain checking by default which
+  gives us the same fix without as much of a performance hit (slight), so we
+  prefer that if available.
+  https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
+  */
+#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
+  if(data->set.ssl.verifypeer) {
+    X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
+                         X509_V_FLAG_TRUSTED_FIRST);
+  }
+#endif
+
   /* SSL always tries to verify the peer, this only says whether it should
    * fail to connect if the verification fails, or if it should continue
    * anyway. In the latter case the result of the verification is checked with
    * SSL_get_verify_result() below. */
   SSL_CTX_set_verify(connssl->ctx,
                      data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
-                     cert_verify_callback);
+                     NULL);
 
   /* give application a chance to interfere with SSL set up. */
   if(data->set.ssl.fsslctx) {
-    retcode = (*data->set.ssl.fsslctx)(data, connssl->ctx,
-                                       data->set.ssl.fsslctxp);
-    if(retcode) {
-      failf(data,"error signaled by ssl ctx callback");
-      return retcode;
+    result = (*data->set.ssl.fsslctx)(data, connssl->ctx,
+                                      data->set.ssl.fsslctxp);
+    if(result) {
+      failf(data, "error signaled by ssl ctx callback");
+      return result;
     }
   }
 
@@ -1867,6 +2061,13 @@ ossl_connect_step1(struct connectdata *conn,
     failf(data, "SSL: couldn't create a context (handle)!");
     return CURLE_OUT_OF_MEMORY;
   }
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+  if(data->set.ssl.verifystatus)
+    SSL_set_tlsext_status_type(connssl->handle, TLSEXT_STATUSTYPE_ocsp);
+#endif
+
   SSL_set_connect_state(connssl->handle);
 
   connssl->server_cert = 0x0;
@@ -1887,7 +2088,7 @@ ossl_connect_step1(struct connectdata *conn,
     /* we got a session id, use it! */
     if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
       failf(data, "SSL: SSL_set_session failed: %s",
-            ERR_error_string(ERR_get_error(),NULL));
+            ERR_error_string(ERR_get_error(), NULL));
       return CURLE_SSL_CONNECT_ERROR;
     }
     /* Informational message */
@@ -1897,16 +2098,16 @@ ossl_connect_step1(struct connectdata *conn,
   /* pass the raw socket into the SSL layers */
   if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
     failf(data, "SSL: SSL_set_fd failed: %s",
-          ERR_error_string(ERR_get_error(),NULL));
+          ERR_error_string(ERR_get_error(), NULL));
     return CURLE_SSL_CONNECT_ERROR;
   }
 
   connssl->connecting_state = ssl_connect_2;
+
   return CURLE_OK;
 }
 
-static CURLcode
-ossl_connect_step2(struct connectdata *conn, int sockindex)
+static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
 {
   struct SessionHandle *data = conn->data;
   int err;
@@ -1936,10 +2137,9 @@ ossl_connect_step2(struct connectdata *conn, int sockindex)
     else {
       /* untreated error */
       unsigned long errdetail;
-      char error_buffer[256]; /* OpenSSL documents that this must be at least
-                                 256 bytes long. */
-      CURLcode rc;
-      const char *cert_problem = NULL;
+      char error_buffer[256]=""; /* OpenSSL documents that this must be at
+                                    least 256 bytes long. */
+      CURLcode result;
       long lerr;
 
       connssl->connecting_state = ssl_connect_2; /* the connection failed,
@@ -1962,7 +2162,7 @@ ossl_connect_step2(struct connectdata *conn, int sockindex)
            SSL routines:
            SSL3_GET_SERVER_CERTIFICATE:
            certificate verify failed */
-        rc = CURLE_SSL_CACERT;
+        result = CURLE_SSL_CACERT;
 
         lerr = SSL_get_verify_result(connssl->handle);
         if(lerr != X509_V_OK) {
@@ -1971,12 +2171,13 @@ ossl_connect_step2(struct connectdata *conn, int sockindex)
                    X509_verify_cert_error_string(lerr));
         }
         else
-          cert_problem = "SSL certificate problem, verify that the CA cert is"
-            " OK.";
-
+          /* strcpy() is fine here as long as the string fits within
+             error_buffer */
+          strcpy(error_buffer,
+                 "SSL certificate problem, check your CA cert");
         break;
       default:
-        rc = CURLE_SSL_CONNECT_ERROR;
+        result = CURLE_SSL_CONNECT_ERROR;
         SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
         break;
       }
@@ -1987,15 +2188,16 @@ ossl_connect_step2(struct connectdata *conn, int sockindex)
        * (RST connection etc.), OpenSSL gives no explanation whatsoever and
        * the SO_ERROR is also lost.
        */
-      if(CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
+      if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
         failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
               conn->host.name, conn->remote_port);
-        return rc;
+        return result;
       }
+
       /* Could be a CERT problem */
+      failf(data, "%s", error_buffer);
 
-      failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
-      return rc;
+      return result;
     }
   }
   else {
@@ -2003,9 +2205,9 @@ ossl_connect_step2(struct connectdata *conn, int sockindex)
     connssl->connecting_state = ssl_connect_3;
 
     /* Informational message */
-    infof (data, "SSL connection using %s / %s\n",
-           get_ssl_version_txt(SSL_get_session(connssl->handle)),
-           SSL_get_cipher(connssl->handle));
+    infof(data, "SSL connection using %s / %s\n",
+          get_ssl_version_txt(connssl->handle),
+          SSL_get_cipher(connssl->handle));
 
 #ifdef HAS_ALPN
     /* Sets data and len to negotiated protocol, len is 0 if no protocol was
@@ -2018,18 +2220,20 @@ ossl_connect_step2(struct connectdata *conn, int sockindex)
       if(len != 0) {
         infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol);
 
+#ifdef USE_NGHTTP2
         if(len == NGHTTP2_PROTO_VERSION_ID_LEN &&
-           memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len) == 0) {
-             conn->negnpn = NPN_HTTP2;
+           !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) {
+          conn->negnpn = CURL_HTTP_VERSION_2_0;
         }
-        else if(len == ALPN_HTTP_1_1_LENGTH && memcmp(ALPN_HTTP_1_1,
-            neg_protocol, ALPN_HTTP_1_1_LENGTH) == 0) {
-          conn->negnpn = NPN_HTTP1_1;
+        else
+#endif
+        if(len == ALPN_HTTP_1_1_LENGTH &&
+           !memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) {
+          conn->negnpn = CURL_HTTP_VERSION_1_1;
         }
       }
-      else {
+      else
         infof(data, "ALPN, server did not agree to a protocol\n");
-      }
     }
 #endif
 
@@ -2082,7 +2286,7 @@ static void pubkey_show(struct SessionHandle *data,
 
 #define print_pubkey_BN(_type, _name, _num)    \
 do {                              \
-  if(pubkey->pkey._type->_name != NULL) { \
+  if(pubkey->pkey._type->_name) { \
     int len = BN_num_bytes(pubkey->pkey._type->_name);  \
     if(len < CERTBUFFERSIZE) {                                    \
       BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)bufp); \
@@ -2123,7 +2327,7 @@ static int X509V3_ext(struct SessionHandle *data,
           X509_EXTENSION_get_critical(ext)?"(critical)":"");
 
     if(!X509V3_EXT_print(bio_out, ext, 0, 0))
-      M_ASN1_OCTET_STRING_print(bio_out, ext->value);
+      ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
 
     BIO_get_mem_ptr(bio_out, &biomem);
 
@@ -2160,6 +2364,7 @@ static void X509_signature(struct SessionHandle *data,
   char buf[1024];
   char *ptr = buf;
   int i;
+
   for(i=0; i<sig->length; i++)
     ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%02x:", sig->data[i]);
 
@@ -2182,7 +2387,6 @@ static void dumpcert(struct SessionHandle *data, X509 *x, int numcert)
                              "Cert", biomem->data, biomem->length);
 
   BIO_free(bio_out);
-
 }
 
 /*
@@ -2196,6 +2400,7 @@ static CURLcode get_cert_chain(struct connectdata *conn,
                                struct ssl_connect_data *connssl)
 
 {
+  CURLcode result;
   STACK_OF(X509) *sk;
   int i;
   char *bufp;
@@ -2213,9 +2418,11 @@ static CURLcode get_cert_chain(struct connectdata *conn,
   }
 
   numcerts = sk_X509_num(sk);
-  if(Curl_ssl_init_certinfo(data, numcerts)) {
+
+  result = Curl_ssl_init_certinfo(data, numcerts);
+  if(result) {
     free(bufp);
-    return CURLE_OUT_OF_MEMORY;
+    return result;
   }
 
   infof(data, "--- Certificate chain\n");
@@ -2250,28 +2457,22 @@ static CURLcode get_cert_chain(struct connectdata *conn,
     Curl_ssl_push_certinfo(data, i, "Version", bufp); /* hex */
 
     num=X509_get_serialNumber(x);
-    if(num->length <= 4) {
-      value = ASN1_INTEGER_get(num);
-      infof(data,"   Serial Number: %ld (0x%lx)\n", value, value);
-      snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
-    }
-    else {
+    {
       int left = CERTBUFFERSIZE;
 
       ptr = bufp;
-      *ptr++ = 0;
-      if(num->type == V_ASN1_NEG_INTEGER)
+      if(num->type == V_ASN1_NEG_INTEGER) {
         *ptr++='-';
+        left--;
+      }
 
-      for(j=0; (j<num->length) && (left>=4); j++) {
-        /* TODO: length restrictions */
-        snprintf(ptr, 3, "%02x%c",num->data[j],
-                 ((j+1 == num->length)?'\n':':'));
-        ptr += 3;
-        left-=4;
+      for(j=0; (j<num->length) && (left>=3); j++) {
+        snprintf(ptr, left, "%02x", num->data[j]);
+        ptr += 2;
+        left -= 2;
       }
       if(num->length)
-        infof(data,"   Serial Number: %s\n", bufp);
+        infof(data, "   Serial Number: %s\n", bufp);
       else
         bufp[0]=0;
     }
@@ -2357,6 +2558,65 @@ static CURLcode get_cert_chain(struct connectdata *conn,
 }
 
 /*
+ * Heavily modified from:
+ * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
+ */
+static CURLcode pkp_pin_peer_pubkey(X509* cert, const char *pinnedpubkey)
+{
+  /* Scratch */
+  int len1 = 0, len2 = 0;
+  unsigned char *buff1 = NULL, *temp = NULL;
+
+  /* Result is returned to caller */
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+  /* if a path wasn't specified, don't pin */
+  if(!pinnedpubkey)
+    return CURLE_OK;
+
+  if(!cert)
+    return result;
+
+  do {
+    /* Begin Gyrations to get the subjectPublicKeyInfo     */
+    /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */
+
+    /* https://groups.google.com/group/mailing.openssl.users/browse_thread
+     /thread/d61858dae102c6c7 */
+    len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
+    if(len1 < 1)
+      break; /* failed */
+
+    /* https://www.openssl.org/docs/crypto/buffer.html */
+    buff1 = temp = OPENSSL_malloc(len1);
+    if(!buff1)
+      break; /* failed */
+
+    /* https://www.openssl.org/docs/crypto/d2i_X509.html */
+    len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp);
+
+    /*
+     * These checks are verifying we got back the same values as when we
+     * sized the buffer. It's pretty weak since they should always be the
+     * same. But it gives us something to test.
+     */
+    if((len1 != len2) || !temp || ((temp - buff1) != len1))
+      break; /* failed */
+
+    /* End Gyrations */
+
+    /* The one good exit point */
+    result = Curl_pin_peer_pubkey(pinnedpubkey, buff1, len1);
+  } while(0);
+
+  /* https://www.openssl.org/docs/crypto/buffer.html */
+  if(buff1)
+    OPENSSL_free(buff1);
+
+  return result;
+}
+
+/*
  * Get the server cert, verify it and show it etc, only call failf() if the
  * 'strict' argument is TRUE as otherwise all this is for informational
  * purposes only!
@@ -2368,7 +2628,7 @@ static CURLcode servercert(struct connectdata *conn,
                            struct ssl_connect_data *connssl,
                            bool strict)
 {
-  CURLcode retcode = CURLE_OK;
+  CURLcode result = CURLE_OK;
   int rc;
   long lerr;
   ASN1_TIME *certdate;
@@ -2376,6 +2636,7 @@ static CURLcode servercert(struct connectdata *conn,
   X509 *issuer;
   FILE *fp;
   char *buffer = data->state.buffer;
+  const char *ptr;
 
   if(data->set.ssl.certinfo)
     /* we've been asked to gather certificate info! */
@@ -2387,7 +2648,8 @@ static CURLcode servercert(struct connectdata *conn,
       failf(data, "SSL: couldn't get peer certificate!");
     return CURLE_PEER_FAILED_VERIFICATION;
   }
-  infof (data, "Server certificate:\n");
+
+  infof(data, "Server certificate:\n");
 
   rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
                          buffer, BUFSIZE);
@@ -2402,11 +2664,11 @@ static CURLcode servercert(struct connectdata *conn,
   infof(data, "\t expire date: %s\n", buffer);
 
   if(data->set.ssl.verifyhost) {
-    retcode = verifyhost(conn, connssl->server_cert);
-    if(retcode) {
+    result = verifyhost(conn, connssl->server_cert);
+    if(result) {
       X509_free(connssl->server_cert);
       connssl->server_cert = NULL;
-      return retcode;
+      return result;
     }
   }
 
@@ -2415,7 +2677,7 @@ static CURLcode servercert(struct connectdata *conn,
   if(rc) {
     if(strict)
       failf(data, "SSL: couldn't get X509-issuer name!");
-    retcode = CURLE_SSL_CONNECT_ERROR;
+    result = CURLE_SSL_CONNECT_ERROR;
   }
   else {
     infof(data, "\t issuer: %s\n", buffer);
@@ -2425,7 +2687,7 @@ static CURLcode servercert(struct connectdata *conn,
 
     /* e.g. match issuer name with provided issuer certificate */
     if(data->set.str[STRING_SSL_ISSUERCERT]) {
-      fp=fopen(data->set.str[STRING_SSL_ISSUERCERT],"r");
+      fp = fopen(data->set.str[STRING_SSL_ISSUERCERT], FOPEN_READTEXT);
       if(!fp) {
         if(strict)
           failf(data, "SSL: Unable to open issuer cert (%s)",
@@ -2434,7 +2696,8 @@ static CURLcode servercert(struct connectdata *conn,
         connssl->server_cert = NULL;
         return CURLE_SSL_ISSUER_ERROR;
       }
-      issuer = PEM_read_X509(fp,NULL,ZERO_NULL,NULL);
+
+      issuer = PEM_read_X509(fp, NULL, ZERO_NULL, NULL);
       if(!issuer) {
         if(strict)
           failf(data, "SSL: Unable to read issuer cert (%s)",
@@ -2444,8 +2707,10 @@ static CURLcode servercert(struct connectdata *conn,
         fclose(fp);
         return CURLE_SSL_ISSUER_ERROR;
       }
+
       fclose(fp);
-      if(X509_check_issued(issuer,connssl->server_cert) != X509_V_OK) {
+
+      if(X509_check_issued(issuer, connssl->server_cert) != X509_V_OK) {
         if(strict)
           failf(data, "SSL: Certificate issuer check failed (%s)",
                 data->set.str[STRING_SSL_ISSUERCERT]);
@@ -2454,13 +2719,15 @@ static CURLcode servercert(struct connectdata *conn,
         connssl->server_cert = NULL;
         return CURLE_SSL_ISSUER_ERROR;
       }
+
       infof(data, "\t SSL certificate issuer check ok (%s)\n",
             data->set.str[STRING_SSL_ISSUERCERT]);
       X509_free(issuer);
     }
 
-    lerr = data->set.ssl.certverifyresult=
+    lerr = data->set.ssl.certverifyresult =
       SSL_get_verify_result(connssl->handle);
+
     if(data->set.ssl.certverifyresult != X509_V_OK) {
       if(data->set.ssl.verifypeer) {
         /* We probably never reach this, because SSL_connect() will fail
@@ -2468,7 +2735,7 @@ static CURLcode servercert(struct connectdata *conn,
         if(strict)
           failf(data, "SSL certificate verify result: %s (%ld)",
                 X509_verify_cert_error_string(lerr), lerr);
-        retcode = CURLE_PEER_FAILED_VERIFICATION;
+        result = CURLE_PEER_FAILED_VERIFICATION;
       }
       else
         infof(data, "\t SSL certificate verify result: %s (%ld),"
@@ -2479,46 +2746,52 @@ static CURLcode servercert(struct connectdata *conn,
       infof(data, "\t SSL certificate verify ok.\n");
   }
 
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+  if(data->set.ssl.verifystatus) {
+    result = verifystatus(conn, connssl);
+    if(result) {
+      X509_free(connssl->server_cert);
+      connssl->server_cert = NULL;
+      return result;
+    }
+  }
+#endif
+
+  if(!strict)
+    /* when not strict, we don't bother about the verify cert problems */
+    result = CURLE_OK;
+
+  ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+  if(!result && ptr) {
+    result = pkp_pin_peer_pubkey(connssl->server_cert, ptr);
+    if(result)
+      failf(data, "SSL: public key does not match pinned public key!");
+  }
+
   X509_free(connssl->server_cert);
   connssl->server_cert = NULL;
   connssl->connecting_state = ssl_connect_done;
 
-  return retcode;
+  return result;
 }
 
-
-static CURLcode
-ossl_connect_step3(struct connectdata *conn,
-                   int sockindex)
+static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
 {
-  CURLcode retcode = CURLE_OK;
-  void *old_ssl_sessionid=NULL;
+  CURLcode result = CURLE_OK;
+  void *old_ssl_sessionid = NULL;
   struct SessionHandle *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  int incache;
+  bool incache;
   SSL_SESSION *our_ssl_sessionid;
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
-#ifdef HAVE_SSL_GET1_SESSION
   our_ssl_sessionid = SSL_get1_session(connssl->handle);
 
-  /* SSL_get1_session() will increment the reference
-     count and the session will stay in memory until explicitly freed with
-     SSL_SESSION_free(3), regardless of its state.
-     This function was introduced in openssl 0.9.5a. */
-#else
-  our_ssl_sessionid = SSL_get_session(connssl->handle);
-
-  /* if SSL_get1_session() is unavailable, use SSL_get_session().
-     This is an inferior option because the session can be flushed
-     at any time by openssl. It is included only so curl compiles
-     under versions of openssl < 0.9.5a.
-
-     WARNING: How curl behaves if it's session is flushed is
-     untested.
-  */
-#endif
+  /* SSL_get1_session() will increment the reference count and the session
+     will stay in memory until explicitly freed with SSL_SESSION_free(3),
+     regardless of its state. */
 
   incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
   if(incache) {
@@ -2528,15 +2801,15 @@ ossl_connect_step3(struct connectdata *conn,
       incache = FALSE;
     }
   }
+
   if(!incache) {
-    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
-                                    0 /* unknown size */);
-    if(retcode) {
+    result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+                                   0 /* unknown size */);
+    if(result) {
       failf(data, "failed to store ssl session");
-      return retcode;
+      return result;
     }
   }
-#ifdef HAVE_SSL_GET1_SESSION
   else {
     /* Session was incache, so refcount already incremented earlier.
      * Avoid further increments with each SSL_get1_session() call.
@@ -2544,7 +2817,6 @@ ossl_connect_step3(struct connectdata *conn,
      */
     SSL_SESSION_free(our_ssl_sessionid);
   }
-#endif
 
   /*
    * We check certificates to authenticate the server; otherwise we risk
@@ -2553,26 +2825,24 @@ ossl_connect_step3(struct connectdata *conn,
    * operations.
    */
 
-  if(!data->set.ssl.verifypeer && !data->set.ssl.verifyhost)
-    (void)servercert(conn, connssl, FALSE);
-  else
-    retcode = servercert(conn, connssl, TRUE);
+  result = servercert(conn, connssl,
+                      (data->set.ssl.verifypeer || data->set.ssl.verifyhost));
 
-  if(CURLE_OK == retcode)
+  if(!result)
     connssl->connecting_state = ssl_connect_done;
-  return retcode;
+
+  return result;
 }
 
 static Curl_recv ossl_recv;
 static Curl_send ossl_send;
 
-static CURLcode
-ossl_connect_common(struct connectdata *conn,
-                    int sockindex,
-                    bool nonblocking,
-                    bool *done)
+static CURLcode ossl_connect_common(struct connectdata *conn,
+                                    int sockindex,
+                                    bool nonblocking,
+                                    bool *done)
 {
-  CURLcode retcode;
+  CURLcode result;
   struct SessionHandle *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
@@ -2585,7 +2855,7 @@ ossl_connect_common(struct connectdata *conn,
     return CURLE_OK;
   }
 
-  if(ssl_connect_1==connssl->connecting_state) {
+  if(ssl_connect_1 == connssl->connecting_state) {
     /* Find out how much more time we're allowed */
     timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
@@ -2594,9 +2864,10 @@ ossl_connect_common(struct connectdata *conn,
       failf(data, "SSL connection timeout");
       return CURLE_OPERATION_TIMEDOUT;
     }
-    retcode = ossl_connect_step1(conn, sockindex);
-    if(retcode)
-      return retcode;
+
+    result = ossl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
   }
 
   while(ssl_connect_2 == connssl->connecting_state ||
@@ -2613,8 +2884,8 @@ ossl_connect_common(struct connectdata *conn,
     }
 
     /* if ssl is expecting something, check if it's available. */
-    if(connssl->connecting_state == ssl_connect_2_reading
-        || connssl->connecting_state == ssl_connect_2_writing) {
+    if(connssl->connecting_state == ssl_connect_2_reading ||
+       connssl->connecting_state == ssl_connect_2_writing) {
 
       curl_socket_t writefd = ssl_connect_2_writing==
         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
@@ -2647,23 +2918,22 @@ ossl_connect_common(struct connectdata *conn,
      * before step2 has completed while ensuring that a client using select()
      * or epoll() will always have a valid fdset to wait on.
      */
-    retcode = ossl_connect_step2(conn, sockindex);
-    if(retcode || (nonblocking &&
-                   (ssl_connect_2 == connssl->connecting_state ||
-                    ssl_connect_2_reading == connssl->connecting_state ||
-                    ssl_connect_2_writing == connssl->connecting_state)))
-      return retcode;
+    result = ossl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
 
   } /* repeat step2 until all transactions are done. */
 
-
-  if(ssl_connect_3==connssl->connecting_state) {
-    retcode = ossl_connect_step3(conn, sockindex);
-    if(retcode)
-      return retcode;
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = ossl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
   }
 
-  if(ssl_connect_done==connssl->connecting_state) {
+  if(ssl_connect_done == connssl->connecting_state) {
     connssl->state = ssl_connection_complete;
     conn->recv[sockindex] = ossl_recv;
     conn->send[sockindex] = ossl_send;
@@ -2678,32 +2948,28 @@ ossl_connect_common(struct connectdata *conn,
   return CURLE_OK;
 }
 
-CURLcode
-Curl_ossl_connect_nonblocking(struct connectdata *conn,
-                              int sockindex,
-                              bool *done)
+CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
+                                       int sockindex,
+                                       bool *done)
 {
   return ossl_connect_common(conn, sockindex, TRUE, done);
 }
 
-CURLcode
-Curl_ossl_connect(struct connectdata *conn,
-                  int sockindex)
+CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex)
 {
-  CURLcode retcode;
+  CURLcode result;
   bool done = FALSE;
 
-  retcode = ossl_connect_common(conn, sockindex, FALSE, &done);
-  if(retcode)
-    return retcode;
+  result = ossl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
 
   DEBUGASSERT(done);
 
   return CURLE_OK;
 }
 
-bool Curl_ossl_data_pending(const struct connectdata *conn,
-                            int connindex)
+bool Curl_ossl_data_pending(const struct connectdata *conn, int connindex)
 {
   if(conn->ssl[connindex].handle)
     /* SSL is in use */
@@ -2798,7 +3064,7 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
     default:
       /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
          value/errno" */
-      /* http://www.openssl.org/docs/crypto/ERR_get_error.html */
+      /* https://www.openssl.org/docs/crypto/ERR_get_error.html */
       sslerror = ERR_get_error();
       if((nread < 0) || sslerror) {
         /* If the return code was negative or there actually is an error in the
@@ -2821,8 +3087,11 @@ size_t Curl_ossl_version(char *buffer, size_t size)
      to OpenSSL in all other aspects */
   return snprintf(buffer, size, "yassl/%s", YASSL_VERSION);
 #else /* YASSL_VERSION */
+#ifdef OPENSSL_IS_BORINGSSL
+  return snprintf(buffer, size, "BoringSSL");
+#else /* OPENSSL_IS_BORINGSSL */
 
-#if(SSLEAY_VERSION_NUMBER >= 0x905000)
+#if(OPENSSL_VERSION_NUMBER >= 0x905000)
   {
     char sub[3];
     unsigned long ssleay_value;
@@ -2850,47 +3119,44 @@ size_t Curl_ossl_version(char *buffer, size_t size)
     }
 
     return snprintf(buffer, size, "%s/%lx.%lx.%lx%s",
-#ifdef OPENSSL_IS_BORINGSSL
-                    "BoringSSL"
-#else
 #ifdef LIBRESSL_VERSION_NUMBER
                     "LibreSSL"
 #else
                     "OpenSSL"
 #endif
-#endif
                     , (ssleay_value>>28)&0xf,
                     (ssleay_value>>20)&0xff,
                     (ssleay_value>>12)&0xff,
                     sub);
   }
 
-#else /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
+#else /* OPENSSL_VERSION_NUMBER is less than 0.9.5 */
 
-#if(SSLEAY_VERSION_NUMBER >= 0x900000)
+#if(OPENSSL_VERSION_NUMBER >= 0x900000)
   return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx",
-                  (SSLEAY_VERSION_NUMBER>>28)&0xff,
-                  (SSLEAY_VERSION_NUMBER>>20)&0xff,
-                  (SSLEAY_VERSION_NUMBER>>12)&0xf);
+                  (OPENSSL_VERSION_NUMBER>>28)&0xff,
+                  (OPENSSL_VERSION_NUMBER>>20)&0xff,
+                  (OPENSSL_VERSION_NUMBER>>12)&0xf);
 
-#else /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
+#else /* (OPENSSL_VERSION_NUMBER >= 0x900000) */
   {
     char sub[2];
     sub[1]='\0';
-    if(SSLEAY_VERSION_NUMBER&0x0f) {
-      sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
+    if(OPENSSL_VERSION_NUMBER&0x0f) {
+      sub[0]=(OPENSSL_VERSION_NUMBER&0x0f) + 'a' -1;
     }
     else
       sub[0]='\0';
 
     return snprintf(buffer, size, "SSL/%x.%x.%x%s",
-                    (SSLEAY_VERSION_NUMBER>>12)&0xff,
-                    (SSLEAY_VERSION_NUMBER>>8)&0xf,
-                    (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
+                    (OPENSSL_VERSION_NUMBER>>12)&0xff,
+                    (OPENSSL_VERSION_NUMBER>>8)&0xf,
+                    (OPENSSL_VERSION_NUMBER>>4)&0xf, sub);
   }
-#endif /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
-#endif /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
+#endif /* (OPENSSL_VERSION_NUMBER >= 0x900000) */
+#endif /* OPENSSL_VERSION_NUMBER is less than 0.9.5 */
 
+#endif /* OPENSSL_IS_BORINGSSL */
 #endif /* YASSL_VERSION */
 }
 
@@ -2898,8 +3164,9 @@ size_t Curl_ossl_version(char *buffer, size_t size)
 int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy,
                      size_t length)
 {
-  if(data)
+  if(data) {
     Curl_ossl_seed(data); /* Initiate the seed if not already done */
+  }
   RAND_bytes(entropy, curlx_uztosi(length));
   return 0; /* 0 as in no problem */
 }
@@ -2915,4 +3182,28 @@ void Curl_ossl_md5sum(unsigned char *tmp, /* input */
   MD5_Update(&MD5pw, tmp, tmplen);
   MD5_Final(md5sum, &MD5pw);
 }
-#endif /* USE_SSLEAY */
+
+#ifndef OPENSSL_NO_SHA256
+void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum /* output */,
+                      size_t unused)
+{
+  SHA256_CTX SHA256pw;
+  (void)unused;
+  SHA256_Init(&SHA256pw);
+  SHA256_Update(&SHA256pw, tmp, tmplen);
+  SHA256_Final(sha256sum, &SHA256pw);
+}
+#endif
+
+bool Curl_ossl_cert_status_request(void)
+{
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+#endif /* USE_OPENSSL */
diff --git a/Utilities/cmcurl/lib/vtls/openssl.h b/Utilities/cmcurl/lib/vtls/openssl.h
index 1a55ffc..a1f347a 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.h
+++ b/Utilities/cmcurl/lib/vtls/openssl.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,7 +24,7 @@
 
 #include "curl_setup.h"
 
-#ifdef USE_SSLEAY
+#ifdef USE_OPENSSL
 /*
  * This header should only be needed to get included by vtls.c and openssl.c
  */
@@ -41,7 +41,7 @@ void Curl_ossl_close(struct connectdata *conn, int sockindex);
 
 /* tell OpenSSL to close down all open information regarding connections (and
    thus session ID caching etc) */
-int Curl_ossl_close_all(struct SessionHandle *data);
+void Curl_ossl_close_all(struct SessionHandle *data);
 
 /* Sets an OpenSSL engine */
 CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine);
@@ -72,9 +72,24 @@ void Curl_ossl_md5sum(unsigned char *tmp, /* input */
                       size_t tmplen,
                       unsigned char *md5sum /* output */,
                       size_t unused);
+void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
+                      size_t tmplen,
+                      unsigned char *sha256sum /* output */,
+                      size_t unused);
+
+bool Curl_ossl_cert_status_request(void);
+
+/* Set the API backend definition to OpenSSL */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_OPENSSL
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
 
-/* this backend provides these functions: */
-#define have_curlssl_md5sum 1
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
+/* this backend suppots CURLOPT_SSL_CTX_* */
+#define have_curlssl_ssl_ctx 1
 
 /* API setup for OpenSSL */
 #define curlssl_init Curl_ossl_init
@@ -93,9 +108,13 @@ void Curl_ossl_md5sum(unsigned char *tmp, /* input */
 #define curlssl_data_pending(x,y) Curl_ossl_data_pending(x,y)
 #define curlssl_random(x,y,z) Curl_ossl_random(x,y,z)
 #define curlssl_md5sum(a,b,c,d) Curl_ossl_md5sum(a,b,c,d)
-#define CURL_SSL_BACKEND CURLSSLBACKEND_OPENSSL
+#ifndef OPENSSL_NO_SHA256
+#define curlssl_sha256sum(a,b,c,d) Curl_ossl_sha256sum(a,b,c,d)
+#endif
+#define curlssl_cert_status_request() Curl_ossl_cert_status_request()
 
-#define DEFAULT_CIPHER_SELECTION "ALL!EXPORT!EXPORT40!EXPORT56!aNULL!LOW!RC4"
+#define DEFAULT_CIPHER_SELECTION \
+  "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
 
-#endif /* USE_SSLEAY */
+#endif /* USE_OPENSSL */
 #endif /* HEADER_CURL_SSLUSE_H */
diff --git a/Utilities/cmcurl/lib/vtls/polarssl.c b/Utilities/cmcurl/lib/vtls/polarssl.c
index 5332b92..066c055 100644
--- a/Utilities/cmcurl/lib/vtls/polarssl.c
+++ b/Utilities/cmcurl/lib/vtls/polarssl.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan at gmail.com>
- * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -55,9 +55,7 @@
 #include "select.h"
 #include "rawstr.h"
 #include "polarssl_threadlock.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -120,11 +118,8 @@ static void polarssl_debug(void *context, int level, const char *line)
 #endif
 
 /* ALPN for http2? */
-#ifdef USE_NGHTTP2
-#  undef HAS_ALPN
-#  ifdef POLARSSL_SSL_ALPN
-#    define HAS_ALPN
-#  endif
+#ifdef POLARSSL_SSL_ALPN
+#  define HAS_ALPN
 #endif
 
 static Curl_recv polarssl_recv;
@@ -287,24 +282,38 @@ polarssl_connect_step1(struct connectdata *conn,
   }
 
   switch(data->set.ssl.version) {
+  default:
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_1);
+    break;
   case CURL_SSLVERSION_SSLv3:
     ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
                         SSL_MINOR_VERSION_0);
+    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_0);
     infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
     break;
   case CURL_SSLVERSION_TLSv1_0:
     ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
                         SSL_MINOR_VERSION_1);
+    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_1);
     infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.0\n");
     break;
   case CURL_SSLVERSION_TLSv1_1:
     ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
                         SSL_MINOR_VERSION_2);
+    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_2);
     infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.1\n");
     break;
   case CURL_SSLVERSION_TLSv1_2:
     ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
                         SSL_MINOR_VERSION_3);
+    ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_3);
     infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n");
     break;
   }
@@ -345,15 +354,23 @@ polarssl_connect_step1(struct connectdata *conn,
   }
 
 #ifdef HAS_ALPN
-  if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
-    if(data->set.ssl_enable_alpn) {
-      static const char* protocols[] = {
-        NGHTTP2_PROTO_VERSION_ID, ALPN_HTTP_1_1, NULL
-      };
-      ssl_set_alpn_protocols(&connssl->ssl, protocols);
-      infof(data, "ALPN, offering %s, %s\n", protocols[0],
-            protocols[1]);
+  if(data->set.ssl_enable_alpn) {
+    static const char* protocols[3];
+    int cur = 0;
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
+      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
     }
+#endif
+
+    protocols[cur++] = ALPN_HTTP_1_1;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    protocols[cur] = NULL;
+
+    ssl_set_alpn_protocols(&connssl->ssl, protocols);
   }
 #endif
 
@@ -375,47 +392,37 @@ polarssl_connect_step2(struct connectdata *conn,
   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
   char buffer[1024];
 
-#ifdef HAS_ALPN
-  const char* next_protocol;
-#endif
-
   char errorbuf[128];
   errorbuf[0] = 0;
 
   conn->recv[sockindex] = polarssl_recv;
   conn->send[sockindex] = polarssl_send;
 
-  for(;;) {
-    if(!(ret = ssl_handshake(&connssl->ssl)))
-      break;
-    else if(ret != POLARSSL_ERR_NET_WANT_READ &&
-            ret != POLARSSL_ERR_NET_WANT_WRITE) {
-#ifdef POLARSSL_ERROR_C
-     error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
-     failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
-                                                    -ret, errorbuf);
+  ret = ssl_handshake(&connssl->ssl);
 
-     return CURLE_SSL_CONNECT_ERROR;
-    }
-    else {
-      if(ret == POLARSSL_ERR_NET_WANT_READ) {
-        connssl->connecting_state = ssl_connect_2_reading;
-        return CURLE_OK;
-      }
-      if(ret == POLARSSL_ERR_NET_WANT_WRITE) {
-        connssl->connecting_state = ssl_connect_2_writing;
-        return CURLE_OK;
-      }
-      failf(data, "SSL_connect failed with error %d.", ret);
-      return CURLE_SSL_CONNECT_ERROR;
+  switch(ret) {
+  case 0:
+    break;
 
-    }
+  case POLARSSL_ERR_NET_WANT_READ:
+    connssl->connecting_state = ssl_connect_2_reading;
+    return CURLE_OK;
+
+  case POLARSSL_ERR_NET_WANT_WRITE:
+    connssl->connecting_state = ssl_connect_2_writing;
+    return CURLE_OK;
+
+  default:
+#ifdef POLARSSL_ERROR_C
+    error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+    failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
+          -ret, errorbuf);
+    return CURLE_SSL_CONNECT_ERROR;
   }
 
   infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
-        ssl_get_ciphersuite(&conn->ssl[sockindex].ssl)
-    );
+        ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) );
 
   ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl);
 
@@ -448,22 +455,24 @@ polarssl_connect_step2(struct connectdata *conn,
 
 #ifdef HAS_ALPN
   if(data->set.ssl_enable_alpn) {
-    next_protocol = ssl_get_alpn_protocol(&connssl->ssl);
+    const char *next_protocol = ssl_get_alpn_protocol(&connssl->ssl);
 
     if(next_protocol != NULL) {
       infof(data, "ALPN, server accepted to use %s\n", next_protocol);
 
-      if(strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
+#ifdef USE_NGHTTP2
+      if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
                   NGHTTP2_PROTO_VERSION_ID_LEN)) {
-        conn->negnpn = NPN_HTTP2;
+        conn->negnpn = CURL_HTTP_VERSION_2_0;
       }
-      else if(strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
-        conn->negnpn = NPN_HTTP1_1;
+      else
+#endif
+      if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
       }
     }
-    else {
+    else
       infof(data, "ALPN, server did not agree to a protocol\n");
-    }
   }
 #endif
 
@@ -477,12 +486,12 @@ static CURLcode
 polarssl_connect_step3(struct connectdata *conn,
                      int sockindex)
 {
-  CURLcode retcode = CURLE_OK;
+  CURLcode result = CURLE_OK;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   struct SessionHandle *data = conn->data;
   void *old_ssl_sessionid = NULL;
-  ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn ;
-  int incache;
+  ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn;
+  bool incache;
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
@@ -495,23 +504,21 @@ polarssl_connect_step3(struct connectdata *conn,
       incache = FALSE;
     }
   }
+
   if(!incache) {
     void *new_session = malloc(sizeof(ssl_session));
 
     if(new_session) {
-      memcpy(new_session, our_ssl_sessionid,
-             sizeof(ssl_session));
+      memcpy(new_session, our_ssl_sessionid, sizeof(ssl_session));
 
-      retcode = Curl_ssl_addsessionid(conn, new_session,
-                                   sizeof(ssl_session));
-    }
-    else {
-      retcode = CURLE_OUT_OF_MEMORY;
+      result = Curl_ssl_addsessionid(conn, new_session, sizeof(ssl_session));
     }
+    else
+      result = CURLE_OUT_OF_MEMORY;
 
-    if(retcode) {
+    if(result) {
       failf(data, "failed to store ssl session");
-      return retcode;
+      return result;
     }
   }
 
@@ -540,11 +547,6 @@ static ssize_t polarssl_send(struct connectdata *conn,
   return ret;
 }
 
-void Curl_polarssl_close_all(struct SessionHandle *data)
-{
-  (void)data;
-}
-
 void Curl_polarssl_close(struct connectdata *conn, int sockindex)
 {
   rsa_free(&conn->ssl[sockindex].rsa);
@@ -585,11 +587,15 @@ void Curl_polarssl_session_free(void *ptr)
   free(ptr);
 }
 
+/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and
+   higher) will be mbed TLS branded.. */
+
 size_t Curl_polarssl_version(char *buffer, size_t size)
 {
   unsigned int version = version_get_number();
-  return snprintf(buffer, size, "PolarSSL/%d.%d.%d", version>>24,
-                  (version>>16)&0xff, (version>>8)&0xff);
+  return snprintf(buffer, size, "%s/%d.%d.%d",
+                  version >= 0x01030A00?"mbedTLS":"PolarSSL",
+                  version>>24, (version>>16)&0xff, (version>>8)&0xff);
 }
 
 static CURLcode
@@ -598,7 +604,7 @@ polarssl_connect_common(struct connectdata *conn,
                         bool nonblocking,
                         bool *done)
 {
-  CURLcode retcode;
+  CURLcode result;
   struct SessionHandle *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
@@ -611,7 +617,7 @@ polarssl_connect_common(struct connectdata *conn,
     return CURLE_OK;
   }
 
-  if(ssl_connect_1==connssl->connecting_state) {
+  if(ssl_connect_1 == connssl->connecting_state) {
     /* Find out how much more time we're allowed */
     timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
@@ -620,9 +626,10 @@ polarssl_connect_common(struct connectdata *conn,
       failf(data, "SSL connection timeout");
       return CURLE_OPERATION_TIMEDOUT;
     }
-    retcode = polarssl_connect_step1(conn, sockindex);
-    if(retcode)
-      return retcode;
+
+    result = polarssl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
   }
 
   while(ssl_connect_2 == connssl->connecting_state ||
@@ -639,8 +646,8 @@ polarssl_connect_common(struct connectdata *conn,
     }
 
     /* if ssl is expecting something, check if it's available. */
-    if(connssl->connecting_state == ssl_connect_2_reading
-       || connssl->connecting_state == ssl_connect_2_writing) {
+    if(connssl->connecting_state == ssl_connect_2_reading ||
+       connssl->connecting_state == ssl_connect_2_writing) {
 
       curl_socket_t writefd = ssl_connect_2_writing==
         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
@@ -674,22 +681,22 @@ polarssl_connect_common(struct connectdata *conn,
      * ensuring that a client using select() or epoll() will always
      * have a valid fdset to wait on.
      */
-    retcode = polarssl_connect_step2(conn, sockindex);
-    if(retcode || (nonblocking &&
-                   (ssl_connect_2 == connssl->connecting_state ||
-                    ssl_connect_2_reading == connssl->connecting_state ||
-                    ssl_connect_2_writing == connssl->connecting_state)))
-      return retcode;
+    result = polarssl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
 
   } /* repeat step2 until all transactions are done. */
 
-  if(ssl_connect_3==connssl->connecting_state) {
-    retcode = polarssl_connect_step3(conn, sockindex);
-    if(retcode)
-      return retcode;
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = polarssl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
   }
 
-  if(ssl_connect_done==connssl->connecting_state) {
+  if(ssl_connect_done == connssl->connecting_state) {
     connssl->state = ssl_connection_complete;
     conn->recv[sockindex] = polarssl_recv;
     conn->send[sockindex] = polarssl_send;
@@ -717,12 +724,12 @@ CURLcode
 Curl_polarssl_connect(struct connectdata *conn,
                     int sockindex)
 {
-  CURLcode retcode;
+  CURLcode result;
   bool done = FALSE;
 
-  retcode = polarssl_connect_common(conn, sockindex, FALSE, &done);
-  if(retcode)
-    return retcode;
+  result = polarssl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
 
   DEBUGASSERT(done);
 
diff --git a/Utilities/cmcurl/lib/vtls/polarssl.h b/Utilities/cmcurl/lib/vtls/polarssl.h
index 9ab7e47..f980dbb 100644
--- a/Utilities/cmcurl/lib/vtls/polarssl.h
+++ b/Utilities/cmcurl/lib/vtls/polarssl.h
@@ -8,6 +8,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan at gmail.com>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -36,10 +37,6 @@ CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn,
                                            int sockindex,
                                            bool *done);
 
-/* tell PolarSSL to close down all open information regarding connections (and
-   thus session ID caching etc) */
-void Curl_polarssl_close_all(struct SessionHandle *data);
-
  /* close a SSL connection */
 void Curl_polarssl_close(struct connectdata *conn, int sockindex);
 
@@ -47,27 +44,32 @@ void Curl_polarssl_session_free(void *ptr);
 size_t Curl_polarssl_version(char *buffer, size_t size);
 int Curl_polarssl_shutdown(struct connectdata *conn, int sockindex);
 
+/* Set the API backend definition to PolarSSL */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_POLARSSL
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
 /* API setup for PolarSSL */
 #define curlssl_init() polarssl_init()
 #define curlssl_cleanup() polarssl_cleanup()
 #define curlssl_connect Curl_polarssl_connect
 #define curlssl_connect_nonblocking Curl_polarssl_connect_nonblocking
 #define curlssl_session_free(x)  Curl_polarssl_session_free(x)
-#define curlssl_close_all Curl_polarssl_close_all
+#define curlssl_close_all(x) ((void)x)
 #define curlssl_close Curl_polarssl_close
 #define curlssl_shutdown(x,y) 0
-#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN)
-#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN)
-#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
 #define curlssl_version Curl_polarssl_version
-#define curlssl_check_cxn(x) (x=x, -1)
-#define curlssl_data_pending(x,y) (x=x, y=y, 0)
-#define CURL_SSL_BACKEND CURLSSLBACKEND_POLARSSL
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
 
 /* This might cause libcurl to use a weeker random!
    TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that
 */
-#define curlssl_random(x,y,z) (x=x, y=y, z=z, CURLE_NOT_BUILT_IN)
+#define curlssl_random(x,y,z) ((void)x, (void)y, (void)z, CURLE_NOT_BUILT_IN)
 
 #endif /* USE_POLARSSL */
 #endif /* HEADER_CURL_POLARSSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c b/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c
index ad18715..62abf43 100644
--- a/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c
+++ b/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c
@@ -36,10 +36,7 @@
 #endif
 
 #include "polarssl_threadlock.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
diff --git a/Utilities/cmcurl/lib/vtls/qssl.c b/Utilities/cmcurl/lib/vtls/qssl.c
deleted file mode 100644
index 4c32053..0000000
--- a/Utilities/cmcurl/lib/vtls/qssl.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#ifdef USE_QSOSSL
-
-#include <qsossl.h>
-
-#ifdef HAVE_LIMITS_H
-#  include <limits.h>
-#endif
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "qssl.h"
-#include "vtls.h"
-#include "connect.h" /* for the connect timeout */
-#include "select.h"
-#include "x509asn1.h"
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-
-int Curl_qsossl_init(void)
-
-{
-  /* Nothing to do here. We must have connection data to initialize ssl, so
-   * defer.
-   */
-
-  return 1;
-}
-
-
-void Curl_qsossl_cleanup(void)
-
-{
-  /* Nothing to do. */
-}
-
-
-static CURLcode Curl_qsossl_init_session(struct SessionHandle * data)
-
-{
-  int rc;
-  char * certname;
-  SSLInit initstr;
-  SSLInitApp initappstr;
-
-  /* Initialize the job for SSL according to the current parameters.
-   * QsoSSL offers two ways to do it: SSL_Init_Application() that uses an
-   *  application identifier to select certificates in the main certificate
-   *  store, and SSL_Init() that uses named keyring files and a password.
-   * It is not possible to have different keyrings for the CAs and the
-   *  local certificate. We thus use the certificate name to identify the
-   *  keyring if given, else the CA file name.
-   * If the key file name is given, it is taken as the password for the
-   *  keyring in certificate file.
-   * We first try to SSL_Init_Application(), then SSL_Init() if it failed.
-   */
-
-  certname = data->set.str[STRING_CERT];
-
-  if(!certname) {
-    certname = data->set.str[STRING_SSL_CAFILE];
-
-    if(!certname)
-      return CURLE_OK;          /* Use previous setup. */
-    }
-
-  memset((char *) &initappstr, 0, sizeof initappstr);
-  initappstr.applicationID = certname;
-  initappstr.applicationIDLen = strlen(certname);
-  initappstr.protocol = SSL_VERSION_CURRENT;    /* TLSV1 compat. SSLV[23]. */
-  initappstr.sessionType = SSL_REGISTERED_AS_CLIENT;
-  rc = SSL_Init_Application(&initappstr);
-
-  if(rc == SSL_ERROR_NOT_REGISTERED) {
-    initstr.keyringFileName = certname;
-    initstr.keyringPassword = data->set.str[STRING_KEY];
-    initstr.cipherSuiteList = NULL;    /* Use default. */
-    initstr.cipherSuiteListLen = 0;
-    rc = SSL_Init(&initstr);
-    }
-
-  switch (rc) {
-
-  case 0:                             /* No error. */
-    break;
-
-  case SSL_ERROR_IO:
-    failf(data, "SSL_Init() I/O error: %s", strerror(errno));
-    return CURLE_SSL_CONNECT_ERROR;
-
-  case SSL_ERROR_BAD_CIPHER_SUITE:
-    return CURLE_SSL_CIPHER;
-
-  case SSL_ERROR_KEYPASSWORD_EXPIRED:
-  case SSL_ERROR_NOT_REGISTERED:
-    return CURLE_SSL_CONNECT_ERROR;
-
-  case SSL_ERROR_NO_KEYRING:
-    return CURLE_SSL_CACERT;
-
-  case SSL_ERROR_CERT_EXPIRED:
-    return CURLE_SSL_CERTPROBLEM;
-
-  default:
-    failf(data, "SSL_Init(): %s", SSL_Strerror(rc, NULL));
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  return CURLE_OK;
-}
-
-
-static CURLcode Curl_qsossl_create(struct connectdata * conn, int sockindex)
-
-{
-  SSLHandle * h;
-  struct ssl_connect_data * connssl = &conn->ssl[sockindex];
-
-  h = SSL_Create(conn->sock[sockindex], SSL_ENCRYPT);
-
-  if(!h) {
-    failf(conn->data, "SSL_Create() I/O error: %s", strerror(errno));
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  connssl->handle = h;
-  return CURLE_OK;
-}
-
-
-static int Curl_qsossl_trap_cert(SSLHandle * h)
-
-{
-  return 1;       /* Accept certificate. */
-}
-
-
-static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
-
-{
-  int rc;
-  struct SessionHandle * data = conn->data;
-  struct ssl_connect_data * connssl = &conn->ssl[sockindex];
-  SSLHandle * h = connssl->handle;
-  long timeout_ms;
-
-  h->exitPgm = data->set.ssl.verifypeer? NULL: Curl_qsossl_trap_cert;
-
-  /* figure out how long time we should wait at maximum */
-  timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
-  if(timeout_ms < 0) {
-    /* time-out, bail out, go home */
-    failf(data, "Connection time-out");
-    return CURLE_OPERATION_TIMEDOUT;
-  }
-
-  /* SSL_Handshake() timeout resolution is second, so round up. */
-  h->timeout = (timeout_ms + 1000 - 1) / 1000;
-
-  /* Set-up protocol. */
-
-  switch (data->set.ssl.version) {
-
-  default:
-  case CURL_SSLVERSION_DEFAULT:
-    h->protocol = SSL_VERSION_CURRENT;          /* TLSV1 compat. SSLV[23]. */
-    break;
-
-  case CURL_SSLVERSION_TLSv1:
-    h->protocol = TLS_VERSION_1;
-    break;
-
-  case CURL_SSLVERSION_SSLv2:
-    h->protocol = SSL_VERSION_2;
-    break;
-
-  case CURL_SSLVERSION_SSLv3:
-    h->protocol = SSL_VERSION_3;
-    break;
-
-  case CURL_SSLVERSION_TLSv1_0:
-  case CURL_SSLVERSION_TLSv1_1:
-  case CURL_SSLVERSION_TLSv1_2:
-    failf(data, "TLS minor version cannot be set");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  h->peerCert = NULL;
-  h->peerCertLen = 0;
-  rc = SSL_Handshake(h, SSL_HANDSHAKE_AS_CLIENT);
-
-  switch (rc) {
-
-  case 0:                             /* No error. */
-    break;
-
-  case SSL_ERROR_BAD_CERTIFICATE:
-  case SSL_ERROR_BAD_CERT_SIG:
-  case SSL_ERROR_NOT_TRUSTED_ROOT:
-    return CURLE_PEER_FAILED_VERIFICATION;
-
-  case SSL_ERROR_BAD_CIPHER_SUITE:
-  case SSL_ERROR_NO_CIPHERS:
-    return CURLE_SSL_CIPHER;
-
-  case SSL_ERROR_CERTIFICATE_REJECTED:
-  case SSL_ERROR_CERT_EXPIRED:
-  case SSL_ERROR_NO_CERTIFICATE:
-    return CURLE_SSL_CERTPROBLEM;
-
-  case SSL_ERROR_IO:
-    failf(data, "SSL_Handshake() I/O error: %s", strerror(errno));
-    return CURLE_SSL_CONNECT_ERROR;
-
-  default:
-    failf(data, "SSL_Handshake(): %s", SSL_Strerror(rc, NULL));
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  /* Verify host. */
-  rc = Curl_verifyhost(conn, h->peerCert, h->peerCert + h->peerCertLen);
-  if(rc != CURLE_OK)
-    return rc;
-
-  /* Gather certificate info. */
-  if(data->set.ssl.certinfo) {
-    if(Curl_ssl_init_certinfo(data, 1))
-      return CURLE_OUT_OF_MEMORY;
-    if(h->peerCert) {
-      rc = Curl_extract_certinfo(conn, 0, h->peerCert,
-                                 h->peerCert + h->peerCertLen);
-      if(rc != CURLE_OK)
-        return rc;
-    }
-  }
-
-  return CURLE_OK;
-}
-
-
-static Curl_recv qsossl_recv;
-static Curl_send qsossl_send;
-
-CURLcode Curl_qsossl_connect(struct connectdata * conn, int sockindex)
-
-{
-  struct SessionHandle * data = conn->data;
-  struct ssl_connect_data * connssl = &conn->ssl[sockindex];
-  int rc;
-
-  rc = Curl_qsossl_init_session(data);
-
-  if(rc == CURLE_OK) {
-    rc = Curl_qsossl_create(conn, sockindex);
-
-    if(rc == CURLE_OK) {
-      rc = Curl_qsossl_handshake(conn, sockindex);
-      if(rc != CURLE_OK)
-        SSL_Destroy(connssl->handle);
-    }
-  }
-
-  if(rc == CURLE_OK) {
-    conn->recv[sockindex] = qsossl_recv;
-    conn->send[sockindex] = qsossl_send;
-    connssl->state = ssl_connection_complete;
-  }
-  else {
-    connssl->handle = NULL;
-    connssl->use = FALSE;
-    connssl->state = ssl_connection_none;
-  }
-
-  return rc;
-}
-
-
-static int Curl_qsossl_close_one(struct ssl_connect_data * conn,
-                                 struct SessionHandle * data)
-
-{
-  int rc;
-
-  if(!conn->handle)
-    return 0;
-
-  rc = SSL_Destroy(conn->handle);
-
-  if(rc) {
-    if(rc == SSL_ERROR_IO) {
-      failf(data, "SSL_Destroy() I/O error: %s", strerror(errno));
-      return -1;
-    }
-
-    /* An SSL error. */
-    failf(data, "SSL_Destroy() returned error %s", SSL_Strerror(rc, NULL));
-    return -1;
-  }
-
-  conn->handle = NULL;
-  return 0;
-}
-
-
-void Curl_qsossl_close(struct connectdata *conn, int sockindex)
-
-{
-  struct SessionHandle *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
-  if(connssl->use)
-    (void) Curl_qsossl_close_one(connssl, data);
-}
-
-
-int Curl_qsossl_close_all(struct SessionHandle * data)
-
-{
-  /* Unimplemented. */
-  (void) data;
-  return 0;
-}
-
-
-int Curl_qsossl_shutdown(struct connectdata * conn, int sockindex)
-
-{
-  struct ssl_connect_data * connssl = &conn->ssl[sockindex];
-  struct SessionHandle *data = conn->data;
-  ssize_t nread;
-  int what;
-  int rc;
-  char buf[120];
-
-  if(!connssl->handle)
-    return 0;
-
-  if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
-    return 0;
-
-  if(Curl_qsossl_close_one(connssl, data))
-    return -1;
-
-  rc = 0;
-
-  what = Curl_socket_ready(conn->sock[sockindex],
-                           CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
-
-  for(;;) {
-    if(what < 0) {
-      /* anything that gets here is fatally bad */
-      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
-      rc = -1;
-      break;
-    }
-
-    if(!what) {                                /* timeout */
-      failf(data, "SSL shutdown timeout");
-      break;
-    }
-
-    /* Something to read, let's do it and hope that it is the close
-       notify alert from the server. No way to SSL_Read now, so use read(). */
-
-    nread = read(conn->sock[sockindex], buf, sizeof(buf));
-
-    if(nread < 0) {
-      failf(data, "read: %s", strerror(errno));
-      rc = -1;
-    }
-
-    if(nread <= 0)
-      break;
-
-    what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
-  }
-
-  return rc;
-}
-
-
-static ssize_t qsossl_send(struct connectdata * conn, int sockindex,
-                           const void * mem, size_t len, CURLcode * curlcode)
-
-{
-  /* SSL_Write() is said to return 'int' while write() and send() returns
-     'size_t' */
-  int rc;
-
-  rc = SSL_Write(conn->ssl[sockindex].handle, (void *) mem, (int) len);
-
-  if(rc < 0) {
-    switch(rc) {
-
-    case SSL_ERROR_BAD_STATE:
-      /* The operation did not complete; the same SSL I/O function
-         should be called again later. This is basically an EWOULDBLOCK
-         equivalent. */
-      *curlcode = CURLE_AGAIN;
-      return -1;
-
-    case SSL_ERROR_IO:
-      switch (errno) {
-      case EWOULDBLOCK:
-      case EINTR:
-        *curlcode = CURLE_AGAIN;
-        return -1;
-        }
-
-      failf(conn->data, "SSL_Write() I/O error: %s", strerror(errno));
-      *curlcode = CURLE_SEND_ERROR;
-      return -1;
-    }
-
-    /* An SSL error. */
-    failf(conn->data, "SSL_Write() returned error %s",
-          SSL_Strerror(rc, NULL));
-    *curlcode = CURLE_SEND_ERROR;
-    return -1;
-  }
-
-  return (ssize_t) rc; /* number of bytes */
-}
-
-
-static ssize_t qsossl_recv(struct connectdata * conn, int num, char * buf,
-                           size_t buffersize, CURLcode * curlcode)
-
-{
-  char error_buffer[120]; /* OpenSSL documents that this must be at
-                             least 120 bytes long. */
-  unsigned long sslerror;
-  int buffsize;
-  int nread;
-
-  buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
-  nread = SSL_Read(conn->ssl[num].handle, buf, buffsize);
-
-  if(nread < 0) {
-    /* failed SSL_read */
-
-    switch (nread) {
-
-    case SSL_ERROR_BAD_STATE:
-      /* there's data pending, re-invoke SSL_Read(). */
-      *curlcode = CURLE_AGAIN;
-      return -1;
-
-    case SSL_ERROR_IO:
-      switch (errno) {
-      case EWOULDBLOCK:
-        *curlcode = CURLE_AGAIN;
-        return -1;
-        }
-
-      failf(conn->data, "SSL_Read() I/O error: %s", strerror(errno));
-      *curlcode = CURLE_RECV_ERROR;
-      return -1;
-
-    default:
-      failf(conn->data, "SSL read error: %s", SSL_Strerror(nread, NULL));
-      *curlcode = CURLE_RECV_ERROR;
-      return -1;
-    }
-  }
-  return (ssize_t) nread;
-}
-
-
-size_t Curl_qsossl_version(char * buffer, size_t size)
-
-{
-  strncpy(buffer, "IBM OS/400 SSL", size);
-  return strlen(buffer);
-}
-
-
-int Curl_qsossl_check_cxn(struct connectdata * cxn)
-
-{
-  int err;
-  int errlen;
-
-  /* The only thing that can be tested here is at the socket level. */
-
-  if(!cxn->ssl[FIRSTSOCKET].handle)
-    return 0; /* connection has been closed */
-
-  err = 0;
-  errlen = sizeof err;
-
-  if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
-                 (unsigned char *) &err, &errlen) ||
-      errlen != sizeof err || err)
-    return 0; /* connection has been closed */
-
-  return -1;  /* connection status unknown */
-}
-
-#endif /* USE_QSOSSL */
diff --git a/Utilities/cmcurl/lib/vtls/qssl.h b/Utilities/cmcurl/lib/vtls/qssl.h
deleted file mode 100644
index 9764eec..0000000
--- a/Utilities/cmcurl/lib/vtls/qssl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef HEADER_CURL_QSSL_H
-#define HEADER_CURL_QSSL_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-/*
- * This header should only be needed to get included by vtls.c and qssl.c
- */
-
-#include "urldata.h"
-
-#ifdef USE_QSOSSL
-int Curl_qsossl_init(void);
-void Curl_qsossl_cleanup(void);
-CURLcode Curl_qsossl_connect(struct connectdata * conn, int sockindex);
-void Curl_qsossl_close(struct connectdata *conn, int sockindex);
-int Curl_qsossl_close_all(struct SessionHandle * data);
-int Curl_qsossl_shutdown(struct connectdata * conn, int sockindex);
-
-size_t Curl_qsossl_version(char * buffer, size_t size);
-int Curl_qsossl_check_cxn(struct connectdata * cxn);
-
-/* API setup for QsoSSL */
-#define curlssl_init Curl_qsossl_init
-#define curlssl_cleanup Curl_qsossl_cleanup
-#define curlssl_connect Curl_qsossl_connect
-
-/*  No session handling for QsoSSL */
-#define curlssl_session_free(x) Curl_nop_stmt
-#define curlssl_close_all Curl_qsossl_close_all
-#define curlssl_close Curl_qsossl_close
-#define curlssl_shutdown(x,y) Curl_qsossl_shutdown(x,y)
-#define curlssl_set_engine(x,y) CURLE_NOT_BUILT_IN
-#define curlssl_set_engine_default(x) CURLE_NOT_BUILT_IN
-#define curlssl_engines_list(x) NULL
-#define curlssl_version Curl_qsossl_version
-#define curlssl_check_cxn(x) Curl_qsossl_check_cxn(x)
-#define curlssl_data_pending(x,y) 0
-#define CURL_SSL_BACKEND CURLSSLBACKEND_QSOSSL
-#endif /* USE_QSOSSL */
-
-#endif /* HEADER_CURL_QSSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/schannel.c b/Utilities/cmcurl/lib/vtls/schannel.c
new file mode 100644
index 0000000..2174e21
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/schannel.c
@@ -0,0 +1,1501 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Marc Hoersken, <info at marc-hoersken.de>
+ * Copyright (C) 2012, Mark Salisbury, <mark.salisbury at hp.com>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all SChannel-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+/*
+ * Based upon the PolarSSL implementation in polarssl.c and polarssl.h:
+ *   Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan at gmail.com>
+ *
+ * Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
+ *   Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * Thanks for code and inspiration!
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#ifndef USE_WINDOWS_SSPI
+#  error "Can't compile SCHANNEL support without SSPI."
+#endif
+
+#include "curl_sspi.h"
+#include "schannel.h"
+#include "vtls.h"
+#include "sendf.h"
+#include "connect.h" /* for the connect timeout */
+#include "strerror.h"
+#include "select.h" /* for the socket readyness */
+#include "inet_pton.h" /* for IP addr SNI check */
+#include "curl_multibyte.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Uncomment to force verbose output
+ * #define infof(x, y, ...) printf(y, __VA_ARGS__)
+ * #define failf(x, y, ...) printf(y, __VA_ARGS__)
+ */
+
+static Curl_recv schannel_recv;
+static Curl_send schannel_send;
+
+#ifdef _WIN32_WCE
+static CURLcode verify_certificate(struct connectdata *conn, int sockindex);
+#endif
+
+static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
+                          void *BufDataPtr, unsigned long BufByteSize)
+{
+  buffer->cbBuffer = BufByteSize;
+  buffer->BufferType = BufType;
+  buffer->pvBuffer = BufDataPtr;
+}
+
+static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
+                              unsigned long NumArrElem)
+{
+  desc->ulVersion = SECBUFFER_VERSION;
+  desc->pBuffers = BufArr;
+  desc->cBuffers = NumArrElem;
+}
+
+static CURLcode
+schannel_connect_step1(struct connectdata *conn, int sockindex)
+{
+  ssize_t written = -1;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  SecBuffer outbuf;
+  SecBufferDesc outbuf_desc;
+  SCHANNEL_CRED schannel_cred;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  struct curl_schannel_cred *old_cred = NULL;
+  struct in_addr addr;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr6;
+#endif
+  TCHAR *host_name;
+  CURLcode result;
+
+  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
+        conn->host.name, conn->remote_port);
+
+  /* check for an existing re-usable credential handle */
+  if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL)) {
+    connssl->cred = old_cred;
+    infof(data, "schannel: re-using existing credential handle\n");
+  }
+  else {
+    /* setup Schannel API options */
+    memset(&schannel_cred, 0, sizeof(schannel_cred));
+    schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
+
+    if(data->set.ssl.verifypeer) {
+#ifdef _WIN32_WCE
+      /* certificate validation on CE doesn't seem to work right; we'll
+         do it following a more manual process. */
+      schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+        SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+        SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+#else
+      schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
+      if(data->set.ssl_no_revoke)
+        schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+                                 SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+      else
+        schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+#endif
+      if(data->set.ssl_no_revoke)
+        infof(data, "schannel: disabled server certificate revocation "
+                    "checks\n");
+      else
+        infof(data, "schannel: checking server certificate revocation\n");
+    }
+    else {
+      schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+        SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+        SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+      infof(data, "schannel: disabled server certificate revocation checks\n");
+    }
+
+    if(!data->set.ssl.verifyhost) {
+      schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
+      infof(data, "schannel: verifyhost setting prevents Schannel from "
+            "comparing the supplied target name with the subject "
+            "names in server certificates. Also disables SNI.\n");
+    }
+
+    switch(data->set.ssl.version) {
+    default:
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT |
+        SP_PROT_TLS1_1_CLIENT |
+        SP_PROT_TLS1_2_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_2:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
+      break;
+    case CURL_SSLVERSION_SSLv3:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
+      break;
+    case CURL_SSLVERSION_SSLv2:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT;
+      break;
+    }
+
+    /* allocate memory for the re-usable credential handle */
+    connssl->cred = (struct curl_schannel_cred *)
+      malloc(sizeof(struct curl_schannel_cred));
+    if(!connssl->cred) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memset(connssl->cred, 0, sizeof(struct curl_schannel_cred));
+
+    /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx */
+    sspi_status =
+      s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
+                                         SECPKG_CRED_OUTBOUND, NULL,
+                                         &schannel_cred, NULL, NULL,
+                                         &connssl->cred->cred_handle,
+                                         &connssl->cred->time_stamp);
+
+    if(sspi_status != SEC_E_OK) {
+      if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+        failf(data, "schannel: SNI or certificate check failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      else
+        failf(data, "schannel: AcquireCredentialsHandle failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      Curl_safefree(connssl->cred);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* Warn if SNI is disabled due to use of an IP address */
+  if(Curl_inet_pton(AF_INET, conn->host.name, &addr)
+#ifdef ENABLE_IPV6
+     || Curl_inet_pton(AF_INET6, conn->host.name, &addr6)
+#endif
+    ) {
+    infof(data, "schannel: using IP address, SNI is not supported by OS.\n");
+  }
+
+  /* setup output buffer */
+  InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
+  InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
+
+  /* setup request flags */
+  connssl->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
+    ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
+    ISC_REQ_STREAM;
+
+  /* allocate memory for the security context handle */
+  connssl->ctxt = (struct curl_schannel_ctxt *)
+    malloc(sizeof(struct curl_schannel_ctxt));
+  if(!connssl->ctxt) {
+    failf(data, "schannel: unable to allocate memory");
+    return CURLE_OUT_OF_MEMORY;
+  }
+  memset(connssl->ctxt, 0, sizeof(struct curl_schannel_ctxt));
+
+  host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+  if(!host_name)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
+
+  sspi_status = s_pSecFn->InitializeSecurityContext(
+    &connssl->cred->cred_handle, NULL, host_name,
+    connssl->req_flags, 0, 0, NULL, 0, &connssl->ctxt->ctxt_handle,
+    &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
+
+  Curl_unicodefree(host_name);
+
+  if(sspi_status != SEC_I_CONTINUE_NEEDED) {
+    if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+      failf(data, "schannel: SNI or certificate check failed: %s",
+            Curl_sspi_strerror(conn, sspi_status));
+    else
+      failf(data, "schannel: initial InitializeSecurityContext failed: %s",
+            Curl_sspi_strerror(conn, sspi_status));
+    Curl_safefree(connssl->ctxt);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "schannel: sending initial handshake data: "
+        "sending %lu bytes...\n", outbuf.cbBuffer);
+
+  /* send initial handshake data which is now stored in output buffer */
+  result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+                            outbuf.cbBuffer, &written);
+  s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
+  if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
+    failf(data, "schannel: failed to send initial handshake data: "
+          "sent %zd of %lu bytes", written, outbuf.cbBuffer);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "schannel: sent initial handshake data: "
+        "sent %zd bytes\n", written);
+
+  connssl->recv_unrecoverable_err = CURLE_OK;
+  connssl->recv_sspi_close_notify = false;
+  connssl->recv_connection_closed = false;
+
+  /* continue to second handshake step */
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_step2(struct connectdata *conn, int sockindex)
+{
+  int i;
+  ssize_t nread = -1, written = -1;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned char *reallocated_buffer;
+  size_t reallocated_length;
+  SecBuffer outbuf[3];
+  SecBufferDesc outbuf_desc;
+  SecBuffer inbuf[2];
+  SecBufferDesc inbuf_desc;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  TCHAR *host_name;
+  CURLcode result;
+  bool doread;
+
+  doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
+
+  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
+        conn->host.name, conn->remote_port);
+
+  if(!connssl->cred || !connssl->ctxt)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* buffer to store previously received and decrypted data */
+  if(connssl->decdata_buffer == NULL) {
+    connssl->decdata_offset = 0;
+    connssl->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+    connssl->decdata_buffer = malloc(connssl->decdata_length);
+    if(connssl->decdata_buffer == NULL) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* buffer to store previously received and encrypted data */
+  if(connssl->encdata_buffer == NULL) {
+    connssl->encdata_offset = 0;
+    connssl->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+    connssl->encdata_buffer = malloc(connssl->encdata_length);
+    if(connssl->encdata_buffer == NULL) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* if we need a bigger buffer to read a full message, increase buffer now */
+  if(connssl->encdata_length - connssl->encdata_offset <
+     CURL_SCHANNEL_BUFFER_FREE_SIZE) {
+    /* increase internal encrypted data buffer */
+    reallocated_length = connssl->encdata_offset +
+      CURL_SCHANNEL_BUFFER_FREE_SIZE;
+    reallocated_buffer = realloc(connssl->encdata_buffer,
+                                 reallocated_length);
+
+    if(reallocated_buffer == NULL) {
+      failf(data, "schannel: unable to re-allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    else {
+      connssl->encdata_buffer = reallocated_buffer;
+      connssl->encdata_length = reallocated_length;
+    }
+  }
+
+  for(;;) {
+    if(doread) {
+      /* read encrypted handshake data from socket */
+      result = Curl_read_plain(conn->sock[sockindex],
+                               (char *) (connssl->encdata_buffer +
+                                         connssl->encdata_offset),
+                               connssl->encdata_length -
+                               connssl->encdata_offset,
+                               &nread);
+      if(result == CURLE_AGAIN) {
+        if(connssl->connecting_state != ssl_connect_2_writing)
+          connssl->connecting_state = ssl_connect_2_reading;
+        infof(data, "schannel: failed to receive handshake, "
+              "need more data\n");
+        return CURLE_OK;
+      }
+      else if((result != CURLE_OK) || (nread == 0)) {
+        failf(data, "schannel: failed to receive handshake, "
+              "SSL/TLS connection failed");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+
+      /* increase encrypted data buffer offset */
+      connssl->encdata_offset += nread;
+    }
+
+    infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+          connssl->encdata_offset, connssl->encdata_length);
+
+    /* setup input buffers */
+    InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(connssl->encdata_offset),
+                  curlx_uztoul(connssl->encdata_offset));
+    InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&inbuf_desc, inbuf, 2);
+
+    /* setup output buffers */
+    InitSecBuffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0);
+    InitSecBuffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0);
+    InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&outbuf_desc, outbuf, 3);
+
+    if(inbuf[0].pvBuffer == NULL) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    /* copy received handshake data into input buffer */
+    memcpy(inbuf[0].pvBuffer, connssl->encdata_buffer,
+           connssl->encdata_offset);
+
+    host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+    if(!host_name)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
+
+    sspi_status = s_pSecFn->InitializeSecurityContext(
+      &connssl->cred->cred_handle, &connssl->ctxt->ctxt_handle,
+      host_name, connssl->req_flags, 0, 0, &inbuf_desc, 0, NULL,
+      &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
+
+    Curl_unicodefree(host_name);
+
+    /* free buffer for received handshake data */
+    Curl_safefree(inbuf[0].pvBuffer);
+
+    /* check if the handshake was incomplete */
+    if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+      connssl->connecting_state = ssl_connect_2_reading;
+      infof(data, "schannel: received incomplete message, need more data\n");
+      return CURLE_OK;
+    }
+
+    /* If the server has requested a client certificate, attempt to continue
+       the handshake without one. This will allow connections to servers which
+       request a client certificate but do not require it. */
+    if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
+       !(connssl->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
+      connssl->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+      connssl->connecting_state = ssl_connect_2_writing;
+      infof(data, "schannel: a client certificate has been requested\n");
+      return CURLE_OK;
+    }
+
+    /* check if the handshake needs to be continued */
+    if(sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) {
+      for(i = 0; i < 3; i++) {
+        /* search for handshake tokens that need to be send */
+        if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
+          infof(data, "schannel: sending next handshake data: "
+                "sending %lu bytes...\n", outbuf[i].cbBuffer);
+
+          /* send handshake token to server */
+          result = Curl_write_plain(conn, conn->sock[sockindex],
+                                    outbuf[i].pvBuffer, outbuf[i].cbBuffer,
+                                    &written);
+          if((result != CURLE_OK) ||
+             (outbuf[i].cbBuffer != (size_t) written)) {
+            failf(data, "schannel: failed to send next handshake data: "
+                  "sent %zd of %lu bytes", written, outbuf[i].cbBuffer);
+            return CURLE_SSL_CONNECT_ERROR;
+          }
+        }
+
+        /* free obsolete buffer */
+        if(outbuf[i].pvBuffer != NULL) {
+          s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer);
+        }
+      }
+    }
+    else {
+      if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+        failf(data, "schannel: SNI or certificate check failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      else
+        failf(data, "schannel: next InitializeSecurityContext failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* check if there was additional remaining encrypted data */
+    if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
+      infof(data, "schannel: encrypted data length: %lu\n", inbuf[1].cbBuffer);
+      /*
+        There are two cases where we could be getting extra data here:
+        1) If we're renegotiating a connection and the handshake is already
+        complete (from the server perspective), it can encrypted app data
+        (not handshake data) in an extra buffer at this point.
+        2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a
+        connection and this extra data is part of the handshake.
+        We should process the data immediately; waiting for the socket to
+        be ready may fail since the server is done sending handshake data.
+      */
+      /* check if the remaining data is less than the total amount
+         and therefore begins after the already processed data */
+      if(connssl->encdata_offset > inbuf[1].cbBuffer) {
+        memmove(connssl->encdata_buffer,
+                (connssl->encdata_buffer + connssl->encdata_offset) -
+                inbuf[1].cbBuffer, inbuf[1].cbBuffer);
+        connssl->encdata_offset = inbuf[1].cbBuffer;
+        if(sspi_status == SEC_I_CONTINUE_NEEDED) {
+          doread = FALSE;
+          continue;
+        }
+      }
+    }
+    else {
+      connssl->encdata_offset = 0;
+    }
+    break;
+  }
+
+  /* check if the handshake needs to be continued */
+  if(sspi_status == SEC_I_CONTINUE_NEEDED) {
+    connssl->connecting_state = ssl_connect_2_reading;
+    return CURLE_OK;
+  }
+
+  /* check if the handshake is complete */
+  if(sspi_status == SEC_E_OK) {
+    connssl->connecting_state = ssl_connect_3;
+    infof(data, "schannel: SSL/TLS handshake complete\n");
+  }
+
+#ifdef _WIN32_WCE
+  /* Windows CE doesn't do any server certificate validation.
+     We have to do it manually. */
+  if(data->set.ssl.verifypeer)
+    return verify_certificate(conn, sockindex);
+#endif
+
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_step3(struct connectdata *conn, int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct curl_schannel_cred *old_cred = NULL;
+  bool incache;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
+        conn->host.name, conn->remote_port);
+
+  if(!connssl->cred)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* check if the required context attributes are met */
+  if(connssl->ret_flags != connssl->req_flags) {
+    if(!(connssl->ret_flags & ISC_RET_SEQUENCE_DETECT))
+      failf(data, "schannel: failed to setup sequence detection");
+    if(!(connssl->ret_flags & ISC_RET_REPLAY_DETECT))
+      failf(data, "schannel: failed to setup replay detection");
+    if(!(connssl->ret_flags & ISC_RET_CONFIDENTIALITY))
+      failf(data, "schannel: failed to setup confidentiality");
+    if(!(connssl->ret_flags & ISC_RET_ALLOCATED_MEMORY))
+      failf(data, "schannel: failed to setup memory allocation");
+    if(!(connssl->ret_flags & ISC_RET_STREAM))
+      failf(data, "schannel: failed to setup stream orientation");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* increment the reference counter of the credential/session handle */
+  if(connssl->cred && connssl->ctxt) {
+    connssl->cred->refcount++;
+    infof(data, "schannel: incremented credential handle refcount = %d\n",
+          connssl->cred->refcount);
+  }
+
+  /* save the current session data for possible re-use */
+  incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL));
+  if(incache) {
+    if(old_cred != connssl->cred) {
+      infof(data, "schannel: old credential handle is stale, removing\n");
+      Curl_ssl_delsessionid(conn, (void *)old_cred);
+      incache = FALSE;
+    }
+  }
+
+  if(!incache) {
+    result = Curl_ssl_addsessionid(conn, (void *)connssl->cred,
+                                   sizeof(struct curl_schannel_cred));
+    if(result) {
+      failf(data, "schannel: failed to store credential handle");
+      return result;
+    }
+    else {
+      connssl->cred->cached = TRUE;
+      infof(data, "schannel: stored credential handle in session cache\n");
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_common(struct connectdata *conn, int sockindex,
+                        bool nonblocking, bool *done)
+{
+  CURLcode result;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* check out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL/TLS connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = schannel_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL/TLS connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
+
+      what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL/TLS connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    result = schannel_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = schannel_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = schannel_recv;
+    conn->send[sockindex] = schannel_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* reset our connection state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static ssize_t
+schannel_send(struct connectdata *conn, int sockindex,
+              const void *buf, size_t len, CURLcode *err)
+{
+  ssize_t written = -1;
+  size_t data_len = 0;
+  unsigned char *data = NULL;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  SecBuffer outbuf[4];
+  SecBufferDesc outbuf_desc;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  CURLcode result;
+
+  /* check if the maximum stream sizes were queried */
+  if(connssl->stream_sizes.cbMaximumMessage == 0) {
+    sspi_status = s_pSecFn->QueryContextAttributes(
+      &connssl->ctxt->ctxt_handle,
+      SECPKG_ATTR_STREAM_SIZES,
+      &connssl->stream_sizes);
+    if(sspi_status != SEC_E_OK) {
+      *err = CURLE_SEND_ERROR;
+      return -1;
+    }
+  }
+
+  /* check if the buffer is longer than the maximum message length */
+  if(len > connssl->stream_sizes.cbMaximumMessage) {
+    *err = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  /* calculate the complete message length and allocate a buffer for it */
+  data_len = connssl->stream_sizes.cbHeader + len +
+    connssl->stream_sizes.cbTrailer;
+  data = (unsigned char *) malloc(data_len);
+  if(data == NULL) {
+    *err = CURLE_OUT_OF_MEMORY;
+    return -1;
+  }
+
+  /* setup output buffers (header, data, trailer, empty) */
+  InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
+                data, connssl->stream_sizes.cbHeader);
+  InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
+                data + connssl->stream_sizes.cbHeader, curlx_uztoul(len));
+  InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
+                data + connssl->stream_sizes.cbHeader + len,
+                connssl->stream_sizes.cbTrailer);
+  InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
+  InitSecBufferDesc(&outbuf_desc, outbuf, 4);
+
+  /* copy data into output buffer */
+  memcpy(outbuf[1].pvBuffer, buf, len);
+
+  /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
+  sspi_status = s_pSecFn->EncryptMessage(&connssl->ctxt->ctxt_handle, 0,
+                                         &outbuf_desc, 0);
+
+  /* check if the message was encrypted */
+  if(sspi_status == SEC_E_OK) {
+    written = 0;
+
+    /* send the encrypted message including header, data and trailer */
+    len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
+
+    /*
+      It's important to send the full message which includes the header,
+      encrypted payload, and trailer.  Until the client receives all the
+      data a coherent message has not been delivered and the client
+      can't read any of it.
+
+      If we wanted to buffer the unwritten encrypted bytes, we would
+      tell the client that all data it has requested to be sent has been
+      sent. The unwritten encrypted bytes would be the first bytes to
+      send on the next invocation.
+      Here's the catch with this - if we tell the client that all the
+      bytes have been sent, will the client call this method again to
+      send the buffered data?  Looking at who calls this function, it
+      seems the answer is NO.
+    */
+
+    /* send entire message or fail */
+    while(len > (size_t)written) {
+      ssize_t this_write;
+      long timeleft;
+      int what;
+
+      this_write = 0;
+
+      timeleft = Curl_timeleft(conn->data, NULL, FALSE);
+      if(timeleft < 0) {
+        /* we already got the timeout */
+        failf(conn->data, "schannel: timed out sending data "
+              "(bytes sent: %zd)", written);
+        *err = CURLE_OPERATION_TIMEDOUT;
+        written = -1;
+        break;
+      }
+
+      what = Curl_socket_ready(CURL_SOCKET_BAD, conn->sock[sockindex],
+                               timeleft);
+      if(what < 0) {
+        /* fatal error */
+        failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        *err = CURLE_SEND_ERROR;
+        written = -1;
+        break;
+      }
+      else if(0 == what) {
+        failf(conn->data, "schannel: timed out sending data "
+              "(bytes sent: %zd)", written);
+        *err = CURLE_OPERATION_TIMEDOUT;
+        written = -1;
+        break;
+      }
+      /* socket is writable */
+
+      result = Curl_write_plain(conn, conn->sock[sockindex], data + written,
+                                len - written, &this_write);
+      if(result == CURLE_AGAIN)
+        continue;
+      else if(result != CURLE_OK) {
+        *err = result;
+        written = -1;
+        break;
+      }
+
+      written += this_write;
+    }
+  }
+  else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) {
+    *err = CURLE_OUT_OF_MEMORY;
+  }
+  else{
+    *err = CURLE_SEND_ERROR;
+  }
+
+  Curl_safefree(data);
+
+  if(len == (size_t)written)
+    /* Encrypted message including header, data and trailer entirely sent.
+       The return value is the number of unencrypted bytes that were sent. */
+    written = outbuf[1].cbBuffer;
+
+  return written;
+}
+
+static ssize_t
+schannel_recv(struct connectdata *conn, int sockindex,
+              char *buf, size_t len, CURLcode *err)
+{
+  size_t size = 0;
+  ssize_t nread = -1;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned char *reallocated_buffer;
+  size_t reallocated_length;
+  bool done = FALSE;
+  SecBuffer inbuf[4];
+  SecBufferDesc inbuf_desc;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  /* we want the length of the encrypted buffer to be at least large enough
+     that it can hold all the bytes requested and some TLS record overhead. */
+  size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
+
+  /****************************************************************************
+   * Don't return or set connssl->recv_unrecoverable_err unless in the cleanup.
+   * The pattern for return error is set *err, optional infof, goto cleanup.
+   *
+   * Our priority is to always return as much decrypted data to the caller as
+   * possible, even if an error occurs. The state of the decrypted buffer must
+   * always be valid. Transfer of decrypted data to the caller's buffer is
+   * handled in the cleanup.
+   */
+
+  infof(data, "schannel: client wants to read %zu bytes\n", len);
+  *err = CURLE_OK;
+
+  if(len && len <= connssl->decdata_offset) {
+    infof(data, "schannel: enough decrypted data is already available\n");
+    goto cleanup;
+  }
+  else if(connssl->recv_unrecoverable_err) {
+    *err = connssl->recv_unrecoverable_err;
+    infof(data, "schannel: an unrecoverable error occurred in a prior call\n");
+    goto cleanup;
+  }
+  else if(connssl->recv_sspi_close_notify) {
+    /* once a server has indicated shutdown there is no more encrypted data */
+    infof(data, "schannel: server indicated shutdown in a prior call\n");
+    goto cleanup;
+  }
+  else if(!len) {
+    /* It's debatable what to return when !len. Regardless we can't return
+    immediately because there may be data to decrypt (in the case we want to
+    decrypt all encrypted cached data) so handle !len later in cleanup.
+    */
+    ; /* do nothing */
+  }
+  else if(!connssl->recv_connection_closed) {
+    /* increase enc buffer in order to fit the requested amount of data */
+    size = connssl->encdata_length - connssl->encdata_offset;
+    if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
+       connssl->encdata_length < min_encdata_length) {
+      reallocated_length = connssl->encdata_offset +
+                           CURL_SCHANNEL_BUFFER_FREE_SIZE;
+      if(reallocated_length < min_encdata_length) {
+        reallocated_length = min_encdata_length;
+      }
+      reallocated_buffer = realloc(connssl->encdata_buffer,
+                                   reallocated_length);
+      if(reallocated_buffer == NULL) {
+        *err = CURLE_OUT_OF_MEMORY;
+        failf(data, "schannel: unable to re-allocate memory");
+        goto cleanup;
+      }
+
+      connssl->encdata_buffer = reallocated_buffer;
+      connssl->encdata_length = reallocated_length;
+      size = connssl->encdata_length - connssl->encdata_offset;
+      infof(data, "schannel: encdata_buffer resized %zu\n",
+            connssl->encdata_length);
+    }
+
+    infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+          connssl->encdata_offset, connssl->encdata_length);
+
+    /* read encrypted data from socket */
+    *err = Curl_read_plain(conn->sock[sockindex],
+                           (char *)(connssl->encdata_buffer +
+                                    connssl->encdata_offset),
+                           size, &nread);
+    if(*err) {
+      nread = -1;
+      if(*err == CURLE_AGAIN)
+        infof(data, "schannel: Curl_read_plain returned CURLE_AGAIN\n");
+      else if(*err == CURLE_RECV_ERROR)
+        infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n");
+      else
+        infof(data, "schannel: Curl_read_plain returned error %d\n", *err);
+    }
+    else if(nread == 0) {
+      connssl->recv_connection_closed = true;
+      infof(data, "schannel: server closed the connection\n");
+    }
+    else if(nread > 0) {
+      connssl->encdata_offset += (size_t)nread;
+      infof(data, "schannel: encrypted data got %zd\n", nread);
+    }
+  }
+
+  infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+        connssl->encdata_offset, connssl->encdata_length);
+
+  /* decrypt loop */
+  while(connssl->encdata_offset > 0 && sspi_status == SEC_E_OK &&
+        (!len || connssl->decdata_offset < len ||
+         connssl->recv_connection_closed)) {
+    /* prepare data buffer for DecryptMessage call */
+    InitSecBuffer(&inbuf[0], SECBUFFER_DATA, connssl->encdata_buffer,
+                  curlx_uztoul(connssl->encdata_offset));
+
+    /* we need 3 more empty input buffers for possible output */
+    InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBuffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBuffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&inbuf_desc, inbuf, 4);
+
+    /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx */
+    sspi_status = s_pSecFn->DecryptMessage(&connssl->ctxt->ctxt_handle,
+                                           &inbuf_desc, 0, NULL);
+
+    /* check if everything went fine (server may want to renegotiate
+       or shutdown the connection context) */
+    if(sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE ||
+       sspi_status == SEC_I_CONTEXT_EXPIRED) {
+      /* check for successfully decrypted data, even before actual
+         renegotiation or shutdown of the connection context */
+      if(inbuf[1].BufferType == SECBUFFER_DATA) {
+        infof(data, "schannel: decrypted data length: %lu\n",
+              inbuf[1].cbBuffer);
+
+        /* increase buffer in order to fit the received amount of data */
+        size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
+               inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
+        if(connssl->decdata_length - connssl->decdata_offset < size ||
+           connssl->decdata_length < len) {
+          /* increase internal decrypted data buffer */
+          reallocated_length = connssl->decdata_offset + size;
+          /* make sure that the requested amount of data fits */
+          if(reallocated_length < len) {
+            reallocated_length = len;
+          }
+          reallocated_buffer = realloc(connssl->decdata_buffer,
+                                       reallocated_length);
+          if(reallocated_buffer == NULL) {
+            *err = CURLE_OUT_OF_MEMORY;
+            failf(data, "schannel: unable to re-allocate memory");
+            goto cleanup;
+          }
+          connssl->decdata_buffer = reallocated_buffer;
+          connssl->decdata_length = reallocated_length;
+        }
+
+        /* copy decrypted data to internal buffer */
+        size = inbuf[1].cbBuffer;
+        if(size) {
+          memcpy(connssl->decdata_buffer + connssl->decdata_offset,
+                 inbuf[1].pvBuffer, size);
+          connssl->decdata_offset += size;
+        }
+
+        infof(data, "schannel: decrypted data added: %zu\n", size);
+        infof(data, "schannel: decrypted data cached: offset %zu length %zu\n",
+              connssl->decdata_offset, connssl->decdata_length);
+      }
+
+      /* check for remaining encrypted data */
+      if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
+        infof(data, "schannel: encrypted data length: %lu\n",
+              inbuf[3].cbBuffer);
+
+        /* check if the remaining data is less than the total amount
+         * and therefore begins after the already processed data
+         */
+        if(connssl->encdata_offset > inbuf[3].cbBuffer) {
+          /* move remaining encrypted data forward to the beginning of
+             buffer */
+          memmove(connssl->encdata_buffer,
+                  (connssl->encdata_buffer + connssl->encdata_offset) -
+                  inbuf[3].cbBuffer, inbuf[3].cbBuffer);
+          connssl->encdata_offset = inbuf[3].cbBuffer;
+        }
+
+        infof(data, "schannel: encrypted data cached: offset %zu length %zu\n",
+              connssl->encdata_offset, connssl->encdata_length);
+      }
+      else {
+        /* reset encrypted buffer offset, because there is no data remaining */
+        connssl->encdata_offset = 0;
+      }
+
+      /* check if server wants to renegotiate the connection context */
+      if(sspi_status == SEC_I_RENEGOTIATE) {
+        infof(data, "schannel: remote party requests renegotiation\n");
+        if(*err && *err != CURLE_AGAIN) {
+          infof(data, "schannel: can't renogotiate, an error is pending\n");
+          goto cleanup;
+        }
+        if(connssl->encdata_offset) {
+          *err = CURLE_RECV_ERROR;
+          infof(data, "schannel: can't renogotiate, "
+                      "encrypted data available\n");
+          goto cleanup;
+        }
+        /* begin renegotiation */
+        infof(data, "schannel: renegotiating SSL/TLS connection\n");
+        connssl->state = ssl_connection_negotiating;
+        connssl->connecting_state = ssl_connect_2_writing;
+        *err = schannel_connect_common(conn, sockindex, FALSE, &done);
+        if(*err) {
+          infof(data, "schannel: renegotiation failed\n");
+          goto cleanup;
+        }
+        /* now retry receiving data */
+        sspi_status = SEC_E_OK;
+        infof(data, "schannel: SSL/TLS connection renegotiated\n");
+        continue;
+      }
+      /* check if the server closed the connection */
+      else if(sspi_status == SEC_I_CONTEXT_EXPIRED) {
+        /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
+           returned so we have to work around that in cleanup. */
+        connssl->recv_sspi_close_notify = true;
+        if(!connssl->recv_connection_closed) {
+          connssl->recv_connection_closed = true;
+          infof(data, "schannel: server closed the connection\n");
+        }
+        goto cleanup;
+      }
+    }
+    else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+      if(!*err)
+        *err = CURLE_AGAIN;
+      infof(data, "schannel: failed to decrypt data, need more data\n");
+      goto cleanup;
+    }
+    else {
+      *err = CURLE_RECV_ERROR;
+      infof(data, "schannel: failed to read data from server: %s\n",
+            Curl_sspi_strerror(conn, sspi_status));
+      goto cleanup;
+    }
+  }
+
+  infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+        connssl->encdata_offset, connssl->encdata_length);
+
+  infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
+        connssl->decdata_offset, connssl->decdata_length);
+
+cleanup:
+  /* Warning- there is no guarantee the encdata state is valid at this point */
+  infof(data, "schannel: schannel_recv cleanup\n");
+
+  /* Error if the connection has closed without a close_notify.
+  Behavior here is a matter of debate. We don't want to be vulnerable to a
+  truncation attack however there's some browser precedent for ignoring the
+  close_notify for compatibility reasons.
+  Additionally, Windows 2000 (v5.0) is a special case since it seems it doesn't
+  return close_notify. In that case if the connection was closed we assume it
+  was graceful (close_notify) since there doesn't seem to be a way to tell.
+  */
+  if(len && !connssl->decdata_offset && connssl->recv_connection_closed &&
+     !connssl->recv_sspi_close_notify) {
+    BOOL isWin2k;
+    ULONGLONG cm;
+    OSVERSIONINFOEX osver;
+
+    memset(&osver, 0, sizeof(osver));
+    osver.dwOSVersionInfoSize = sizeof(osver);
+    osver.dwMajorVersion = 5;
+
+    cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+    cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+
+    isWin2k = VerifyVersionInfo(&osver,
+                                (VER_MAJORVERSION | VER_MINORVERSION |
+                                 VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
+                                cm);
+
+    if(isWin2k && sspi_status == SEC_E_OK)
+      connssl->recv_sspi_close_notify = true;
+    else {
+      *err = CURLE_RECV_ERROR;
+      infof(data, "schannel: server closed abruptly (missing close_notify)\n");
+    }
+  }
+
+  /* Any error other than CURLE_AGAIN is an unrecoverable error. */
+  if(*err && *err != CURLE_AGAIN)
+      connssl->recv_unrecoverable_err = *err;
+
+  size = len < connssl->decdata_offset ? len : connssl->decdata_offset;
+  if(size) {
+    memcpy(buf, connssl->decdata_buffer, size);
+    memmove(connssl->decdata_buffer, connssl->decdata_buffer + size,
+            connssl->decdata_offset - size);
+    connssl->decdata_offset -= size;
+
+    infof(data, "schannel: decrypted data returned %zu\n", size);
+    infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
+          connssl->decdata_offset, connssl->decdata_length);
+    *err = CURLE_OK;
+    return (ssize_t)size;
+  }
+
+  if(!*err && !connssl->recv_connection_closed)
+      *err = CURLE_AGAIN;
+
+  /* It's debatable what to return when !len. We could return whatever error we
+  got from decryption but instead we override here so the return is consistent.
+  */
+  if(!len)
+    *err = CURLE_OK;
+
+  return *err ? -1 : 0;
+}
+
+CURLcode
+Curl_schannel_connect_nonblocking(struct connectdata *conn, int sockindex,
+                                  bool *done)
+{
+  return schannel_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode
+Curl_schannel_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = schannel_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->use) /* SSL/TLS is in use */
+    return (connssl->encdata_offset > 0 ||
+            connssl->decdata_offset > 0 ) ? TRUE : FALSE;
+  else
+    return FALSE;
+}
+
+void Curl_schannel_close(struct connectdata *conn, int sockindex)
+{
+  if(conn->ssl[sockindex].use)
+    /* if the SSL/TLS channel hasn't been shut down yet, do that now. */
+    Curl_ssl_shutdown(conn, sockindex);
+}
+
+int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
+{
+  /* See http://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx
+   * Shutting Down an Schannel Connection
+   */
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
+        conn->host.name, conn->remote_port);
+
+  if(connssl->cred && connssl->ctxt) {
+    SecBufferDesc BuffDesc;
+    SecBuffer Buffer;
+    SECURITY_STATUS sspi_status;
+    SecBuffer outbuf;
+    SecBufferDesc outbuf_desc;
+    CURLcode result;
+    TCHAR *host_name;
+    DWORD dwshut = SCHANNEL_SHUTDOWN;
+
+    InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
+    InitSecBufferDesc(&BuffDesc, &Buffer, 1);
+
+    sspi_status = s_pSecFn->ApplyControlToken(&connssl->ctxt->ctxt_handle,
+                                              &BuffDesc);
+
+    if(sspi_status != SEC_E_OK)
+      failf(data, "schannel: ApplyControlToken failure: %s",
+            Curl_sspi_strerror(conn, sspi_status));
+
+    host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+    if(!host_name)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* setup output buffer */
+    InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
+
+    sspi_status = s_pSecFn->InitializeSecurityContext(
+      &connssl->cred->cred_handle,
+      &connssl->ctxt->ctxt_handle,
+      host_name,
+      connssl->req_flags,
+      0,
+      0,
+      NULL,
+      0,
+      &connssl->ctxt->ctxt_handle,
+      &outbuf_desc,
+      &connssl->ret_flags,
+      &connssl->ctxt->time_stamp);
+
+    Curl_unicodefree(host_name);
+
+    if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
+      /* send close message which is in output buffer */
+      ssize_t written;
+      result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+                                outbuf.cbBuffer, &written);
+
+      s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
+      if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
+        infof(data, "schannel: failed to send close msg: %s"
+              " (bytes written: %zd)\n", curl_easy_strerror(result), written);
+      }
+    }
+  }
+
+  /* free SSPI Schannel API security context handle */
+  if(connssl->ctxt) {
+    infof(data, "schannel: clear security context handle\n");
+    s_pSecFn->DeleteSecurityContext(&connssl->ctxt->ctxt_handle);
+    Curl_safefree(connssl->ctxt);
+  }
+
+  /* free SSPI Schannel API credential handle */
+  if(connssl->cred) {
+    /* decrement the reference counter of the credential/session handle */
+    if(connssl->cred->refcount > 0) {
+      connssl->cred->refcount--;
+      infof(data, "schannel: decremented credential handle refcount = %d\n",
+            connssl->cred->refcount);
+    }
+
+    /* if the handle was not cached and the refcount is zero */
+    if(!connssl->cred->cached && connssl->cred->refcount == 0) {
+      infof(data, "schannel: clear credential handle\n");
+      s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
+      Curl_safefree(connssl->cred);
+    }
+  }
+
+  /* free internal buffer for received encrypted data */
+  if(connssl->encdata_buffer != NULL) {
+    Curl_safefree(connssl->encdata_buffer);
+    connssl->encdata_length = 0;
+    connssl->encdata_offset = 0;
+  }
+
+  /* free internal buffer for received decrypted data */
+  if(connssl->decdata_buffer != NULL) {
+    Curl_safefree(connssl->decdata_buffer);
+    connssl->decdata_length = 0;
+    connssl->decdata_offset = 0;
+  }
+
+  return CURLE_OK;
+}
+
+void Curl_schannel_session_free(void *ptr)
+{
+  struct curl_schannel_cred *cred = ptr;
+
+  if(cred && cred->cached) {
+    if(cred->refcount == 0) {
+      s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
+      Curl_safefree(cred);
+    }
+    else {
+      cred->cached = FALSE;
+    }
+  }
+}
+
+int Curl_schannel_init(void)
+{
+  return (Curl_sspi_global_init() == CURLE_OK ? 1 : 0);
+}
+
+void Curl_schannel_cleanup(void)
+{
+  Curl_sspi_global_cleanup();
+}
+
+size_t Curl_schannel_version(char *buffer, size_t size)
+{
+  size = snprintf(buffer, size, "WinSSL");
+
+  return size;
+}
+
+int Curl_schannel_random(unsigned char *entropy, size_t length)
+{
+  HCRYPTPROV hCryptProv = 0;
+
+  if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
+                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+    return 1;
+
+  if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) {
+    CryptReleaseContext(hCryptProv, 0UL);
+    return 1;
+  }
+
+  CryptReleaseContext(hCryptProv, 0UL);
+  return 0;
+}
+
+#ifdef _WIN32_WCE
+static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
+{
+  SECURITY_STATUS status;
+  struct SessionHandle *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CURLcode result = CURLE_OK;
+  CERT_CONTEXT *pCertContextServer = NULL;
+  const CERT_CHAIN_CONTEXT *pChainContext = NULL;
+
+  status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
+                                            SECPKG_ATTR_REMOTE_CERT_CONTEXT,
+                                            &pCertContextServer);
+
+  if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
+    failf(data, "schannel: Failed to read remote certificate context: %s",
+          Curl_sspi_strerror(conn, status));
+    result = CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  if(result == CURLE_OK) {
+    CERT_CHAIN_PARA ChainPara;
+    memset(&ChainPara, 0, sizeof(ChainPara));
+    ChainPara.cbSize = sizeof(ChainPara);
+
+    if(!CertGetCertificateChain(NULL,
+                                pCertContextServer,
+                                NULL,
+                                pCertContextServer->hCertStore,
+                                &ChainPara,
+                                (data->set.ssl_no_revoke ? 0 :
+                                 CERT_CHAIN_REVOCATION_CHECK_CHAIN),
+                                NULL,
+                                &pChainContext)) {
+      failf(data, "schannel: CertGetCertificateChain failed: %s",
+            Curl_sspi_strerror(conn, GetLastError()));
+      pChainContext = NULL;
+      result = CURLE_PEER_FAILED_VERIFICATION;
+    }
+
+    if(result == CURLE_OK) {
+      CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
+      DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
+      dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
+      if(dwTrustErrorMask) {
+        if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_REVOKED");
+        else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_PARTIAL_CHAIN");
+        else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_UNTRUSTED_ROOT");
+        else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_NOT_TIME_VALID");
+        else
+          failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
+                dwTrustErrorMask);
+        result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+    }
+  }
+
+  if(result == CURLE_OK) {
+    if(data->set.ssl.verifyhost) {
+      TCHAR cert_hostname_buff[128];
+      xcharp_u hostname;
+      xcharp_u cert_hostname;
+      DWORD len;
+
+      cert_hostname.const_tchar_ptr = cert_hostname_buff;
+      hostname.tchar_ptr = Curl_convert_UTF8_to_tchar(conn->host.name);
+
+      /* TODO: Fix this for certificates with multiple alternative names.
+      Right now we're only asking for the first preferred alternative name.
+      Instead we'd need to do all via CERT_NAME_SEARCH_ALL_NAMES_FLAG
+      (if WinCE supports that?) and run this section in a loop for each.
+      https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx
+      curl: (51) schannel: CertGetNameString() certificate hostname
+      (.google.com) did not match connection (google.com)
+      */
+      len = CertGetNameString(pCertContextServer,
+                              CERT_NAME_DNS_TYPE,
+                              0,
+                              NULL,
+                              cert_hostname.tchar_ptr,
+                              128);
+      if(len > 0 && *cert_hostname.tchar_ptr == '*') {
+        /* this is a wildcard cert.  try matching the last len - 1 chars */
+        int hostname_len = strlen(conn->host.name);
+        cert_hostname.tchar_ptr++;
+        if(_tcsicmp(cert_hostname.const_tchar_ptr,
+                    hostname.const_tchar_ptr + hostname_len - len + 2) != 0)
+          result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else if(len == 0 || _tcsicmp(hostname.const_tchar_ptr,
+                                   cert_hostname.const_tchar_ptr) != 0) {
+        result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+      if(result == CURLE_PEER_FAILED_VERIFICATION) {
+        char *_cert_hostname;
+        _cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname.tchar_ptr);
+        failf(data, "schannel: CertGetNameString() certificate hostname "
+              "(%s) did not match connection (%s)",
+              _cert_hostname, conn->host.name);
+        Curl_unicodefree(_cert_hostname);
+      }
+      Curl_unicodefree(hostname.tchar_ptr);
+    }
+  }
+
+  if(pChainContext)
+    CertFreeCertificateChain(pChainContext);
+
+  if(pCertContextServer)
+    CertFreeCertificateContext(pCertContextServer);
+
+  return result;
+}
+#endif /* _WIN32_WCE */
+
+#endif /* USE_SCHANNEL */
diff --git a/Utilities/cmcurl/lib/vtls/schannel.h b/Utilities/cmcurl/lib/vtls/schannel.h
new file mode 100644
index 0000000..5329584
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/schannel.h
@@ -0,0 +1,118 @@
+#ifndef HEADER_CURL_SCHANNEL_H
+#define HEADER_CURL_SCHANNEL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012, Marc Hoersken, <info at marc-hoersken.de>, et al.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#include "urldata.h"
+
+#ifndef UNISP_NAME_A
+#define UNISP_NAME_A "Microsoft Unified Security Protocol Provider"
+#endif
+
+#ifndef UNISP_NAME_W
+#define UNISP_NAME_W L"Microsoft Unified Security Protocol Provider"
+#endif
+
+#ifndef UNISP_NAME
+#ifdef UNICODE
+#define UNISP_NAME  UNISP_NAME_W
+#else
+#define UNISP_NAME  UNISP_NAME_A
+#endif
+#endif
+
+#ifndef SP_PROT_SSL2_CLIENT
+#define SP_PROT_SSL2_CLIENT             0x00000008
+#endif
+
+#ifndef SP_PROT_SSL3_CLIENT
+#define SP_PROT_SSL3_CLIENT             0x00000008
+#endif
+
+#ifndef SP_PROT_TLS1_CLIENT
+#define SP_PROT_TLS1_CLIENT             0x00000080
+#endif
+
+#ifndef SP_PROT_TLS1_0_CLIENT
+#define SP_PROT_TLS1_0_CLIENT           SP_PROT_TLS1_CLIENT
+#endif
+
+#ifndef SP_PROT_TLS1_1_CLIENT
+#define SP_PROT_TLS1_1_CLIENT           0x00000200
+#endif
+
+#ifndef SP_PROT_TLS1_2_CLIENT
+#define SP_PROT_TLS1_2_CLIENT           0x00000800
+#endif
+
+#ifndef SECBUFFER_ALERT
+#define SECBUFFER_ALERT                 17
+#endif
+
+/* Both schannel buffer sizes must be > 0 */
+#define CURL_SCHANNEL_BUFFER_INIT_SIZE   4096
+#define CURL_SCHANNEL_BUFFER_FREE_SIZE   1024
+
+
+CURLcode Curl_schannel_connect(struct connectdata *conn, int sockindex);
+
+CURLcode Curl_schannel_connect_nonblocking(struct connectdata *conn,
+                                           int sockindex,
+                                           bool *done);
+
+bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex);
+void Curl_schannel_close(struct connectdata *conn, int sockindex);
+int Curl_schannel_shutdown(struct connectdata *conn, int sockindex);
+void Curl_schannel_session_free(void *ptr);
+
+int Curl_schannel_init(void);
+void Curl_schannel_cleanup(void);
+size_t Curl_schannel_version(char *buffer, size_t size);
+
+int Curl_schannel_random(unsigned char *entropy, size_t length);
+
+/* Set the API backend definition to Schannel */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_SCHANNEL
+
+/* API setup for Schannel */
+#define curlssl_init Curl_schannel_init
+#define curlssl_cleanup Curl_schannel_cleanup
+#define curlssl_connect Curl_schannel_connect
+#define curlssl_connect_nonblocking Curl_schannel_connect_nonblocking
+#define curlssl_session_free Curl_schannel_session_free
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_schannel_close
+#define curlssl_shutdown Curl_schannel_shutdown
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_schannel_version
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending Curl_schannel_data_pending
+#define curlssl_random(x,y,z) ((void)x, Curl_schannel_random(y,z))
+
+#endif /* USE_SCHANNEL */
+#endif /* HEADER_CURL_SCHANNEL_H */
diff --git a/Utilities/cmcurl/lib/vtls/vtls.c b/Utilities/cmcurl/lib/vtls/vtls.c
index 88511b8..01bbc61 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.c
+++ b/Utilities/cmcurl/lib/vtls/vtls.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,7 +31,6 @@
    Curl_ossl_ - prefix for OpenSSL ones
    Curl_gtls_ - prefix for GnuTLS ones
    Curl_nss_ - prefix for NSS ones
-   Curl_qssl_ - prefix for QsoSSL ones
    Curl_gskit_ - prefix for GSKit ones
    Curl_polarssl_ - prefix for PolarSSL ones
    Curl_cyassl_ - prefix for CyaSSL ones
@@ -60,29 +59,20 @@
 #include "urldata.h"
 
 #include "vtls.h" /* generic SSL protos etc */
-#include "openssl.h" /* OpenSSL versions */
-#include "gtls.h"   /* GnuTLS versions */
-#include "nssg.h"   /* NSS versions */
-#include "qssl.h"   /* QSOSSL versions */
-#include "gskit.h"  /* Global Secure ToolKit versions */
-#include "polarssl.h" /* PolarSSL versions */
-#include "axtls.h"  /* axTLS versions */
-#include "cyassl.h"  /* CyaSSL versions */
-#include "curl_schannel.h" /* Schannel SSPI version */
-#include "curl_darwinssl.h" /* SecureTransport (Darwin) version */
 #include "slist.h"
 #include "sendf.h"
 #include "rawstr.h"
 #include "url.h"
-#include "curl_memory.h"
 #include "progress.h"
 #include "share.h"
 #include "timeval.h"
+#include "curl_md5.h"
+#include "warnless.h"
+#include "curl_base64.h"
+#include "curl_printf.h"
 
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
 #include "memdebug.h"
 
 /* convenience macro to check if this handle is using a shared SSL session */
@@ -193,7 +183,7 @@ void Curl_free_ssl_config(struct ssl_config_data* sslc)
 
 unsigned int Curl_rand(struct SessionHandle *data)
 {
-  unsigned int r;
+  unsigned int r = 0;
   static unsigned int randseed;
   static bool seeded = FALSE;
 
@@ -286,47 +276,66 @@ void Curl_ssl_cleanup(void)
   }
 }
 
+static bool ssl_prefs_check(struct SessionHandle *data)
+{
+  /* check for CURLOPT_SSLVERSION invalid parameter value */
+  if((data->set.ssl.version < 0)
+     || (data->set.ssl.version >= CURL_SSLVERSION_LAST)) {
+    failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION");
+    return FALSE;
+  }
+  return TRUE;
+}
+
 CURLcode
 Curl_ssl_connect(struct connectdata *conn, int sockindex)
 {
-  CURLcode res;
+  CURLcode result;
+
+  if(!ssl_prefs_check(conn->data))
+    return CURLE_SSL_CONNECT_ERROR;
+
   /* mark this is being ssl-enabled from here on. */
   conn->ssl[sockindex].use = TRUE;
   conn->ssl[sockindex].state = ssl_connection_negotiating;
 
-  res = curlssl_connect(conn, sockindex);
+  result = curlssl_connect(conn, sockindex);
 
-  if(!res)
+  if(!result)
     Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
 
-  return res;
+  return result;
 }
 
 CURLcode
 Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
                              bool *done)
 {
-  CURLcode res;
+  CURLcode result;
+
+  if(!ssl_prefs_check(conn->data))
+    return CURLE_SSL_CONNECT_ERROR;
+
   /* mark this is being ssl requested from here on. */
   conn->ssl[sockindex].use = TRUE;
 #ifdef curlssl_connect_nonblocking
-  res = curlssl_connect_nonblocking(conn, sockindex, done);
+  result = curlssl_connect_nonblocking(conn, sockindex, done);
 #else
   *done = TRUE; /* fallback to BLOCKING */
-  res = curlssl_connect(conn, sockindex);
+  result = curlssl_connect(conn, sockindex);
 #endif /* non-blocking connect support */
-  if(!res && *done)
+  if(!result && *done)
     Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
-  return res;
+  return result;
 }
 
 /*
  * Check if there's a session ID for the given connection in the cache, and if
  * there's one suitable, it is provided. Returns TRUE when no entry matched.
  */
-int Curl_ssl_getsessionid(struct connectdata *conn,
-                          void **ssl_sessionid,
-                          size_t *idsize) /* set 0 if unknown */
+bool Curl_ssl_getsessionid(struct connectdata *conn,
+                           void **ssl_sessionid,
+                           size_t *idsize) /* set 0 if unknown */
 {
   struct curl_ssl_session *check;
   struct SessionHandle *data = conn->data;
@@ -473,9 +482,8 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
   store->sessionid = ssl_sessionid;
   store->idsize = idsize;
   store->age = *general_age;    /* set current age */
-  if(store->name)
     /* free it if there's one already present */
-    free(store->name);
+  free(store->name);
   store->name = clone_host;               /* clone host name */
   store->remote_port = conn->remote_port; /* port number */
 
@@ -601,34 +609,37 @@ void Curl_ssl_free_certinfo(struct SessionHandle *data)
 {
   int i;
   struct curl_certinfo *ci = &data->info.certs;
+
   if(ci->num_of_certs) {
     /* free all individual lists used */
     for(i=0; i<ci->num_of_certs; i++) {
       curl_slist_free_all(ci->certinfo[i]);
       ci->certinfo[i] = NULL;
     }
+
     free(ci->certinfo); /* free the actual array too */
     ci->certinfo = NULL;
     ci->num_of_certs = 0;
   }
 }
 
-int Curl_ssl_init_certinfo(struct SessionHandle * data,
-                           int num)
+CURLcode Curl_ssl_init_certinfo(struct SessionHandle *data, int num)
 {
-  struct curl_certinfo * ci = &data->info.certs;
-  struct curl_slist * * table;
+  struct curl_certinfo *ci = &data->info.certs;
+  struct curl_slist **table;
 
-  /* Initialize the certificate information structures. Return 0 if OK, else 1.
-   */
+  /* Free any previous certificate information structures */
   Curl_ssl_free_certinfo(data);
-  ci->num_of_certs = num;
+
+  /* Allocate the required certificate information structures */
   table = calloc((size_t) num, sizeof(struct curl_slist *));
   if(!table)
-    return 1;
+    return CURLE_OUT_OF_MEMORY;
 
+  ci->num_of_certs = num;
   ci->certinfo = table;
-  return 0;
+
+  return CURLE_OK;
 }
 
 /*
@@ -643,7 +654,7 @@ CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
   struct curl_certinfo * ci = &data->info.certs;
   char * output;
   struct curl_slist * nl;
-  CURLcode res = CURLE_OK;
+  CURLcode result = CURLE_OK;
   size_t labellen = strlen(label);
   size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
 
@@ -664,11 +675,11 @@ CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
   if(!nl) {
     free(output);
     curl_slist_free_all(ci->certinfo[certnum]);
-    res = CURLE_OUT_OF_MEMORY;
+    result = CURLE_OUT_OF_MEMORY;
   }
 
   ci->certinfo[certnum] = nl;
-  return res;
+  return result;
 }
 
 /*
@@ -692,14 +703,260 @@ int Curl_ssl_random(struct SessionHandle *data,
   return curlssl_random(data, entropy, length);
 }
 
-#ifdef have_curlssl_md5sum
-void Curl_ssl_md5sum(unsigned char *tmp, /* input */
-                     size_t tmplen,
-                     unsigned char *md5sum, /* output */
-                     size_t md5len)
+/*
+ * Public key pem to der conversion
+ */
+
+static CURLcode pubkey_pem_to_der(const char *pem,
+                                  unsigned char **der, size_t *der_len)
+{
+  char *stripped_pem, *begin_pos, *end_pos;
+  size_t pem_count, stripped_pem_count = 0, pem_len;
+  CURLcode result;
+
+  /* if no pem, exit. */
+  if(!pem)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  begin_pos = strstr(pem, "-----BEGIN PUBLIC KEY-----");
+  if(!begin_pos)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  pem_count = begin_pos - pem;
+  /* Invalid if not at beginning AND not directly following \n */
+  if(0 != pem_count && '\n' != pem[pem_count - 1])
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* 26 is length of "-----BEGIN PUBLIC KEY-----" */
+  pem_count += 26;
+
+  /* Invalid if not directly following \n */
+  end_pos = strstr(pem + pem_count, "\n-----END PUBLIC KEY-----");
+  if(!end_pos)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  pem_len = end_pos - pem;
+
+  stripped_pem = malloc(pem_len - pem_count + 1);
+  if(!stripped_pem)
+    return CURLE_OUT_OF_MEMORY;
+
+  /*
+   * Here we loop through the pem array one character at a time between the
+   * correct indices, and place each character that is not '\n' or '\r'
+   * into the stripped_pem array, which should represent the raw base64 string
+   */
+  while(pem_count < pem_len) {
+    if('\n' != pem[pem_count] && '\r' != pem[pem_count])
+      stripped_pem[stripped_pem_count++] = pem[pem_count];
+    ++pem_count;
+  }
+  /* Place the null terminator in the correct place */
+  stripped_pem[stripped_pem_count] = '\0';
+
+  result = Curl_base64_decode(stripped_pem, der, der_len);
+
+  Curl_safefree(stripped_pem);
+
+  return result;
+}
+
+/*
+ * Generic pinned public key check.
+ */
+
+CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
+                              const unsigned char *pubkey, size_t pubkeylen)
 {
+  FILE *fp;
+  unsigned char *buf = NULL, *pem_ptr = NULL;
+  long filesize;
+  size_t size, pem_len;
+  CURLcode pem_read;
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+#ifdef curlssl_sha256sum
+  size_t pinkeylen;
+  char *pinkeycopy, *begin_pos, *end_pos;
+  unsigned char *sha256sumdigest = NULL, *expectedsha256sumdigest = NULL;
+#endif
+
+  /* if a path wasn't specified, don't pin */
+  if(!pinnedpubkey)
+    return CURLE_OK;
+  if(!pubkey || !pubkeylen)
+    return result;
+
+#ifdef curlssl_sha256sum
+  /* only do this if pinnedpubkey starts with "sha256//", length 8 */
+  if(strncmp(pinnedpubkey, "sha256//", 8) == 0) {
+    /* compute sha256sum of public key */
+    sha256sumdigest = malloc(SHA256_DIGEST_LENGTH);
+    if(!sha256sumdigest)
+      return CURLE_OUT_OF_MEMORY;
+    curlssl_sha256sum(pubkey, pubkeylen,
+                      sha256sumdigest, SHA256_DIGEST_LENGTH);
+
+    /* it starts with sha256//, copy so we can modify it */
+    pinkeylen = strlen(pinnedpubkey) + 1;
+    pinkeycopy = malloc(pinkeylen);
+    if(!pinkeycopy) {
+      Curl_safefree(sha256sumdigest);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memcpy(pinkeycopy, pinnedpubkey, pinkeylen);
+    /* point begin_pos to the copy, and start extracting keys */
+    begin_pos = pinkeycopy;
+    do {
+      end_pos = strstr(begin_pos, ";sha256//");
+      /*
+       * if there is an end_pos, null terminate,
+       * otherwise it'll go to the end of the original string
+       */
+      if(end_pos)
+        end_pos[0] = '\0';
+
+      /* decode base64 pinnedpubkey, 8 is length of "sha256//" */
+      pem_read = Curl_base64_decode(begin_pos + 8,
+                                    &expectedsha256sumdigest, &size);
+      /* if not valid base64, don't bother comparing or freeing */
+      if(!pem_read) {
+        /* compare sha256 digests directly */
+        if(SHA256_DIGEST_LENGTH == size &&
+           !memcmp(sha256sumdigest, expectedsha256sumdigest,
+                   SHA256_DIGEST_LENGTH)) {
+          result = CURLE_OK;
+          Curl_safefree(expectedsha256sumdigest);
+          break;
+        }
+        Curl_safefree(expectedsha256sumdigest);
+      }
+
+      /*
+       * change back the null-terminator we changed earlier,
+       * and look for next begin
+       */
+      if(end_pos) {
+        end_pos[0] = ';';
+        begin_pos = strstr(end_pos, "sha256//");
+      }
+    } while(end_pos && begin_pos);
+    Curl_safefree(sha256sumdigest);
+    Curl_safefree(pinkeycopy);
+    return result;
+  }
+#endif
+
+  fp = fopen(pinnedpubkey, "rb");
+  if(!fp)
+    return result;
+
+  do {
+    /* Determine the file's size */
+    if(fseek(fp, 0, SEEK_END))
+      break;
+    filesize = ftell(fp);
+    if(fseek(fp, 0, SEEK_SET))
+      break;
+    if(filesize < 0 || filesize > MAX_PINNED_PUBKEY_SIZE)
+      break;
+
+    /*
+     * if the size of our certificate is bigger than the file
+     * size then it can't match
+     */
+    size = curlx_sotouz((curl_off_t) filesize);
+    if(pubkeylen > size)
+      break;
+
+    /*
+     * Allocate buffer for the pinned key
+     * With 1 additional byte for null terminator in case of PEM key
+     */
+    buf = malloc(size + 1);
+    if(!buf)
+      break;
+
+    /* Returns number of elements read, which should be 1 */
+    if((int) fread(buf, size, 1, fp) != 1)
+      break;
+
+    /* If the sizes are the same, it can't be base64 encoded, must be der */
+    if(pubkeylen == size) {
+      if(!memcmp(pubkey, buf, pubkeylen))
+        result = CURLE_OK;
+      break;
+    }
+
+    /*
+     * Otherwise we will assume it's PEM and try to decode it
+     * after placing null terminator
+     */
+    buf[size] = '\0';
+    pem_read = pubkey_pem_to_der((const char *)buf, &pem_ptr, &pem_len);
+    /* if it wasn't read successfully, exit */
+    if(pem_read)
+      break;
+
+    /*
+     * if the size of our certificate doesn't match the size of
+     * the decoded file, they can't be the same, otherwise compare
+     */
+    if(pubkeylen == pem_len && !memcmp(pubkey, pem_ptr, pubkeylen))
+      result = CURLE_OK;
+  } while(0);
+
+  Curl_safefree(buf);
+  Curl_safefree(pem_ptr);
+  fclose(fp);
+
+  return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
+                         size_t tmplen,
+                         unsigned char *md5sum, /* output */
+                         size_t md5len)
+{
+#ifdef curlssl_md5sum
   curlssl_md5sum(tmp, tmplen, md5sum, md5len);
+#else
+  MD5_context *MD5pw;
+
+  (void) md5len;
+
+  MD5pw = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!MD5pw)
+    return CURLE_OUT_OF_MEMORY;
+  Curl_MD5_update(MD5pw, tmp, curlx_uztoui(tmplen));
+  Curl_MD5_final(MD5pw, md5sum);
+#endif
+  return CURLE_OK;
+}
+#endif
+
+/*
+ * Check whether the SSL backend supports the status_request extension.
+ */
+bool Curl_ssl_cert_status_request(void)
+{
+#ifdef curlssl_cert_status_request
+  return curlssl_cert_status_request();
+#else
+  return FALSE;
+#endif
 }
+
+/*
+ * Check whether the SSL backend supports false start.
+ */
+bool Curl_ssl_false_start(void)
+{
+#ifdef curlssl_false_start
+  return curlssl_false_start();
+#else
+  return FALSE;
 #endif
+}
 
 #endif /* USE_SSL */
diff --git a/Utilities/cmcurl/lib/vtls/vtls.h b/Utilities/cmcurl/lib/vtls/vtls.h
index e21fdef..2349e5b 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.h
+++ b/Utilities/cmcurl/lib/vtls/vtls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,10 +23,28 @@
  ***************************************************************************/
 #include "curl_setup.h"
 
+#include "openssl.h"        /* OpenSSL versions */
+#include "gtls.h"           /* GnuTLS versions */
+#include "nssg.h"           /* NSS versions */
+#include "gskit.h"          /* Global Secure ToolKit versions */
+#include "polarssl.h"       /* PolarSSL versions */
+#include "axtls.h"          /* axTLS versions */
+#include "cyassl.h"         /* CyaSSL versions */
+#include "schannel.h"       /* Schannel SSPI version */
+#include "darwinssl.h"      /* SecureTransport (Darwin) version */
+
+#ifndef MAX_PINNED_PUBKEY_SIZE
+#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
+#endif
+
 #ifndef MD5_DIGEST_LENGTH
 #define MD5_DIGEST_LENGTH 16 /* fixed size */
 #endif
 
+#ifndef SHA256_DIGEST_LENGTH
+#define SHA256_DIGEST_LENGTH 32 /* fixed size */
+#endif
+
 /* see http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */
 #define ALPN_HTTP_1_1_LENGTH 8
 #define ALPN_HTTP_1_1 "http/1.1"
@@ -68,7 +86,7 @@ int Curl_ssl_check_cxn(struct connectdata *conn);
 /* Certificate information list handling. */
 
 void Curl_ssl_free_certinfo(struct SessionHandle *data);
-int Curl_ssl_init_certinfo(struct SessionHandle * data, int num);
+CURLcode Curl_ssl_init_certinfo(struct SessionHandle * data, int num);
 CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle * data, int certnum,
                                     const char * label, const char * value,
                                     size_t valuelen);
@@ -78,9 +96,9 @@ CURLcode Curl_ssl_push_certinfo(struct SessionHandle * data, int certnum,
 /* Functions to be used by SSL library adaptation functions */
 
 /* extract a session ID */
-int Curl_ssl_getsessionid(struct connectdata *conn,
-                          void **ssl_sessionid,
-                          size_t *idsize) /* set 0 if unknown */;
+bool Curl_ssl_getsessionid(struct connectdata *conn,
+                           void **ssl_sessionid,
+                           size_t *idsize) /* set 0 if unknown */;
 /* add a new session ID */
 CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
                                void *ssl_sessionid,
@@ -94,18 +112,24 @@ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
    in */
 int Curl_ssl_random(struct SessionHandle *data, unsigned char *buffer,
                     size_t length);
-void Curl_ssl_md5sum(unsigned char *tmp, /* input */
-                     size_t tmplen,
-                     unsigned char *md5sum, /* output */
-                     size_t md5len);
+CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
+                         size_t tmplen,
+                         unsigned char *md5sum, /* output */
+                         size_t md5len);
+/* Check pinned public key. */
+CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
+                              const unsigned char *pubkey, size_t pubkeylen);
 
-#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
+bool Curl_ssl_cert_status_request(void);
 
-#ifdef have_curlssl_md5sum
-#define HAVE_CURL_SSL_MD5SUM
-#endif
+bool Curl_ssl_false_start(void);
+
+#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
 
 #else
+/* Set the API backend definition to none */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_NONE
+
 /* When SSL support is not present, just define away these function calls */
 #define Curl_ssl_init() 1
 #define Curl_ssl_cleanup() Curl_nop_stmt
@@ -125,8 +149,9 @@ void Curl_ssl_md5sum(unsigned char *tmp, /* input */
 #define Curl_ssl_free_certinfo(x) Curl_nop_stmt
 #define Curl_ssl_connect_nonblocking(x,y,z) CURLE_NOT_BUILT_IN
 #define Curl_ssl_kill_session(x) Curl_nop_stmt
-#define Curl_ssl_random(x,y,z) CURLE_NOT_BUILT_IN
-#define CURL_SSL_BACKEND CURLSSLBACKEND_NONE
+#define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN)
+#define Curl_ssl_cert_status_request() FALSE
+#define Curl_ssl_false_start() FALSE
 #endif
 
 #endif /* HEADER_CURL_VTLS_H */
diff --git a/Utilities/cmcurl/lib/wildcard.c b/Utilities/cmcurl/lib/wildcard.c
index 7130d5e..6f55839 100644
--- a/Utilities/cmcurl/lib/wildcard.c
+++ b/Utilities/cmcurl/lib/wildcard.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,10 +25,7 @@
 #include "wildcard.h"
 #include "llist.h"
 #include "fileinfo.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -62,15 +59,10 @@ void Curl_wildcard_dtor(struct WildcardData *wc)
     wc->filelist = NULL;
   }
 
-  if(wc->path) {
-    free(wc->path);
-    wc->path = NULL;
-  }
-
-  if(wc->pattern) {
-    free(wc->pattern);
-    wc->pattern = NULL;
-  }
+  free(wc->path);
+  wc->path = NULL;
+  free(wc->pattern);
+  wc->pattern = NULL;
 
   wc->customptr = NULL;
   wc->state = CURLWC_INIT;
diff --git a/Utilities/cmcurl/lib/x509asn1.c b/Utilities/cmcurl/lib/x509asn1.c
index 1f87155..a3dfd64 100644
--- a/Utilities/cmcurl/lib/x509asn1.c
+++ b/Utilities/cmcurl/lib/x509asn1.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,7 +22,8 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_QSOSSL) || defined(USE_GSKIT) || defined(USE_NSS)
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
+    defined(USE_CYASSL)
 
 #include <curl/curl.h>
 #include "urldata.h"
@@ -33,10 +34,7 @@
 #include "inet_pton.h"
 #include "curl_base64.h"
 #include "x509asn1.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
+#include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -122,6 +120,7 @@ const char * Curl_getASN1Element(curl_asn1Element * elem,
     return (const char *) NULL;
 
   /* Process header byte. */
+  elem->header = beg;
   b = (unsigned char) *beg++;
   elem->constructed = (b & 0x20) != 0;
   elem->class = (b >> 6) & 3;
@@ -211,7 +210,6 @@ static const char * octet2str(const char * beg, const char * end)
 }
 
 static const char * bit2str(const char * beg, const char * end)
-
 {
   /* Convert an ASN.1 bit string to a printable string.
      Return the dynamically allocated string, or NULL if an error occurs. */
@@ -300,8 +298,10 @@ utf8asn1str(char * * to, int type, const char * from, const char * end)
       case 4:
         wc = (wc << 8) | *(const unsigned char *) from++;
         wc = (wc << 8) | *(const unsigned char *) from++;
+        /* fallthrough */
       case 2:
         wc = (wc << 8) | *(const unsigned char *) from++;
+        /* fallthrough */
       default: /* case 1: */
         wc = (wc << 8) | *(const unsigned char *) from++;
       }
@@ -539,8 +539,6 @@ static const char * UTime2str(const char * beg, const char * end)
 
 const char * Curl_ASN1tostr(curl_asn1Element * elem, int type)
 {
-  static const char zero = '\0';
-
   /* Convert an ASN.1 element to a printable string.
      Return the dynamically allocated string, or NULL if an error occurs. */
 
@@ -561,7 +559,7 @@ const char * Curl_ASN1tostr(curl_asn1Element * elem, int type)
   case CURL_ASN1_OCTET_STRING:
     return octet2str(elem->beg, elem->end);
   case CURL_ASN1_NULL:
-    return strdup(&zero);
+    return strdup("");
   case CURL_ASN1_OBJECT_IDENTIFIER:
     return OID2str(elem->beg, elem->end, TRUE);
   case CURL_ASN1_UTC_TIME:
@@ -682,6 +680,7 @@ void Curl_parseX509(curl_X509certificate * cert,
      Syntax is assumed to have already been checked by the SSL backend.
      See RFC 5280. */
 
+  cert->certificate.header = NULL;
   cert->certificate.beg = beg;
   cert->certificate.end = end;
 
@@ -701,6 +700,7 @@ void Curl_parseX509(curl_X509certificate * cert,
   beg = tbsCertificate.beg;
   end = tbsCertificate.end;
   /* Get optional version, get serialNumber. */
+  cert->version.header = NULL;
   cert->version.beg = &defaultVersion;
   cert->version.end = &defaultVersion + sizeof defaultVersion;;
   beg = Curl_getASN1Element(&elem, beg, end);
@@ -720,15 +720,19 @@ void Curl_parseX509(curl_X509certificate * cert,
   /* Get subject. */
   beg = Curl_getASN1Element(&cert->subject, beg, end);
   /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */
-  beg = Curl_getASN1Element(&elem, beg, end);
+  beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
   ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm,
-                            elem.beg, elem.end);
-  Curl_getASN1Element(&cert->subjectPublicKey, ccp, elem.end);
+                            cert->subjectPublicKeyInfo.beg,
+                            cert->subjectPublicKeyInfo.end);
+  Curl_getASN1Element(&cert->subjectPublicKey, ccp,
+                      cert->subjectPublicKeyInfo.end);
   /* Get optional issuerUiqueID, subjectUniqueID and extensions. */
   cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0;
   cert->extensions.tag = elem.tag = 0;
+  cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL;
   cert->issuerUniqueID.beg = cert->issuerUniqueID.end = "";
   cert->subjectUniqueID.beg = cert->subjectUniqueID.end = "";
+  cert->extensions.header = NULL;
   cert->extensions.beg = cert->extensions.end = "";
   if(beg < end)
     beg = Curl_getASN1Element(&elem, beg, end);
@@ -771,6 +775,7 @@ static const char * dumpAlgo(curl_asn1Element * param,
   /* Get algorithm parameters and return algorithm name. */
 
   beg = Curl_getASN1Element(&oid, beg, end);
+  param->header = NULL;
   param->tag = 0;
   param->beg = param->end = end;
   if(beg < end)
@@ -816,7 +821,7 @@ static void do_pubkey(struct SessionHandle * data, int certnum,
     /* Compute key length. */
     for(q = elem.beg; !*q && q < elem.end; q++)
       ;
-    len = (elem.end - q) * 8;
+    len = (unsigned long)((elem.end - q) * 8);
     if(len)
       for(i = *(unsigned char *) q; !(i & 0x80); i <<= 1)
         len--;
@@ -871,7 +876,7 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
   char * cp1;
   size_t cl1;
   char * cp2;
-  CURLcode cc;
+  CURLcode result;
   unsigned long version;
   size_t i;
   size_t j;
@@ -985,11 +990,11 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
   free((char *) ccp);
 
   /* Generate PEM certificate. */
-  cc = Curl_base64_encode(data, cert.certificate.beg,
-                          cert.certificate.end - cert.certificate.beg,
-                          &cp1, &cl1);
-  if(cc != CURLE_OK)
-    return cc;
+  result = Curl_base64_encode(data, cert.certificate.beg,
+                              cert.certificate.end - cert.certificate.beg,
+                              &cp1, &cl1);
+  if(result)
+    return result;
   /* Compute the number of characters in final certificate string. Format is:
      -----BEGIN CERTIFICATE-----\n
      <max 64 base64 characters>\n
@@ -1019,9 +1024,9 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
   return CURLE_OK;
 }
 
-#endif /* USE_QSOSSL or USE_GSKIT or USE_NSS */
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */
 
-#if defined(USE_QSOSSL) || defined(USE_GSKIT)
+#if defined(USE_GSKIT)
 
 static const char * checkOID(const char * beg, const char * end,
                              const char * oid)
@@ -1111,8 +1116,7 @@ CURLcode Curl_verifyhost(struct connectdata * conn,
           if(len > 0)
             if(strlen(dnsname) == (size_t) len)
               i = Curl_cert_hostcheck((const char *) dnsname, conn->host.name);
-          if(dnsname)
-            free(dnsname);
+          free(dnsname);
           if(!i)
             return CURLE_PEER_FAILED_VERIFICATION;
           matched = i;
@@ -1140,6 +1144,7 @@ CURLcode Curl_verifyhost(struct connectdata * conn,
   }
 
   /* Process subject. */
+  name.header = NULL;
   name.beg = name.end = "";
   q = cert.subject.beg;
   /* we have to look to the last occurrence of a commonName in the
@@ -1180,4 +1185,4 @@ CURLcode Curl_verifyhost(struct connectdata * conn,
   return CURLE_PEER_FAILED_VERIFICATION;
 }
 
-#endif /* USE_QSOSSL or USE_GSKIT */
+#endif /* USE_GSKIT */
diff --git a/Utilities/cmcurl/lib/x509asn1.h b/Utilities/cmcurl/lib/x509asn1.h
index 1741d6d..eb23e50 100644
--- a/Utilities/cmcurl/lib/x509asn1.h
+++ b/Utilities/cmcurl/lib/x509asn1.h
@@ -8,7 +8,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,7 +25,8 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_QSOSSL) || defined(USE_GSKIT) || defined(USE_NSS)
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
+    defined(USE_CYASSL)
 
 #include "urldata.h"
 
@@ -76,8 +77,9 @@
 
 /* ASN.1 parsed element. */
 typedef struct {
+  const char *  header;         /* Pointer to header byte. */
   const char *  beg;            /* Pointer to element data. */
-  const char *  end;            /* Pointer to 1st byte after element data. */
+  const char *  end;            /* Pointer to 1st byte after element. */
   unsigned char class;          /* ASN.1 element class. */
   unsigned char tag;            /* ASN.1 element tag. */
   bool          constructed;    /* Element is constructed. */
@@ -102,6 +104,7 @@ typedef struct {
   curl_asn1Element      notBefore;
   curl_asn1Element      notAfter;
   curl_asn1Element      subject;
+  curl_asn1Element      subjectPublicKeyInfo;
   curl_asn1Element      subjectPublicKeyAlgorithm;
   curl_asn1Element      subjectPublicKey;
   curl_asn1Element      issuerUniqueID;
@@ -125,5 +128,5 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
 CURLcode Curl_verifyhost(struct connectdata * conn,
                          const char * beg, const char * end);
 
-#endif /* USE_QSOSSL or USE_GSKIT or USE_NSS */
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */
 #endif /* HEADER_CURL_X509ASN1_H */
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp
index 41896a7..7b33828 100644
--- a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp
+++ b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp
@@ -529,7 +529,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
       return addError("'" + std::string(token.start_, token.end_) +
                           "' is not a number.",
                       token);
-    Value::UInt digit(c - '0');
+    Value::UInt digit(static_cast<Value::UInt>(c - '0'));
     if (value >= threshold) {
       // We've hit or exceeded the max value divided by 10 (rounded down). If
       // a) we've only just touched the limit, b) this is the last digit, and
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp
index b64cdb0..e3f4e53 100644
--- a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp
+++ b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp
@@ -24,7 +24,9 @@
 // Solaris
 #if defined(__sun)
 # include <ieeefp.h>
-# define isfinite finite
+# if !defined(isfinite)
+#  define isfinite finite
+# endif
 #endif
 
 // AIX
diff --git a/bootstrap b/bootstrap
index 14046ee..31e9b89 100755
--- a/bootstrap
+++ b/bootstrap
@@ -248,6 +248,7 @@ CMAKE_CXX_SOURCES="\
   cmCommandArgumentLexer \
   cmCommandArgumentParser \
   cmCommandArgumentParserHelper \
+  cmCommonTargetGenerator \
   cmCPackPropertiesGenerator \
   cmDefinitions \
   cmDepends \
@@ -276,8 +277,10 @@ CMAKE_CXX_SOURCES="\
   cmGeneratorExpressionNode \
   cmGeneratorExpressionParser \
   cmGeneratorExpression \
+  cmGlobalCommonGenerator \
   cmGlobalGenerator \
   cmInstallDirectoryGenerator \
+  cmLocalCommonGenerator \
   cmLocalGenerator \
   cmInstalledFile \
   cmInstallGenerator \
@@ -299,6 +302,7 @@ CMAKE_CXX_SOURCES="\
   cmMakefileLibraryTargetGenerator \
   cmMakefileTargetGenerator \
   cmMakefileUtilityTargetGenerator \
+  cmOutputConverter \
   cmOSXBundleGenerator \
   cmNewLineStyle \
   cmBootstrapCommands1 \
@@ -318,11 +322,6 @@ CMAKE_CXX_SOURCES="\
   cmExprLexer \
   cmExprParser \
   cmExprParserHelper \
-  cmGlobalNinjaGenerator \
-  cmLocalNinjaGenerator \
-  cmNinjaTargetGenerator \
-  cmNinjaNormalTargetGenerator \
-  cmNinjaUtilityTargetGenerator \
 "
 
 if ${cmake_system_mingw}; then
@@ -374,12 +373,6 @@ KWSYS_FILES="\
   SystemTools.hxx \
   Terminal.h"
 
-KWSYS_IOS_FILES="
-  fstream \
-  iosfwd \
-  iostream \
-  sstream"
-
 KWIML_FILES='
   ABI.h
   INT.h
@@ -499,30 +492,7 @@ cmake_kwsys_config_replace_string ()
                 s/@KWSYS_LFS_AVAILABLE@/${KWSYS_LFS_AVAILABLE}/g;
                 s/@KWSYS_LFS_REQUESTED@/${KWSYS_LFS_REQUESTED}/g;
                 s/@KWSYS_NAME_IS_KWSYS@/${KWSYS_NAME_IS_KWSYS}/g;
-                s/@KWSYS_IOS_USE_ANSI@/${KWSYS_IOS_USE_ANSI}/g;
-                s/@KWSYS_IOS_HAVE_STD@/${KWSYS_IOS_HAVE_STD}/g;
-                s/@KWSYS_IOS_USE_SSTREAM@/${KWSYS_IOS_USE_SSTREAM}/g;
-                s/@KWSYS_IOS_USE_STRSTREAM_H@/${KWSYS_IOS_USE_STRSTREAM_H}/g;
-                s/@KWSYS_IOS_USE_STRSTREA_H@/${KWSYS_IOS_USE_STRSTREA_H}/g;
-                s/@KWSYS_IOS_HAVE_BINARY@/${KWSYS_IOS_HAVE_BINARY}/g;
-                s/@KWSYS_STL_HAVE_STD@/${KWSYS_STL_HAVE_STD}/g;
-                s/@KWSYS_STL_STRING_HAVE_ISTREAM@/${KWSYS_STL_STRING_HAVE_ISTREAM}/g;
-                s/@KWSYS_STL_STRING_HAVE_OSTREAM@/${KWSYS_STL_STRING_HAVE_OSTREAM}/g;
-                s/@KWSYS_STL_STRING_HAVE_NEQ_CHAR@/${KWSYS_STL_STRING_HAVE_NEQ_CHAR}/g;
-                s/@KWSYS_STL_HAS_ITERATOR_TRAITS@/${KWSYS_STL_HAS_ITERATOR_TRAITS}/g;
-                s/@KWSYS_STL_HAS_ITERATOR_CATEGORY@/${KWSYS_STL_HAS_ITERATOR_CATEGORY}/g;
-                s/@KWSYS_STL_HAS___ITERATOR_CATEGORY@/${KWSYS_STL_HAS___ITERATOR_CATEGORY}/g;
-                s/@KWSYS_STL_HAS_ALLOCATOR_TEMPLATE@/${KWSYS_STL_HAS_ALLOCATOR_TEMPLATE}/g;
-                s/@KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE@/${KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE}/g;
-                s/@KWSYS_STL_HAS_ALLOCATOR_REBIND@/${KWSYS_STL_HAS_ALLOCATOR_REBIND}/g;
-                s/@KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT@/${KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT}/g;
-                s/@KWSYS_STL_HAS_ALLOCATOR_OBJECTS@/${KWSYS_STL_HAS_ALLOCATOR_OBJECTS}/g;
                 s/@KWSYS_STL_HAS_WSTRING@/${KWSYS_STL_HAS_WSTRING}/g;
-                s/@KWSYS_CXX_HAS_CSTDDEF@/${KWSYS_CXX_HAS_CSTDDEF}/g;
-                s/@KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS@/${KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS}/g;
-                s/@KWSYS_CXX_HAS_MEMBER_TEMPLATES@/${KWSYS_CXX_HAS_MEMBER_TEMPLATES}/g;
-                s/@KWSYS_CXX_HAS_FULL_SPECIALIZATION@/${KWSYS_CXX_HAS_FULL_SPECIALIZATION}/g;
-                s/@KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP@/${KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP}/g;
                 s/@KWSYS_STAT_HAS_ST_MTIM@/${KWSYS_STAT_HAS_ST_MTIM}/g;}" >> "${OUTFILE}${_tmp}"
     if [ -f "${OUTFILE}${_tmp}" ]; then
       if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then
@@ -1203,38 +1173,13 @@ KWSYS_NAME_IS_KWSYS=0
 KWSYS_BUILD_SHARED=0
 KWSYS_LFS_AVAILABLE=0
 KWSYS_LFS_REQUESTED=0
-KWSYS_IOS_USE_STRSTREAM_H=0
-KWSYS_IOS_USE_STRSTREA_H=0
-KWSYS_IOS_HAVE_STD=0
-KWSYS_IOS_USE_SSTREAM=0
-KWSYS_IOS_USE_ANSI=0
-KWSYS_IOS_HAVE_BINARY=0
-KWSYS_STL_HAVE_STD=0
 KWSYS_STAT_HAS_ST_MTIM=0
-KWSYS_STL_STRING_HAVE_NEQ_CHAR=0
-KWSYS_STL_HAS_ITERATOR_TRAITS=0
-KWSYS_STL_HAS_ITERATOR_CATEGORY=0
-KWSYS_STL_HAS___ITERATOR_CATEGORY=0
-KWSYS_STL_HAS_ALLOCATOR_TEMPLATE=0
-KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE=0
-KWSYS_STL_HAS_ALLOCATOR_REBIND=0
-KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT=0
-KWSYS_STL_HAS_ALLOCATOR_OBJECTS=0
 KWSYS_STL_HAS_WSTRING=0
 KWSYS_CXX_HAS_SETENV=0
 KWSYS_CXX_HAS_UNSETENV=0
 KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=0
 KWSYS_CXX_HAS_UTIMENSAT=0
 KWSYS_CXX_HAS_UTIMES=0
-KWSYS_CXX_HAS_CSTDDEF=0
-KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS=0
-KWSYS_CXX_HAS_MEMBER_TEMPLATES=0
-KWSYS_CXX_HAS_FULL_SPECIALIZATION=0
-KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP=0
-
-# Hardcode these kwsys features.  They work on all known UNIX compilers anyway.
-KWSYS_STL_STRING_HAVE_ISTREAM=1
-KWSYS_STL_STRING_HAVE_OSTREAM=1
 
 if cmake_try_run "${cmake_cxx_compiler}" \
   "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_SETENV" \
@@ -1264,151 +1209,7 @@ else
 fi
 
 if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAVE_STD" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_STL_HAVE_STD=1
-  echo "${cmake_cxx_compiler} has STL in std:: namespace"
-else
-  echo "${cmake_cxx_compiler} does not have STL in std:: namespace"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_IOS_USE_ANSI" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_IOS_USE_ANSI=1
-  echo "${cmake_cxx_compiler} has ANSI streams"
-else
-  echo "${cmake_cxx_compiler} does not have ANSI streams"
-fi
-
-if [ "x$KWSYS_IOS_USE_ANSI" = "x1" ]; then
-  if cmake_try_run "${cmake_cxx_compiler}" \
-    "${cmake_cxx_flags} -DTEST_KWSYS_IOS_HAVE_STD" \
-    "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-    KWSYS_IOS_HAVE_STD=1
-    echo "${cmake_cxx_compiler} has streams in std:: namespace"
-  else
-    echo "${cmake_cxx_compiler} does not have streams in std:: namespace"
-  fi
-  if cmake_try_run "${cmake_cxx_compiler}" \
-    "${cmake_cxx_flags} -DTEST_KWSYS_IOS_USE_SSTREAM" \
-    "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-    KWSYS_IOS_USE_SSTREAM=1
-    echo "${cmake_cxx_compiler} has sstream"
-  else
-    echo "${cmake_cxx_compiler} does not have sstream"
-  fi
-fi
-
-if [ "x$KWSYS_IOS_USE_SSTREAM" = "x0" ]; then
-  if cmake_try_run "${cmake_cxx_compiler}" \
-    "${cmake_cxx_flags} -DTEST_KWSYS_IOS_USE_STRSTREAM_H" \
-    "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-    KWSYS_IOS_USE_STRSTREAM_H=1
-    echo "${cmake_cxx_compiler} has strstream.h"
-  else
-    echo "${cmake_cxx_compiler} does not have strstream.h"
-  fi
-  if [ "x$KWSYS_IOS_USE_STRSTREAM_H" = "x0" ]; then
-    if cmake_try_run "${cmake_cxx_compiler}" \
-      "${cmake_cxx_flags} -DTEST_KWSYS_IOS_USE_STRSTREA_H" \
-      "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-      KWSYS_IOS_USE_STRSTREA_H=1
-      echo "${cmake_cxx_compiler} has strstrea.h"
-    else
-      echo "${cmake_cxx_compiler} does not have strstrea.h"
-    fi
-  fi
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_STL_STRING_HAVE_NEQ_CHAR -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_STL_STRING_HAVE_NEQ_CHAR=1
-  echo "${cmake_cxx_compiler} has operator!=(string, char*)"
-else
-  echo "${cmake_cxx_compiler} does not have operator!=(string, char*)"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ITERATOR_TRAITS -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_STL_HAS_ITERATOR_TRAITS=1
-  echo "${cmake_cxx_compiler} has stl iterator_traits"
-else
-  echo "${cmake_cxx_compiler} does not have stl iterator_traits"
-fi
-
-if [ "x${KWSYS_STL_HAS_ITERATOR_TRAITS}" = "x0" ]; then
-  if cmake_try_run "${cmake_cxx_compiler}" \
-    "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ITERATOR_CATEGORY -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
-    "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-    KWSYS_STL_HAS_ITERATOR_CATEGORY=1
-    echo "${cmake_cxx_compiler} has old iterator_category"
-  else
-    echo "${cmake_cxx_compiler} does not have old iterator_category"
-  fi
-  if [ "x${KWSYS_STL_HAS_ITERATOR_CATEGORY}" = "x0" ]; then
-    if cmake_try_run "${cmake_cxx_compiler}" \
-      "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS___ITERATOR_CATEGORY -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
-      "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-      KWSYS_STL_HAS___ITERATOR_CATEGORY=1
-      echo "${cmake_cxx_compiler} has old __iterator_category"
-    else
-      echo "${cmake_cxx_compiler} does not have old __iterator_category"
-    fi
-  fi
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_TEMPLATE -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_STL_HAS_ALLOCATOR_TEMPLATE=1
-  echo "${cmake_cxx_compiler} has standard template allocator"
-else
-  echo "${cmake_cxx_compiler} does not have standard template allocator"
-fi
-
-if [ "x${KWSYS_STL_HAS_ALLOCATOR_TEMPLATE}" = "x1" ]; then
-  if cmake_try_run "${cmake_cxx_compiler}" \
-    "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_REBIND -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
-    "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-    KWSYS_STL_HAS_ALLOCATOR_REBIND=1
-    echo "${cmake_cxx_compiler} has allocator<>::rebind<>"
-  else
-    echo "${cmake_cxx_compiler} does not have allocator<>::rebind<>"
-  fi
-
-  if cmake_try_run "${cmake_cxx_compiler}" \
-    "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
-    "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-    KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT=1
-    echo "${cmake_cxx_compiler} has non-standard allocator<>::max_size argument"
-  else
-    echo "${cmake_cxx_compiler} does not have non-standard allocator<>::max_size argument"
-  fi
-else
-  if cmake_try_run "${cmake_cxx_compiler}" \
-    "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
-    "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-    KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE=1
-    echo "${cmake_cxx_compiler} has old non-template allocator"
-  else
-    echo "${cmake_cxx_compiler} does not have old non-template allocator"
-  fi
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_OBJECTS -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_STL_HAS_ALLOCATOR_OBJECTS=1
-  echo "${cmake_cxx_compiler} has stl containers supporting allocator objects"
-else
-  echo "${cmake_cxx_compiler} does not have stl containers supporting allocator objects"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_WSTRING -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
+  "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_WSTRING" \
   "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
   KWSYS_STL_HAS_WSTRING=1
   echo "${cmake_cxx_compiler} has stl wstring"
@@ -1417,51 +1218,6 @@ else
 fi
 
 if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_CSTDDEF" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_CXX_HAS_CSTDDEF=1
-  echo "${cmake_cxx_compiler} has header cstddef"
-else
-  echo "${cmake_cxx_compiler} does not have header cstddef"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  echo "${cmake_cxx_compiler} does not require template friends to use <>"
-else
-  KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS=1
-  echo "${cmake_cxx_compiler} requires template friends to use <>"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_MEMBER_TEMPLATES" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_CXX_HAS_MEMBER_TEMPLATES=1
-  echo "${cmake_cxx_compiler} supports member templates"
-else
-  echo "${cmake_cxx_compiler} does not support member templates"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_FULL_SPECIALIZATION" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_CXX_HAS_FULL_SPECIALIZATION=1
-  echo "${cmake_cxx_compiler} has standard template specialization syntax"
-else
-  echo "${cmake_cxx_compiler} does not have standard template specialization syntax"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP=1
-  echo "${cmake_cxx_compiler} has argument dependent lookup"
-else
-  echo "${cmake_cxx_compiler} does not have argument dependent lookup"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
   "${cmake_cxx_flags} -DTEST_KWSYS_STAT_HAS_ST_MTIM" \
   "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
   KWSYS_STAT_HAS_ST_MTIM=1
@@ -1470,15 +1226,6 @@ else
   echo "${cmake_cxx_compiler} does not have struct stat with st_mtim member"
 fi
 
-if cmake_try_run "${cmake_cxx_compiler}" \
-  "${cmake_cxx_flags} -DTEST_KWSYS_IOS_HAVE_BINARY -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI} -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD}" \
-  "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
-  KWSYS_IOS_HAVE_BINARY=1
-  echo "${cmake_cxx_compiler} has ios::binary openmode"
-else
-  echo "${cmake_cxx_compiler} does not have ios::binary openmode"
-fi
-
 # Just to be safe, let us store compiler and flags to the header file
 
 cmake_bootstrap_version='$Revision$'
@@ -1550,22 +1297,6 @@ for a in ${KWSYS_FILES}; do
      "${cmake_bootstrap_dir}/cmsys/${a}" KWSYS_NAMESPACE cmsys
 done
 
-for a in ${KWSYS_IOS_FILES}; do
-  cmake_replace_string "${cmake_source_dir}/Source/kwsys/kwsys_ios_${a}.h.in" \
-     "${cmake_bootstrap_dir}/cmsys/ios/${a}" KWSYS_NAMESPACE cmsys
-done
-
-cmake_replace_string "${cmake_source_dir}/Source/kwsys/kwsys_stl.hxx.in" \
-   "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_a" KWSYS_STL_HEADER_EXTRA ""
-
-cmake_replace_string "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_a" \
-   "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_b" KWSYS_NAMESPACE cmsys
-
-for a in string vector set map algorithm; do
-  cmake_replace_string "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_b" \
-    "${cmake_bootstrap_dir}/cmsys/stl/${a}" KWSYS_STL_HEADER ${a}
-done
-
 for a in ${KWIML_FILES}; do
   cmake_replace_string "${cmake_source_dir}/Utilities/KWIML/${a}.in" \
      "${cmake_bootstrap_dir}/cmIML/${a}" KWIML cmIML

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-cmake/cmake.git



More information about the Pkg-cmake-commits mailing list