Merge topic 'fetchcontent-reject-CMAKE_TOOLCHAIN_FILE-env-var'

c15674a9cb FetchContent: Reject CMAKE_TOOLCHAIN_FILE env var in sub-build
31ef93f19f FetchContent: Only use @-@ replacements for sub-build CMakeLists.txt

Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !8248
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index bd55e24..21236fa 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -140,21 +140,40 @@
    |prefix_XXX_SUBDIR| for each ``<prefix>`` in
    :variable:`CMAKE_SYSTEM_PREFIX_PATH`
 
-1. .. versionadded:: 3.12
-    If called from within a find module or any other script loaded by a call to
-    :command:`find_package(<PackageName>)`, search prefixes unique to the
-    current package being found.  Specifically, look in the
-    :variable:`<PackageName>_ROOT` CMake variable and the
-    :envvar:`<PackageName>_ROOT` environment variable.
-    The package root variables are maintained as a stack, so if called from
-    nested find modules or config packages, root paths from the parent's find
-    module or config package will be searched after paths from the current
-    module or package.  In other words, the search order would be
-    ``<CurrentPackage>_ROOT``, ``ENV{<CurrentPackage>_ROOT}``,
-    ``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc.
-    This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
-    the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
-    See policy :policy:`CMP0074`.
+1. If called from within a find module or any other script loaded by a call to
+   :command:`find_package(<PackageName>)`, search prefixes unique to the
+   current package being found.  See policy :policy:`CMP0074`.
+
+   .. versionadded:: 3.12
+
+   Specifically, search paths specified by the following variables, in order:
+
+   a. :variable:`<PackageName>_ROOT` CMake variable,
+      where ``<PackageName>`` is the case-preserved package name.
+
+   b. :variable:`<PACKAGENAME>_ROOT` CMake variable,
+      where ``<PACKAGENAME>`` is the upper-cased package name.
+      See policy :policy:`CMP0144`.
+
+      .. versionadded:: 3.27
+
+   c. :envvar:`<PackageName>_ROOT` environment variable,
+      where ``<PackageName>`` is the case-preserved package name.
+
+   d. :envvar:`<PACKAGENAME>_ROOT` environment variable,
+      where ``<PACKAGENAME>`` is the upper-cased package name.
+      See policy :policy:`CMP0144`.
+
+      .. versionadded:: 3.27
+
+   The package root variables are maintained as a stack, so if called from
+   nested find modules or config packages, root paths from the parent's find
+   module or config package will be searched after paths from the current
+   module or package.  In other words, the search order would be
+   ``<CurrentPackage>_ROOT``, ``ENV{<CurrentPackage>_ROOT}``,
+   ``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc.
+   This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
+   the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
 
    * |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX|
 
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index de4cb88..b82088e 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -367,17 +367,37 @@
 steps.  If ``NO_DEFAULT_PATH`` is specified all ``NO_*`` options are
 enabled.
 
-1. .. versionadded:: 3.12
-    Search paths specified in the :variable:`<PackageName>_ROOT` CMake
-    variable and the :envvar:`<PackageName>_ROOT` environment variable,
-    where ``<PackageName>`` is the package to be found
-    (the case-preserved first argument to ``find_package``).
-    The package root variables are maintained as a stack so if
-    called from within a find module, root paths from the parent's find
-    module will also be searched after paths for the current package.
-    This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
-    the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
-    See policy :policy:`CMP0074`.
+1. Search prefixes unique to the current ``<PackageName>`` being found.
+   See policy :policy:`CMP0074`.
+
+   .. versionadded:: 3.12
+
+   Specifically, search prefixes specified by the following variables,
+   in order:
+
+   a. :variable:`<PackageName>_ROOT` CMake variable,
+      where ``<PackageName>`` is the case-preserved package name.
+
+   b. :variable:`<PACKAGENAME>_ROOT` CMake variable,
+      where ``<PACKAGENAME>`` is the upper-cased package name.
+      See policy :policy:`CMP0144`.
+
+      .. versionadded:: 3.27
+
+   c. :envvar:`<PackageName>_ROOT` environment variable,
+      where ``<PackageName>`` is the case-preserved package name.
+
+   d. :envvar:`<PACKAGENAME>_ROOT` environment variable,
+      where ``<PACKAGENAME>`` is the upper-cased package name.
+      See policy :policy:`CMP0144`.
+
+      .. versionadded:: 3.27
+
+   The package root variables are maintained as a stack so if
+   called from within a find module, root paths from the parent's find
+   module will also be searched after paths for the current package.
+   This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
+   the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
 
 2. Search paths specified in cmake-specific cache variables.  These
    are intended to be used on the command line with a :option:`-DVAR=VALUE <cmake -D>`.
diff --git a/Help/envvar/PackageName_ROOT.rst b/Help/envvar/PackageName_ROOT.rst
index fa8c385..6e9c744 100644
--- a/Help/envvar/PackageName_ROOT.rst
+++ b/Help/envvar/PackageName_ROOT.rst
@@ -17,3 +17,17 @@
 variable convention on those platforms).
 
 See also the :variable:`<PackageName>_ROOT` CMake variable.
+
+.. envvar:: <PACKAGENAME>_ROOT
+
+  .. versionadded:: 3.27
+
+  Calls to :command:`find_package(<PackageName>)` will also search in
+  prefixes specified by the upper-case ``<PACKAGENAME>_ROOT`` environment
+  variable.  See policy :policy:`CMP0144`.
+
+.. note::
+
+  Note that the ``<PackageName>_ROOT`` and ``<PACKAGENAME>_ROOT``
+  environment variables are distinct only on platforms that have
+  case-sensitive environments.
diff --git a/Help/guide/tutorial/A Basic Starting Point.rst b/Help/guide/tutorial/A Basic Starting Point.rst
index 3dac68a..37b0668 100644
--- a/Help/guide/tutorial/A Basic Starting Point.rst
+++ b/Help/guide/tutorial/A Basic Starting Point.rst
@@ -160,7 +160,7 @@
   :name: CMakeLists.txt-add_executable
   :language: cmake
   :start-after: # add the executable
-  :end-before: # TODO 9:
+  :end-before: # TODO 3:
 
 .. raw:: html
 
@@ -240,7 +240,7 @@
   :name: tutorial.cxx-cxx11
   :language: c++
   :start-after: // convert input to double
-  :end-before: // TODO 12:
+  :end-before: // TODO 6:
 
 .. raw:: html
 
@@ -265,7 +265,7 @@
   :name: CMakeLists.txt-CXX_STANDARD
   :language: cmake
   :start-after: # specify the C++ standard
-  :end-before: # TODO 7:
+  :end-before: # configure a header file
 
 .. raw:: html
 
@@ -375,7 +375,7 @@
   :name: CMakeLists.txt-configure_file
   :language: cmake
   :start-after: # to the source code
-  :end-before: # TODO 8:
+  :end-before: # TODO 2:
 
 .. raw:: html
 
@@ -420,7 +420,6 @@
   :caption: TODO 10: TutorialConfig.h.in
   :name: TutorialConfig.h.in
   :language: c++
-  :end-before: // TODO 13:
 
 .. raw:: html
 
diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst
index 6f9714e..08f3eea 100644
--- a/Help/guide/tutorial/Adding Generator Expressions.rst
+++ b/Help/guide/tutorial/Adding Generator Expressions.rst
@@ -299,7 +299,7 @@
   :name: CMakeLists.txt-target_compile_options-genex
   :language: cmake
   :start-after: set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-  :end-before: # should we use our own math functions
+  :end-before: # configure a header file to pass some of the CMake settings
 
 .. raw:: html
 
diff --git a/Help/guide/tutorial/Adding System Introspection.rst b/Help/guide/tutorial/Adding System Introspection.rst
index b69abd2..b314773 100644
--- a/Help/guide/tutorial/Adding System Introspection.rst
+++ b/Help/guide/tutorial/Adding System Introspection.rst
@@ -119,7 +119,7 @@
   :name: MathFunctions/CMakeLists.txt-target_compile_definitions
   :language: cmake
   :start-after: # add compile definitions
-  :end-before: # install libs
+  :end-before: # state
 
 .. raw:: html
 
@@ -136,7 +136,8 @@
   :caption: TODO 4: MathFunctions/mysqrt.cxx
   :name: MathFunctions/mysqrt.cxx-include-cmath
   :language: c++
-  :end-before: #include <iostream>
+  :start-after: #include "mysqrt.h"
+  :end-before: include <iostream>
 
 .. raw:: html
 
diff --git a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
index 4aef050..74b7496 100644
--- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
+++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
@@ -100,7 +100,7 @@
   :name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
   :language: cmake
   :start-after: # to find MathFunctions.h
-  :end-before: # TODO 3: Link to
+  :end-before: option
 
 .. raw:: html
 
@@ -119,7 +119,7 @@
   :name: CMakeLists.txt-remove-EXTRA_INCLUDES
   :language: cmake
   :start-after: # add the MathFunctions library
-  :end-before: # add the executable
+  :end-before: # TODO 2: Link to tutorial_compiler_flags
 
 .. raw:: html
 
diff --git a/Help/guide/tutorial/Adding a Custom Command and Generated File.rst b/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
index b1f9840..9e6311e 100644
--- a/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
+++ b/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
@@ -23,15 +23,25 @@
 then run it as part of the build process. A few commands are needed to
 accomplish this.
 
-First, at the top of ``MathFunctions/CMakeLists.txt``, the executable for
-``MakeTable`` is added as any other executable would be added.
+First, in the ``USE_MYMATH`` section of ``MathFunctions/CMakeLists.txt``,
+we add an executable for ``MakeTable``.
 
 .. literalinclude:: Step9/MathFunctions/CMakeLists.txt
   :caption: MathFunctions/CMakeLists.txt
   :name: MathFunctions/CMakeLists.txt-add_executable-MakeTable
   :language: cmake
   :start-after: # first we add the executable that generates the table
-  :end-before: # add the command to generate the source code
+  :end-before: target_link_libraries
+
+After creating the executable, we add the ``tutorial_compiler_flags`` to our
+executable using :command:`target_link_libraries`.
+
+.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
+  :caption: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-link-tutorial-compiler-flags
+  :language: cmake
+  :start-after: add_executable
+  :end-before: # add the command to generate
 
 Then we add a custom command that specifies how to produce ``Table.h``
 by running MakeTable.
@@ -41,7 +51,7 @@
   :name: MathFunctions/CMakeLists.txt-add_custom_command-Table.h
   :language: cmake
   :start-after: # add the command to generate the source code
-  :end-before: # add the main library
+  :end-before: # library that just does sqrt
 
 Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated
 file ``Table.h``. This is done by adding the generated ``Table.h`` to the list
@@ -51,8 +61,8 @@
   :caption: MathFunctions/CMakeLists.txt
   :name: MathFunctions/CMakeLists.txt-add_library-Table.h
   :language: cmake
-  :start-after: # add the main library
-  :end-before: # state that anybody linking
+  :start-after:   # library that just does sqrt
+  :end-before: # state that we depend on
 
 We also have to add the current binary directory to the list of include
 directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
@@ -62,7 +72,19 @@
   :name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h
   :language: cmake
   :start-after: # state that we depend on our bin
-  :end-before: # install libs
+  :end-before: target_link_libraries
+
+As the last thing in our ``USE_MYMATH`` section, we need to link the our
+flags onto ``SqrtLibrary`` and then link ``SqrtLibrary`` onto
+``MathFunctions``. This makes the resulting ``USE_MYMATH`` section look like
+the following:
+
+.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
+  :caption: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-full_USE_MYMATH-section
+  :language: cmake
+  :start-after: if (USE_MYMATH)
+  :end-before: endif()
 
 Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
 ``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table:
diff --git a/Help/guide/tutorial/Adding a Library.rst b/Help/guide/tutorial/Adding a Library.rst
index a56c327..2dd731f 100644
--- a/Help/guide/tutorial/Adding a Library.rst
+++ b/Help/guide/tutorial/Adding a Library.rst
@@ -51,11 +51,13 @@
 the compiler.
 
 For this tutorial we will put the library into a subdirectory called
-``MathFunctions``. This directory already contains a header file,
-``MathFunctions.h``, and a source file ``mysqrt.cxx``. We will not need to
-modify either of these files. The source file has one function called
+``MathFunctions``. This directory already contains the header files
+``MathFunctions.h`` and ``mysqrt.h``. Their respective source files
+``MathFunctions.cxx`` and ``mysqrt.cxx`` are also provided. We will not need
+to modify any of these files. ``mysqrt.cxx`` has one function called
 ``mysqrt`` that provides similar functionality to the compiler's ``sqrt``
-function.
+function. ``MathFunctions.cxx`` contains one function ``sqrt`` which serves
+to hide the implementation details of ``sqrt``.
 
 From the ``Help/guide/tutorial/Step2`` directory, start with ``TODO 1`` and
 complete through ``TODO 6``.
@@ -91,10 +93,10 @@
 
 In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create
 a library target called ``MathFunctions`` with :command:`add_library`. The
-source file for the library is passed as an argument to
+source files for the library are passed as an argument to
 :command:`add_library`. This looks like the following line:
 
-.. raw:: html
+.. raw:: html/
 
   <details><summary>TODO 1: Click to show/hide answer</summary>
 
@@ -171,36 +173,40 @@
 
   <details><summary>TODO 5: Click to show/hide answer</summary>
 
-.. code-block:: c++
-  :caption: TODO 5 : tutorial.cxx
-  :name: tutorial.cxx-include_MathFunctions.h
-
-  #include "MathFunctions.h"
+.. literalinclude:: Step3/tutorial.cxx
+  :caption: TODO 5: tutorial.cxx
+  :name: CMakeLists.txt-include-MathFunctions.h
+  :language: cmake
+  :start-after: #include <string>
+  :end-before: #include "TutorialConfig.h"
 
 .. raw:: html
 
   </details>
 
-Lastly, replace ``sqrt`` with our library function ``mysqrt``.
+Lastly, replace ``sqrt`` with our library function ``mathfunctions::mysqrt``.
 
 .. raw:: html
 
   <details><summary>TODO 6: Click to show/hide answer</summary>
 
-.. code-block:: c++
-  :caption: TODO 6 : tutorial.cxx
-  :name: tutorial.cxx-call_mysqrt
-
-  const double outputValue = mysqrt(inputValue);
+.. literalinclude:: Step3/tutorial.cxx
+  :caption: TODO 7: tutorial.cxx
+  :name: CMakeLists.txt-option
+  :language: cmake
+  :start-after:   const double inputValue = std::stod(argv[1]);
+  :end-before: std::cout
 
 .. raw:: html
 
   </details>
 
-Exercise 2 - Making Our Library Optional
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Exercise 2 - Adding an Option
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Now let us make the MathFunctions library optional. While for the tutorial
+Now let us add an option in the MathFunctions library to allow developers to
+select either the custom square root implementation or the built in standard
+implementation. While for the tutorial
 there really isn't any need to do so, for larger projects this is a common
 occurrence.
 
@@ -219,28 +225,26 @@
 -----------------
 
 * :command:`if`
-* :command:`list`
 * :command:`option`
-* :command:`cmakedefine <configure_file>`
+* :command:`target_compile_definitions`
 
 Files to Edit
 -------------
 
-* ``CMakeLists.txt``
-* ``tutorial.cxx``
-* ``TutorialConfig.h.in``
+* ``MathFunctions/CMakeLists.txt``
+* ``MathFunctions/MathFunctions.cxx``
 
 Getting Started
 ---------------
 
 Start with the resulting files from Exercise 1. Complete ``TODO 7`` through
-``TODO 13``.
+``TODO 9``.
 
 First create a variable ``USE_MYMATH`` using the :command:`option` command
-in the top-level ``CMakeLists.txt`` file. In that same file, use that option
-to determine whether to build and use the ``MathFunctions`` library.
+in ``MathFunctions/CMakeLists.txt``. In that same file, use that option
+to pass a compile definition to the ``MathFunctions`` library.
 
-Then, update ``tutorial.cxx`` and ``TutorialConfig.h.in`` to use
+Then, update ``MathFunctions.cxx`` to redirect compilation based on
 ``USE_MYMATH``.
 
 Build and Run
@@ -279,7 +283,7 @@
 Solution
 --------
 
-The first step is to add an option to the top-level ``CMakeLists.txt`` file.
+The first step is to add an option to ``MathFunctions/CMakeLists.txt``.
 This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and
 :manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be
 changed by the user.
@@ -288,172 +292,95 @@
 
   <details><summary>TODO 7: Click to show/hide answer</summary>
 
-.. literalinclude:: Step3/CMakeLists.txt
-  :caption: TODO 7: CMakeLists.txt
-  :name: CMakeLists.txt-option
+.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
+  :caption: TODO 7: MathFunctions/CMakeLists.txt
+  :name: CMakeLists.txt-option-library-level
   :language: cmake
   :start-after: # should we use our own math functions
-  :end-before: # configure a header file to pass some of the CMake settings
+  :end-before: if (USE_MYMATH)
 
 .. raw:: html
 
   </details>
 
-Next, make building and linking the ``MathFunctions`` library
-conditional.
+Next, make building and linking our library with ``mysqrt`` function
+conditional using this new option.
 
-Start by creating a :command:`list` of the optional library targets for our
-project. At the moment, it is just ``MathFunctions``. Let's name our list
-``EXTRA_LIBS``.
-
-Similarly, we need to make a :command:`list` for the optional includes which
-we will call ``EXTRA_INCLUDES``. In this list, we will ``APPEND`` the path of
-the header file needed for our library.
-
-Next, create an :command:`if` statement which checks the value of
+Create an :command:`if` statement which checks the value of
 ``USE_MYMATH``. Inside the :command:`if` block, put the
-:command:`add_subdirectory` command from Exercise 1 with the additional
-:command:`list` commands.
-
-When ``USE_MYMATH`` is ``ON``, the lists will be generated and will be added to
-our project. When ``USE_MYMATH`` is ``OFF``, the lists stay empty. With this
-strategy, we allow users to toggle ``USE_MYMATH`` to manipulate what library is
-used in the build.
-
-The top-level CMakeLists.txt file will now look like the following:
+:command:`target_compile_definitions` command with the compile
+definition ``USE_MYMATH``.
 
 .. raw:: html
 
   <details><summary>TODO 8: Click to show/hide answer</summary>
 
-.. literalinclude:: Step3/CMakeLists.txt
-  :caption: TODO 8: CMakeLists.txt
+.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
+  :caption: TODO 8: MathFunctions/CMakeLists.txt
   :name: CMakeLists.txt-USE_MYMATH
   :language: cmake
-  :start-after: # add the MathFunctions library
-  :end-before: # add the executable
+  :start-after: USE_MYMATH "Use tutorial provided math implementation" ON)
 
 .. raw:: html
 
   </details>
 
-Now that we have these two lists, we need to update
-:command:`target_link_libraries` and :command:`target_include_directories` to
-use them. Changing them is fairly straightforward.
-
-For :command:`target_link_libraries`, we replace the written out
-library names with ``EXTRA_LIBS``. This looks like the following:
+The corresponding changes to the source code are fairly straightforward.
+In ``MathFunctions.cxx``, we make ``USE_MYMATH`` control which square root
+function is used:
 
 .. raw:: html
 
   <details><summary>TODO 9: Click to show/hide answer</summary>
 
-.. literalinclude:: Step3/CMakeLists.txt
-  :caption: TODO 9: CMakeLists.txt
-  :name: CMakeLists.txt-target_link_libraries-EXTRA_LIBS
-  :language: cmake
-  :start-after: add_executable(Tutorial tutorial.cxx)
-  :end-before: # TODO 3
+.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
+  :caption: TODO 9: MathFunctions/MathFunctions.cxx
+  :name: MathFunctions-USE_MYMATH-if
+  :language: c++
+  :start-after: which square root function should we use?
+  :end-before: }
 
 .. raw:: html
 
   </details>
 
-Then, we do the same thing with :command:`target_include_directories` and
-``EXTRA_INCLUDES``.
+Next, we need to include ``mysqrt.h`` if ``USE_MYMATH`` is defined.
 
 .. raw:: html
 
   <details><summary>TODO 10: Click to show/hide answer</summary>
 
-.. literalinclude:: Step3/CMakeLists.txt
-  :caption: TODO 10 : CMakeLists.txt
-  :name: CMakeLists.txt-target_link_libraries-EXTRA_INCLUDES
-  :language: cmake
-  :start-after: # so that we will find TutorialConfig.h
+.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
+  :caption: TODO 10: MathFunctions/MathFunctions.cxx
+  :name: MathFunctions-USE_MYMATH-if-include
+  :language: c++
+  :start-after: include <cmath>
+  :end-before: namespace mathfunctions
 
 .. raw:: html
 
   </details>
 
-Note that this is a classic approach when dealing with many components. We
-will cover the modern approach in the Step 3 of the tutorial.
-
-The corresponding changes to the source code are fairly straightforward.
-First, in ``tutorial.cxx``, we include the ``MathFunctions.h`` header if
-``USE_MYMATH`` is defined.
+Finally, we need to include ``cmath`` now that we are using ``std::sqrt``.
 
 .. raw:: html
 
   <details><summary>TODO 11: Click to show/hide answer</summary>
 
-.. literalinclude:: Step3/tutorial.cxx
-  :caption: TODO 11 : tutorial.cxx
-  :name: tutorial.cxx-ifdef-include
-  :language: c++
-  :start-after: // should we include the MathFunctions header
-  :end-before: int main
+.. code-block:: c++
+  :caption: TODO 11 : MathFunctions/MathFunctions.cxx
+  :name: tutorial.cxx-include_cmath
+
+  #include <cmath>
 
 .. raw:: html
 
   </details>
 
-Then, in the same file, we make ``USE_MYMATH`` control which square root
-function is used:
+When ``USE_MYMATH`` is ``ON``, the compile definition ``USE_MYMATH`` will
+be set. We can then use this compile definition to enable or disable
+sections of our source code. With this strategy, we allow users to
+toggle ``USE_MYMATH`` to manipulate what library is used in the build.
 
-.. raw:: html
-
-  <details><summary>TODO 12: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/tutorial.cxx
-  :caption: TODO 12 : tutorial.cxx
-  :name: tutorial.cxx-ifdef-const
-  :language: c++
-  :start-after: // which square root function should we use?
-  :end-before: std::cout << "The square root of
-
-.. raw:: html
-
-  </details>
-
-Since the source code now requires ``USE_MYMATH`` we can add it to
-``TutorialConfig.h.in`` with the following line:
-
-.. raw:: html
-
-  <details><summary>TODO 13: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/TutorialConfig.h.in
-  :caption: TODO 13 : TutorialConfig.h.in
-  :name: TutorialConfig.h.in-cmakedefine
-  :language: c++
-  :lines: 4
-
-.. raw:: html
-
-  </details>
-
-With these changes, our library is now completely optional to whoever is
-building and using it.
-
-Bonus Question
---------------
-
-Why is it important that we configure ``TutorialConfig.h.in``
-after the option for ``USE_MYMATH``? What would happen if we inverted the two?
-
-Answer
-------
-
-.. raw:: html
-
-  <details><summary>Click to show/hide answer</summary>
-
-We configure after because ``TutorialConfig.h.in`` uses the value of
-``USE_MYMATH``. If we configure the file before
-calling :command:`option`, we won't be using the expected value of
-``USE_MYMATH``.
-
-.. raw:: html
-
-  </details>
+With these changes, the ``mysqrt`` function is now completely optional to
+whoever is building and using the ``MathFunctions`` library.
diff --git a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx
index 0145300..c0991b9 100644
--- a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx
@@ -10,6 +10,7 @@
 namespace mathfunctions {
 double sqrt(double x)
 {
+// which square root function should we use?
 #ifdef USE_MYMATH
   return detail::mysqrt(x);
 #else
diff --git a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
index 7befe1d..504e42f 100644
--- a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
+++ b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
@@ -10,49 +10,22 @@
 top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows
 users to optionally select if the value should be ``ON`` or ``OFF``.
 
-Next we are going to refactor ``MathFunctions`` to become a real library that
-encapsulates using ``mysqrt`` or ``sqrt``, instead of requiring the calling
-code to do this logic. This will also mean that ``USE_MYMATH`` will not control
-building ``MathFunctions``, but instead will control the behavior of this
-library.
-
-The first step is to update the starting section of the top-level
-``CMakeLists.txt`` to look like:
-
 .. literalinclude:: Step11/CMakeLists.txt
   :caption: CMakeLists.txt
   :name: CMakeLists.txt-option-BUILD_SHARED_LIBS
   :language: cmake
-  :end-before: # add the binary tree
+  :start-after: set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
+  :end-before: # configure a header file to pass the version number only
 
-Now that we have made ``MathFunctions`` always be used, we will need to update
-the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to
-create a SqrtLibrary that will conditionally be built and installed when
-``USE_MYMATH`` is enabled. Now, since this is a tutorial, we are going to
-explicitly require that SqrtLibrary is built statically.
+Next, we need to specify output directories for our static and shared
+libraries.
 
-The end result is that ``MathFunctions/CMakeLists.txt`` should look like:
-
-.. literalinclude:: Step11/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-add_library-STATIC
+.. literalinclude:: Step11/CMakeLists.txt
+  :caption: CMakeLists.txt
+  :name: CMakeLists.txt-cmake-output-directories
   :language: cmake
-  :lines: 1-36,42-
-
-Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and
-``detail`` namespaces:
-
-.. literalinclude:: Step11/MathFunctions/mysqrt.cxx
-  :caption: MathFunctions/mysqrt.cxx
-  :name: MathFunctions/mysqrt.cxx-namespace
-  :language: c++
-
-We also need to make some changes in ``tutorial.cxx``, so that it no longer
-uses ``USE_MYMATH``:
-
-#. Always include ``MathFunctions.h``
-#. Always use ``mathfunctions::sqrt``
-#. Don't include ``cmath``
+  :start-after: # we don't need to tinker with the path to run the executable
+  :end-before: # configure a header file to pass the version number only
 
 Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:
 
diff --git a/Help/guide/tutorial/Step10/CMakeLists.txt b/Help/guide/tutorial/Step10/CMakeLists.txt
index 5c661aa..2dd6db5 100644
--- a/Help/guide/tutorial/Step10/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/CMakeLists.txt
@@ -16,22 +16,15 @@
   "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
 )
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
-# configure a header file to pass some of the CMake settings
-# to the source code
+# configure a header file to pass the version number only
 configure_file(TutorialConfig.h.in TutorialConfig.h)
 
 # add the MathFunctions library
-if(USE_MYMATH)
-  add_subdirectory(MathFunctions)
-  list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
 
 # add the executable
 add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
 
 # add the binary tree to the search path for include files
 # so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
index fa73321..6f6c430 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
@@ -1,32 +1,51 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-
-# add the command to generate the source code
-add_custom_command(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  DEPENDS MakeTable
-  )
-
-# add the main library
-add_library(MathFunctions
-            mysqrt.cxx
-            ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-            )
+# add the library that runs
+add_library(MathFunctions MathFunctions.cxx)
 
 # state that anybody linking to us needs to include the current source dir
 # to find MathFunctions.h, while we don't.
-# state that we depend on our binary dir to find Table.h
 target_include_directories(MathFunctions
-          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-          PRIVATE   ${CMAKE_CURRENT_BINARY_DIR}
-          )
+                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+                           )
 
-# link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if(USE_MYMATH)
+
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+
+  # first we add the executable that generates the table
+  add_executable(MakeTable MakeTable.cxx)
+  target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
+
+  # add the command to generate the source code
+  add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+    COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+    DEPENDS MakeTable
+    )
+
+  # library that just does sqrt
+  add_library(SqrtLibrary STATIC
+              mysqrt.cxx
+              ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+              )
+
+  # state that we depend on our binary dir to find Table.h
+  target_include_directories(SqrtLibrary PRIVATE
+                             ${CMAKE_CURRENT_BINARY_DIR}
+                             )
+
+  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
+endif()
+
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
 
 # install libs
 set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
 install(TARGETS ${installable_libs} DESTINATION lib)
 # install include headers
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx
index 0145300..c0991b9 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx
@@ -10,6 +10,7 @@
 namespace mathfunctions {
 double sqrt(double x)
 {
+// which square root function should we use?
 #ifdef USE_MYMATH
   return detail::mysqrt(x);
 #else
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
index cd36bcc..1e916e1 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
@@ -1 +1,3 @@
-double mysqrt(double x);
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
index 7d80ee9..8153f18 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
@@ -5,6 +5,8 @@
 // include the generated table
 #include "Table.h"
 
+namespace mathfunctions {
+namespace detail {
 // a hack square root calculation using simple operations
 double mysqrt(double x)
 {
@@ -31,3 +33,5 @@
 
   return result;
 }
+}
+}
diff --git a/Help/guide/tutorial/Step10/TutorialConfig.h.in b/Help/guide/tutorial/Step10/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step10/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step10/TutorialConfig.h.in
@@ -1,4 +1,3 @@
 // the configured options and settings for Tutorial
 #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
 #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step10/tutorial.cxx b/Help/guide/tutorial/Step10/tutorial.cxx
index b3c6a4f..37a0333 100644
--- a/Help/guide/tutorial/Step10/tutorial.cxx
+++ b/Help/guide/tutorial/Step10/tutorial.cxx
@@ -1,15 +1,11 @@
 // A simple program that computes the square root of a number
-#include <cmath>
 #include <iostream>
+#include <sstream>
 #include <string>
 
+#include "MathFunctions.h"
 #include "TutorialConfig.h"
 
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-#  include "MathFunctions.h"
-#endif
-
 int main(int argc, char* argv[])
 {
   if (argc < 2) {
@@ -23,12 +19,7 @@
   // convert input to double
   const double inputValue = std::stod(argv[1]);
 
-  // which square root function should we use?
-#ifdef USE_MYMATH
-  const double outputValue = mysqrt(inputValue);
-#else
-  const double outputValue = sqrt(inputValue);
-#endif
+  const double outputValue = mathfunctions::sqrt(inputValue);
 
   std::cout << "The square root of " << inputValue << " is " << outputValue
             << std::endl;
diff --git a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx
index 0145300..c0991b9 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx
@@ -10,6 +10,7 @@
 namespace mathfunctions {
 double sqrt(double x)
 {
+// which square root function should we use?
 #ifdef USE_MYMATH
   return detail::mysqrt(x);
 #else
diff --git a/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
index 0145300..c0991b9 100644
--- a/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
@@ -10,6 +10,7 @@
 namespace mathfunctions {
 double sqrt(double x)
 {
+// which square root function should we use?
 #ifdef USE_MYMATH
   return detail::mysqrt(x);
 #else
diff --git a/Help/guide/tutorial/Step2/CMakeLists.txt b/Help/guide/tutorial/Step2/CMakeLists.txt
index 2b96128..0a06ed7 100644
--- a/Help/guide/tutorial/Step2/CMakeLists.txt
+++ b/Help/guide/tutorial/Step2/CMakeLists.txt
@@ -7,36 +7,20 @@
 set(CMAKE_CXX_STANDARD 11)
 set(CMAKE_CXX_STANDARD_REQUIRED True)
 
-# TODO 7: Create a variable USE_MYMATH using option and set default to ON
-
 # configure a header file to pass some of the CMake settings
 # to the source code
 configure_file(TutorialConfig.h.in TutorialConfig.h)
 
-# TODO 8: Use list() and APPEND to create a list of optional libraries
-# called  EXTRA_LIBS and a list of optional include directories called
-# EXTRA_INCLUDES. Add the MathFunctions library and source directory to
-# the appropriate lists.
-#
-# Only call add_subdirectory and only add MathFunctions specific values
-# to EXTRA_LIBS and EXTRA_INCLUDES if USE_MYMATH is true.
-
 # TODO 2: Use add_subdirectory() to add MathFunctions to this project
 
 # add the executable
 add_executable(Tutorial tutorial.cxx)
 
-# TODO 9: Use EXTRA_LIBS instead of the MathFunctions specific values
-# in target_link_libraries.
-
 # TODO 3: Use target_link_libraries to link the library to our executable
 
 # TODO 4: Add MathFunctions to Tutorial's target_include_directories()
 # Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder!
 
-# TODO 10: Use EXTRA_INCLUDES instead of the MathFunctions specific values
-# in target_include_directories.
-
 # add the binary tree to the search path for include files
 # so that we will find TutorialConfig.h
 target_include_directories(Tutorial PUBLIC
diff --git a/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
index b7779b7..c468b0e 100644
--- a/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
@@ -1,2 +1,7 @@
 # TODO 1: Add a library called MathFunctions
 # Hint: You will need the add_library command
+
+# TODO 7: Create a variable USE_MYMATH using option and set default to ON
+
+# TODO 8: If USE_MYMATH is ON, use target_compile_definitions to pass
+# USE_MYMATH as a precompiled definition to our source files
diff --git a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..781d0ec
--- /dev/null
+++ b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,15 @@
+#include "MathFunctions.h"
+
+// TODO 11: include cmath
+
+// TODO 10: Wrap the mysqrt include in a precompiled ifdef based on USE_MYMATH
+#include "mysqrt.h"
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+  // TODO 9: If USE_MYMATH is defined, use detail::mysqrt.
+  // Otherwise, use std::sqrt.
+  return detail::mysqrt(x);
+}
+}
diff --git a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx
index 1e4d97a..ba0ac64 100644
--- a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx
@@ -1,5 +1,9 @@
+#include "mysqrt.h"
+
 #include <iostream>
 
+namespace mathfunctions {
+namespace detail {
 // a hack square root calculation using simple operations
 double mysqrt(double x)
 {
@@ -20,3 +24,5 @@
   }
   return result;
 }
+}
+}
diff --git a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step2/TutorialConfig.h.in b/Help/guide/tutorial/Step2/TutorialConfig.h.in
index 6c09e1a..7e4d7fa 100644
--- a/Help/guide/tutorial/Step2/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step2/TutorialConfig.h.in
@@ -1,5 +1,3 @@
 // the configured options and settings for Tutorial
 #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
 #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-
-// TODO 13: use cmakedefine to define USE_MYMATH
diff --git a/Help/guide/tutorial/Step2/tutorial.cxx b/Help/guide/tutorial/Step2/tutorial.cxx
index 87f5e0f..7a2a595 100644
--- a/Help/guide/tutorial/Step2/tutorial.cxx
+++ b/Help/guide/tutorial/Step2/tutorial.cxx
@@ -3,11 +3,8 @@
 #include <iostream>
 #include <string>
 
-#include "TutorialConfig.h"
-
-// TODO 11: Only include MathFunctions if USE_MYMATH is defined
-
 // TODO 5: Include MathFunctions.h
+#include "TutorialConfig.h"
 
 int main(int argc, char* argv[])
 {
@@ -22,9 +19,7 @@
   // convert input to double
   const double inputValue = std::stod(argv[1]);
 
-  // TODO 12: Use mysqrt if USE_MYMATH is defined and sqrt otherwise
-
-  // TODO 6: Replace sqrt with mysqrt
+  // TODO 6: Replace sqrt with mathfunctions::sqrt
 
   // calculate square root
   const double outputValue = sqrt(inputValue);
diff --git a/Help/guide/tutorial/Step3/CMakeLists.txt b/Help/guide/tutorial/Step3/CMakeLists.txt
index 007770a..f051826 100644
--- a/Help/guide/tutorial/Step3/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/CMakeLists.txt
@@ -7,9 +7,6 @@
 set(CMAKE_CXX_STANDARD 11)
 set(CMAKE_CXX_STANDARD_REQUIRED True)
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
 # configure a header file to pass some of the CMake settings
 # to the source code
 configure_file(TutorialConfig.h.in TutorialConfig.h)
@@ -17,16 +14,13 @@
 # TODO 2: Remove EXTRA_INCLUDES list
 
 # add the MathFunctions library
-if(USE_MYMATH)
-  add_subdirectory(MathFunctions)
-  list(APPEND EXTRA_LIBS MathFunctions)
-  list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
-endif()
+add_subdirectory(MathFunctions)
+list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
 
 # add the executable
 add_executable(Tutorial tutorial.cxx)
 
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+target_link_libraries(Tutorial PUBLIC MathFunctions)
 
 # TODO 3: Remove use of EXTRA_INCLUDES
 
diff --git a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
index 7bf05e0..90d6c24 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
@@ -1,5 +1,11 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
 
 # TODO 1: State that anybody linking to MathFunctions needs to include the
 # current source directory, while MathFunctions itself doesn't.
 # Hint: Use target_include_directories with the INTERFACE keyword
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+endif()
diff --git a/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+#  include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+  return detail::mysqrt(x);
+#else
+  return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx
index abe767d..ba0ac64 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx
@@ -1,7 +1,9 @@
+#include "mysqrt.h"
+
 #include <iostream>
 
-#include "MathFunctions.h"
-
+namespace mathfunctions {
+namespace detail {
 // a hack square root calculation using simple operations
 double mysqrt(double x)
 {
@@ -22,3 +24,5 @@
   }
   return result;
 }
+}
+}
diff --git a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step3/TutorialConfig.h.in b/Help/guide/tutorial/Step3/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step3/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step3/TutorialConfig.h.in
@@ -1,4 +1,3 @@
 // the configured options and settings for Tutorial
 #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
 #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step3/tutorial.cxx b/Help/guide/tutorial/Step3/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step3/tutorial.cxx
+++ b/Help/guide/tutorial/Step3/tutorial.cxx
@@ -3,13 +3,9 @@
 #include <iostream>
 #include <string>
 
+#include "MathFunctions.h"
 #include "TutorialConfig.h"
 
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-#  include "MathFunctions.h"
-#endif
-
 int main(int argc, char* argv[])
 {
   if (argc < 2) {
@@ -23,12 +19,7 @@
   // convert input to double
   const double inputValue = std::stod(argv[1]);
 
-  // which square root function should we use?
-#ifdef USE_MYMATH
-  const double outputValue = mysqrt(inputValue);
-#else
-  const double outputValue = sqrt(inputValue);
-#endif
+  const double outputValue = mathfunctions::sqrt(inputValue);
 
   std::cout << "The square root of " << inputValue << " is " << outputValue
             << std::endl;
diff --git a/Help/guide/tutorial/Step4/CMakeLists.txt b/Help/guide/tutorial/Step4/CMakeLists.txt
index fa4aab2..dcda135 100644
--- a/Help/guide/tutorial/Step4/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/CMakeLists.txt
@@ -31,25 +31,19 @@
 # build-tree
 # Hint: Use BUILD_INTERFACE
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
 # configure a header file to pass some of the CMake settings
 # to the source code
 configure_file(TutorialConfig.h.in TutorialConfig.h)
 
 # add the MathFunctions library
-if(USE_MYMATH)
-  add_subdirectory(MathFunctions)
-  list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
 
 # add the executable
 add_executable(Tutorial tutorial.cxx)
 
 # TODO 2: Link to tutorial_compiler_flags
 
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+target_link_libraries(Tutorial PUBLIC MathFunctions)
 
 # add the binary tree to the search path for include files
 # so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
index 5f7369c..cc71d86 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
@@ -1,9 +1,15 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
 
 # state that anybody linking to us needs to include the current source dir
 # to find MathFunctions.h, while we don't.
 target_include_directories(MathFunctions
-          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-          )
+                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+                           )
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+endif()
 
 # TODO 3: Link to tutorial_compiler_flags
diff --git a/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+#  include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+  return detail::mysqrt(x);
+#else
+  return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx
index abe767d..ba0ac64 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx
@@ -1,7 +1,9 @@
+#include "mysqrt.h"
+
 #include <iostream>
 
-#include "MathFunctions.h"
-
+namespace mathfunctions {
+namespace detail {
 // a hack square root calculation using simple operations
 double mysqrt(double x)
 {
@@ -22,3 +24,5 @@
   }
   return result;
 }
+}
+}
diff --git a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step4/TutorialConfig.h.in b/Help/guide/tutorial/Step4/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step4/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step4/TutorialConfig.h.in
@@ -1,4 +1,3 @@
 // the configured options and settings for Tutorial
 #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
 #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step4/tutorial.cxx b/Help/guide/tutorial/Step4/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step4/tutorial.cxx
+++ b/Help/guide/tutorial/Step4/tutorial.cxx
@@ -3,13 +3,9 @@
 #include <iostream>
 #include <string>
 
+#include "MathFunctions.h"
 #include "TutorialConfig.h"
 
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-#  include "MathFunctions.h"
-#endif
-
 int main(int argc, char* argv[])
 {
   if (argc < 2) {
@@ -23,12 +19,7 @@
   // convert input to double
   const double inputValue = std::stod(argv[1]);
 
-  // which square root function should we use?
-#ifdef USE_MYMATH
-  const double outputValue = mysqrt(inputValue);
-#else
-  const double outputValue = sqrt(inputValue);
-#endif
+  const double outputValue = mathfunctions::sqrt(inputValue);
 
   std::cout << "The square root of " << inputValue << " is " << outputValue
             << std::endl;
diff --git a/Help/guide/tutorial/Step5/CMakeLists.txt b/Help/guide/tutorial/Step5/CMakeLists.txt
index 279ddf9..ad814f6 100644
--- a/Help/guide/tutorial/Step5/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/CMakeLists.txt
@@ -16,22 +16,17 @@
   "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
 )
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
 # configure a header file to pass some of the CMake settings
 # to the source code
 configure_file(TutorialConfig.h.in TutorialConfig.h)
 
 # add the MathFunctions library
-if(USE_MYMATH)
-  add_subdirectory(MathFunctions)
-  list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
 
 # add the executable
 add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
 
 # add the binary tree to the search path for include files
 # so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
index 6cd88d7..000a786 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
@@ -1,13 +1,19 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
 
 # state that anybody linking to us needs to include the current source dir
 # to find MathFunctions.h, while we don't.
 target_include_directories(MathFunctions
-          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-          )
+                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+                           )
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+endif()
 
 # link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
 
 # TODO 1: Create a variable called installable_libs that is a list of all
 # libraries we want to install (e.g. MathFunctions and tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+#  include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+  return detail::mysqrt(x);
+#else
+  return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx
index abe767d..ba0ac64 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx
@@ -1,7 +1,9 @@
+#include "mysqrt.h"
+
 #include <iostream>
 
-#include "MathFunctions.h"
-
+namespace mathfunctions {
+namespace detail {
 // a hack square root calculation using simple operations
 double mysqrt(double x)
 {
@@ -22,3 +24,5 @@
   }
   return result;
 }
+}
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step5/TutorialConfig.h.in b/Help/guide/tutorial/Step5/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step5/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step5/TutorialConfig.h.in
@@ -1,4 +1,3 @@
 // the configured options and settings for Tutorial
 #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
 #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step5/tutorial.cxx b/Help/guide/tutorial/Step5/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step5/tutorial.cxx
+++ b/Help/guide/tutorial/Step5/tutorial.cxx
@@ -3,13 +3,9 @@
 #include <iostream>
 #include <string>
 
+#include "MathFunctions.h"
 #include "TutorialConfig.h"
 
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-#  include "MathFunctions.h"
-#endif
-
 int main(int argc, char* argv[])
 {
   if (argc < 2) {
@@ -23,12 +19,7 @@
   // convert input to double
   const double inputValue = std::stod(argv[1]);
 
-  // which square root function should we use?
-#ifdef USE_MYMATH
-  const double outputValue = mysqrt(inputValue);
-#else
-  const double outputValue = sqrt(inputValue);
-#endif
+  const double outputValue = mathfunctions::sqrt(inputValue);
 
   std::cout << "The square root of " << inputValue << " is " << outputValue
             << std::endl;
diff --git a/Help/guide/tutorial/Step6/CMakeLists.txt b/Help/guide/tutorial/Step6/CMakeLists.txt
index c11e307..a86d60a 100644
--- a/Help/guide/tutorial/Step6/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/CMakeLists.txt
@@ -16,22 +16,17 @@
   "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
 )
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
 # configure a header file to pass some of the CMake settings
 # to the source code
 configure_file(TutorialConfig.h.in TutorialConfig.h)
 
 # add the MathFunctions library
-if(USE_MYMATH)
-  add_subdirectory(MathFunctions)
-  list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
 
 # add the executable
 add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
 
 # add the binary tree to the search path for include files
 # so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
index b4724c4..623cb74 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -1,13 +1,19 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
 
 # state that anybody linking to us needs to include the current source dir
 # to find MathFunctions.h, while we don't.
 target_include_directories(MathFunctions
-          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-          )
+                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+                           )
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+endif()
 
 # link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
 
 # install libs
 set(installable_libs MathFunctions tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+#  include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+  return detail::mysqrt(x);
+#else
+  return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
index abe767d..ba0ac64 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
@@ -1,7 +1,9 @@
+#include "mysqrt.h"
+
 #include <iostream>
 
-#include "MathFunctions.h"
-
+namespace mathfunctions {
+namespace detail {
 // a hack square root calculation using simple operations
 double mysqrt(double x)
 {
@@ -22,3 +24,5 @@
   }
   return result;
 }
+}
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step6/TutorialConfig.h.in b/Help/guide/tutorial/Step6/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step6/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step6/TutorialConfig.h.in
@@ -1,4 +1,3 @@
 // the configured options and settings for Tutorial
 #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
 #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step6/tutorial.cxx b/Help/guide/tutorial/Step6/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step6/tutorial.cxx
+++ b/Help/guide/tutorial/Step6/tutorial.cxx
@@ -3,13 +3,9 @@
 #include <iostream>
 #include <string>
 
+#include "MathFunctions.h"
 #include "TutorialConfig.h"
 
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-#  include "MathFunctions.h"
-#endif
-
 int main(int argc, char* argv[])
 {
   if (argc < 2) {
@@ -23,12 +19,7 @@
   // convert input to double
   const double inputValue = std::stod(argv[1]);
 
-  // which square root function should we use?
-#ifdef USE_MYMATH
-  const double outputValue = mysqrt(inputValue);
-#else
-  const double outputValue = sqrt(inputValue);
-#endif
+  const double outputValue = mathfunctions::sqrt(inputValue);
 
   std::cout << "The square root of " << inputValue << " is " << outputValue
             << std::endl;
diff --git a/Help/guide/tutorial/Step7/CMakeLists.txt b/Help/guide/tutorial/Step7/CMakeLists.txt
index d26a90c..97ec6aa 100644
--- a/Help/guide/tutorial/Step7/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/CMakeLists.txt
@@ -16,22 +16,17 @@
   "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
 )
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
 # configure a header file to pass some of the CMake settings
 # to the source code
 configure_file(TutorialConfig.h.in TutorialConfig.h)
 
 # add the MathFunctions library
-if(USE_MYMATH)
-  add_subdirectory(MathFunctions)
-  list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
 
 # add the executable
 add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
 
 # add the binary tree to the search path for include files
 # so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
index e5bdc4d..c0d1e72 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
@@ -1,33 +1,39 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
 
 # state that anybody linking to us needs to include the current source dir
 # to find MathFunctions.h, while we don't.
 target_include_directories(MathFunctions
-          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-          )
+                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+                           )
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+
+  # TODO 1: Include CheckCXXSourceCompiles
+
+  # TODO 2: Use check_cxx_source_compiles with simple C++ code to verify
+  # availability of:
+  # * std::log
+  # * std::exp
+  # Store the results in HAVE_LOG and HAVE_EXP respectively.
+
+  # Hint: Sample C++ code which uses log:
+  # #include <cmath>
+  # int main() {
+  #   std::log(1.0);
+  #   return 0;
+  # }
+
+  # TODO 3: Conditionally on HAVE_LOG and HAVE_EXP, add private compile
+  # definitions "HAVE_LOG" and "HAVE_EXP" to the MathFunctions target.
+
+  # Hint: Use target_compile_definitions()
+endif()
 
 # link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
-
-# TODO 1: Include CheckCXXSourceCompiles
-
-# TODO 2: Use check_cxx_source_compiles with simple C++ code to verify
-# availability of:
-# * std::log
-# * std::exp
-# Store the results in HAVE_LOG and HAVE_EXP respectively.
-
-# Hint: Sample C++ code which uses log:
-# #include <cmath>
-# int main() {
-#   std::log(1.0);
-#   return 0;
-# }
-
-# TODO 3: Conditionally on HAVE_LOG and HAVE_EXP, add private compile
-# definitions "HAVE_LOG" and "HAVE_EXP" to the MathFunctions target.
-
-#Hint: Use target_compile_definitions()
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
 
 # install libs
 set(installable_libs MathFunctions tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+#  include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+  return detail::mysqrt(x);
+#else
+  return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
index 3d2492a..9963cff 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
@@ -1,8 +1,9 @@
+#include "mysqrt.h"
+
 #include <iostream>
 
-// TODO 4: include cmath
-#include "MathFunctions.h"
-
+namespace mathfunctions {
+namespace detail {
 // a hack square root calculation using simple operations
 double mysqrt(double x)
 {
@@ -32,3 +33,5 @@
 
   return result;
 }
+}
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step7/TutorialConfig.h.in b/Help/guide/tutorial/Step7/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step7/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step7/TutorialConfig.h.in
@@ -1,4 +1,3 @@
 // the configured options and settings for Tutorial
 #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
 #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step7/tutorial.cxx b/Help/guide/tutorial/Step7/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step7/tutorial.cxx
+++ b/Help/guide/tutorial/Step7/tutorial.cxx
@@ -3,13 +3,9 @@
 #include <iostream>
 #include <string>
 
+#include "MathFunctions.h"
 #include "TutorialConfig.h"
 
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-#  include "MathFunctions.h"
-#endif
-
 int main(int argc, char* argv[])
 {
   if (argc < 2) {
@@ -23,12 +19,7 @@
   // convert input to double
   const double inputValue = std::stod(argv[1]);
 
-  // which square root function should we use?
-#ifdef USE_MYMATH
-  const double outputValue = mysqrt(inputValue);
-#else
-  const double outputValue = sqrt(inputValue);
-#endif
+  const double outputValue = mathfunctions::sqrt(inputValue);
 
   std::cout << "The square root of " << inputValue << " is " << outputValue
             << std::endl;
diff --git a/Help/guide/tutorial/Step8/CMakeLists.txt b/Help/guide/tutorial/Step8/CMakeLists.txt
index cb87281..97ec6aa 100644
--- a/Help/guide/tutorial/Step8/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/CMakeLists.txt
@@ -16,23 +16,17 @@
   "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
 )
 
-
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
 # configure a header file to pass some of the CMake settings
 # to the source code
 configure_file(TutorialConfig.h.in TutorialConfig.h)
 
 # add the MathFunctions library
-if(USE_MYMATH)
-  add_subdirectory(MathFunctions)
-  list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
 
 # add the executable
 add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
 
 # add the binary tree to the search path for include files
 # so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
index f81b563..861014d 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
@@ -1,36 +1,43 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+
+  # does this system provide the log and exp functions?
+  include(CheckCXXSourceCompiles)
+  check_cxx_source_compiles("
+    #include <cmath>
+    int main() {
+      std::log(1.0);
+      return 0;
+    }
+  " HAVE_LOG)
+  check_cxx_source_compiles("
+    #include <cmath>
+    int main() {
+      std::exp(1.0);
+      return 0;
+    }
+  " HAVE_EXP)
+
+  # add compile definitions
+  if(HAVE_LOG AND HAVE_EXP)
+    target_compile_definitions(MathFunctions
+                               PRIVATE "HAVE_LOG" "HAVE_EXP"
+                               )
+  endif()
+endif()
 
 # state that anybody linking to us needs to include the current source dir
 # to find MathFunctions.h, while we don't.
 target_include_directories(MathFunctions
-          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-          )
+                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+                           )
 
 # link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
-
-# does this system provide the log and exp functions?
-include(CheckCXXSourceCompiles)
-check_cxx_source_compiles("
-  #include <cmath>
-  int main() {
-    std::log(1.0);
-    return 0;
-  }
-" HAVE_LOG)
-check_cxx_source_compiles("
-  #include <cmath>
-  int main() {
-    std::exp(1.0);
-    return 0;
-  }
-" HAVE_EXP)
-
-# add compile definitions
-if(HAVE_LOG AND HAVE_EXP)
-  target_compile_definitions(MathFunctions
-                             PRIVATE "HAVE_LOG" "HAVE_EXP")
-endif()
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
 
 # install libs
 set(installable_libs MathFunctions tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+#  include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+  return detail::mysqrt(x);
+#else
+  return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
index 7eecd26..28ab042 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
@@ -1,8 +1,10 @@
+#include "mysqrt.h"
+
 #include <cmath>
 #include <iostream>
 
-#include "MathFunctions.h"
-
+namespace mathfunctions {
+namespace detail {
 // a hack square root calculation using simple operations
 double mysqrt(double x)
 {
@@ -30,3 +32,5 @@
 #endif
   return result;
 }
+}
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step8/TutorialConfig.h.in b/Help/guide/tutorial/Step8/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step8/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step8/TutorialConfig.h.in
@@ -1,4 +1,3 @@
 // the configured options and settings for Tutorial
 #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
 #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step8/tutorial.cxx b/Help/guide/tutorial/Step8/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step8/tutorial.cxx
+++ b/Help/guide/tutorial/Step8/tutorial.cxx
@@ -3,13 +3,9 @@
 #include <iostream>
 #include <string>
 
+#include "MathFunctions.h"
 #include "TutorialConfig.h"
 
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-#  include "MathFunctions.h"
-#endif
-
 int main(int argc, char* argv[])
 {
   if (argc < 2) {
@@ -23,12 +19,7 @@
   // convert input to double
   const double inputValue = std::stod(argv[1]);
 
-  // which square root function should we use?
-#ifdef USE_MYMATH
-  const double outputValue = mysqrt(inputValue);
-#else
-  const double outputValue = sqrt(inputValue);
-#endif
+  const double outputValue = mathfunctions::sqrt(inputValue);
 
   std::cout << "The square root of " << inputValue << " is " << outputValue
             << std::endl;
diff --git a/Help/guide/tutorial/Step9/CMakeLists.txt b/Help/guide/tutorial/Step9/CMakeLists.txt
index d26a90c..97ec6aa 100644
--- a/Help/guide/tutorial/Step9/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/CMakeLists.txt
@@ -16,22 +16,17 @@
   "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
 )
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
 # configure a header file to pass some of the CMake settings
 # to the source code
 configure_file(TutorialConfig.h.in TutorialConfig.h)
 
 # add the MathFunctions library
-if(USE_MYMATH)
-  add_subdirectory(MathFunctions)
-  list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
 
 # add the executable
 add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
 
 # add the binary tree to the search path for include files
 # so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
index 8e04f97..05c8616 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
@@ -1,34 +1,49 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-
-# add the command to generate the source code
-add_custom_command(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  DEPENDS MakeTable
-  )
-
-# add the main library
-add_library(MathFunctions
-            mysqrt.cxx
-            ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-            )
+add_library(MathFunctions MathFunctions.cxx)
 
 # state that anybody linking to us needs to include the current source dir
 # to find MathFunctions.h, while we don't.
-# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the
-# TutorialConfig.h include is an implementation detail
-# state that we depend on our binary dir to find Table.h
 target_include_directories(MathFunctions
-          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-          PRIVATE   ${CMAKE_CURRENT_BINARY_DIR}
-          )
+                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+                           )
 
-# link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+
+  # first we add the executable that generates the table
+  add_executable(MakeTable MakeTable.cxx)
+  target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
+
+  # add the command to generate the source code
+  add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+    COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+    DEPENDS MakeTable
+    )
+
+  # library that just does sqrt
+  add_library(SqrtLibrary STATIC
+              mysqrt.cxx
+              ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+              )
+
+  # state that we depend on our binary dir to find Table.h
+  target_include_directories(SqrtLibrary PRIVATE
+              ${CMAKE_CURRENT_BINARY_DIR}
+              )
+
+  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
+endif()
+
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
 
 # install libs
 set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
 install(TARGETS ${installable_libs} DESTINATION lib)
 # install include headers
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+#  include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+  return detail::mysqrt(x);
+#else
+  return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx
index 7d80ee9..477d715 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx
@@ -1,10 +1,12 @@
-#include <iostream>
+#include "mysqrt.h"
 
-#include "MathFunctions.h"
+#include <iostream>
 
 // include the generated table
 #include "Table.h"
 
+namespace mathfunctions {
+namespace detail {
 // a hack square root calculation using simple operations
 double mysqrt(double x)
 {
@@ -31,3 +33,5 @@
 
   return result;
 }
+}
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step9/TutorialConfig.h.in b/Help/guide/tutorial/Step9/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step9/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step9/TutorialConfig.h.in
@@ -1,4 +1,3 @@
 // the configured options and settings for Tutorial
 #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
 #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step9/tutorial.cxx b/Help/guide/tutorial/Step9/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step9/tutorial.cxx
+++ b/Help/guide/tutorial/Step9/tutorial.cxx
@@ -3,13 +3,9 @@
 #include <iostream>
 #include <string>
 
+#include "MathFunctions.h"
 #include "TutorialConfig.h"
 
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-#  include "MathFunctions.h"
-#endif
-
 int main(int argc, char* argv[])
 {
   if (argc < 2) {
@@ -23,12 +19,7 @@
   // convert input to double
   const double inputValue = std::stod(argv[1]);
 
-  // which square root function should we use?
-#ifdef USE_MYMATH
-  const double outputValue = mysqrt(inputValue);
-#else
-  const double outputValue = sqrt(inputValue);
-#endif
+  const double outputValue = mathfunctions::sqrt(inputValue);
 
   std::cout << "The square root of " << inputValue << " is " << outputValue
             << std::endl;
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index c3e87d7..8a92b4b 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -446,16 +446,20 @@
   components from a path. See :ref:`Path Structure And Terminology` for the
   meaning of each path component.
 
+  .. versionchanged:: 3.27
+    All operations now accept a list of paths as argument. When a list of paths
+    is specified, the operation will be applied to each path.
+
   ::
 
-    $<PATH:GET_ROOT_NAME,path>
-    $<PATH:GET_ROOT_DIRECTORY,path>
-    $<PATH:GET_ROOT_PATH,path>
-    $<PATH:GET_FILENAME,path>
-    $<PATH:GET_EXTENSION[,LAST_ONLY],path>
-    $<PATH:GET_STEM[,LAST_ONLY],path>
-    $<PATH:GET_RELATIVE_PART,path>
-    $<PATH:GET_PARENT_PATH,path>
+    $<PATH:GET_ROOT_NAME,path...>
+    $<PATH:GET_ROOT_DIRECTORY,path...>
+    $<PATH:GET_ROOT_PATH,path...>
+    $<PATH:GET_FILENAME,path...>
+    $<PATH:GET_EXTENSION[,LAST_ONLY],path...>
+    $<PATH:GET_STEM[,LAST_ONLY],path...>
+    $<PATH:GET_RELATIVE_PART,path...>
+    $<PATH:GET_PARENT_PATH,path...>
 
   If a requested component is not present in the path, an empty string is
   returned.
@@ -470,9 +474,14 @@
 options of the :command:`cmake_path` command.  All paths are expected to be
 in cmake-style format.
 
+.. versionchanged:: 3.27
+  All operations now accept a list of paths as argument. When a list of paths
+  is specified, the operation will be applied to each path.
+
+
 .. _GenEx PATH-CMAKE_PATH:
 
-.. genex:: $<PATH:CMAKE_PATH[,NORMALIZE],path>
+.. genex:: $<PATH:CMAKE_PATH[,NORMALIZE],path...>
 
   .. versionadded:: 3.24
 
@@ -483,7 +492,7 @@
   When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
   <Normalization>` after the conversion.
 
-.. genex:: $<PATH:APPEND,path,input,...>
+.. genex:: $<PATH:APPEND,path...,input,...>
 
   .. versionadded:: 3.24
 
@@ -493,7 +502,7 @@
 
   See :ref:`cmake_path(APPEND) <APPEND>` for more details.
 
-.. genex:: $<PATH:REMOVE_FILENAME,path>
+.. genex:: $<PATH:REMOVE_FILENAME,path...>
 
   .. versionadded:: 3.24
 
@@ -503,7 +512,7 @@
 
   See :ref:`cmake_path(REMOVE_FILENAME) <REMOVE_FILENAME>` for more details.
 
-.. genex:: $<PATH:REPLACE_FILENAME,path,input>
+.. genex:: $<PATH:REPLACE_FILENAME,path...,input>
 
   .. versionadded:: 3.24
 
@@ -513,7 +522,7 @@
 
   See :ref:`cmake_path(REPLACE_FILENAME) <REPLACE_FILENAME>` for more details.
 
-.. genex:: $<PATH:REMOVE_EXTENSION[,LAST_ONLY],path>
+.. genex:: $<PATH:REMOVE_EXTENSION[,LAST_ONLY],path...>
 
   .. versionadded:: 3.24
 
@@ -521,7 +530,7 @@
 
   See :ref:`cmake_path(REMOVE_EXTENSION) <REMOVE_EXTENSION>` for more details.
 
-.. genex:: $<PATH:REPLACE_EXTENSION[,LAST_ONLY],path,input>
+.. genex:: $<PATH:REPLACE_EXTENSION[,LAST_ONLY],path...,input>
 
   .. versionadded:: 3.24
 
@@ -530,14 +539,14 @@
 
   See :ref:`cmake_path(REPLACE_EXTENSION) <REPLACE_EXTENSION>` for more details.
 
-.. genex:: $<PATH:NORMAL_PATH,path>
+.. genex:: $<PATH:NORMAL_PATH,path...>
 
   .. versionadded:: 3.24
 
   Returns ``path`` normalized according to the steps described in
   :ref:`Normalization`.
 
-.. genex:: $<PATH:RELATIVE_PATH,path,base_directory>
+.. genex:: $<PATH:RELATIVE_PATH,path...,base_directory>
 
   .. versionadded:: 3.24
 
@@ -547,7 +556,7 @@
   See :ref:`cmake_path(RELATIVE_PATH) <cmake_path-RELATIVE_PATH>` for more
   details.
 
-.. genex:: $<PATH:ABSOLUTE_PATH[,NORMALIZE],path,base_directory>
+.. genex:: $<PATH:ABSOLUTE_PATH[,NORMALIZE],path...,base_directory>
 
   .. versionadded:: 3.24
 
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 22e9eb2..e4c286d 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,14 @@
 to determine whether to report an error on use of deprecated macros or
 functions.
 
+Policies Introduced by CMake 3.27
+=================================
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0144: find_package uses upper-case PACKAGENAME_ROOT variables. </policy/CMP0144>
+
 Policies Introduced by CMake 3.26
 =================================
 
diff --git a/Help/policy/CMP0144.rst b/Help/policy/CMP0144.rst
new file mode 100644
index 0000000..3959d96
--- /dev/null
+++ b/Help/policy/CMP0144.rst
@@ -0,0 +1,26 @@
+CMP0144
+-------
+
+.. versionadded:: 3.27
+
+:command:`find_package` uses upper-case ``<PACKAGENAME>_ROOT`` variables.
+
+In CMake 3.27 and above the :command:`find_package(<PackageName>)` command now
+searches prefixes specified by the upper-case :variable:`<PACKAGENAME>_ROOT`
+CMake variable and the :envvar:`<PACKAGENAME>_ROOT` environment variable
+in addition to the case-preserved :variable:`<PackageName>_ROOT` and
+:envvar:`<PackageName>_ROOT` variables used since policy :policy:`CMP0074`.
+This policy provides compatibility with projects that have not been
+updated to avoid using ``<PACKAGENAME>_ROOT`` variables for other purposes.
+
+The ``OLD`` behavior for this policy is to ignore ``<PACKAGENAME>_ROOT``
+variables if the original ``<PackageName>`` has lower-case characters.
+The ``NEW`` behavior for this policy is to use ``<PACKAGENAME>_ROOT``
+variables.
+
+This policy was introduced in CMake version 3.27.  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/release/dev/PATH-genex-support-list.rst b/Help/release/dev/PATH-genex-support-list.rst
new file mode 100644
index 0000000..ce87fdd
--- /dev/null
+++ b/Help/release/dev/PATH-genex-support-list.rst
@@ -0,0 +1,5 @@
+PATH-genex-supports-list
+------------------------
+
+* The :genex:`$<PATH>` generator expression learned to process list of paths
+  for decomposition and transformation operations.
diff --git a/Help/release/dev/find_package-PACKAGENAME_ROOT.rst b/Help/release/dev/find_package-PACKAGENAME_ROOT.rst
new file mode 100644
index 0000000..0388271
--- /dev/null
+++ b/Help/release/dev/find_package-PACKAGENAME_ROOT.rst
@@ -0,0 +1,7 @@
+find_package-PACKAGENAME_ROOT
+-----------------------------
+
+* The :command:`find_package` command now searches prefixes specified by
+  upper-case :variable:`<PACKAGENAME>_ROOT` CMake variables and upper-case
+  :envvar:`<PACKAGENAME>_ROOT` environment variables.
+  See policy :policy:`CMP0144`.
diff --git a/Help/variable/PackageName_ROOT.rst b/Help/variable/PackageName_ROOT.rst
index 6b17be3..8b728ba 100644
--- a/Help/variable/PackageName_ROOT.rst
+++ b/Help/variable/PackageName_ROOT.rst
@@ -14,3 +14,11 @@
 :ref:`semicolon-separated list <CMake Language Lists>` of multiple prefixes.
 
 See also the :envvar:`<PackageName>_ROOT` environment variable.
+
+.. variable:: <PACKAGENAME>_ROOT
+
+  .. versionadded:: 3.27
+
+  Calls to :command:`find_package(<PackageName>)` will also search in
+  prefixes specified by the upper-case ``<PACKAGENAME>_ROOT`` CMake
+  variable.  See policy :policy:`CMP0144`.
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index 153563f..dd5f617 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -1536,7 +1536,9 @@
     if(CMAKE_GENERATOR_TOOLSET)
       list(APPEND subCMakeOpts "-T${CMAKE_GENERATOR_TOOLSET}")
     endif()
-
+    if(CMAKE_GENERATOR_INSTANCE)
+      list(APPEND subCMakeOpts "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}")
+    endif()
     if(CMAKE_MAKE_PROGRAM)
       list(APPEND subCMakeOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
     endif()
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index ae1148d..4e8374c 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -120,12 +120,13 @@
     unset(_OpenSSL_has_dependency_zlib)
     if(OPENSSL_USE_STATIC_LIBS)
       set(_OpenSSL_libs "${_OPENSSL_STATIC_LIBRARIES}")
+      set(_OpenSSL_ldflags_other "${_OPENSSL_STATIC_LDFLAGS_OTHER}")
     else()
       set(_OpenSSL_libs "${_OPENSSL_LIBRARIES}")
+      set(_OpenSSL_ldflags_other "${_OPENSSL_LDFLAGS_OTHER}")
     endif()
     if(_OpenSSL_libs)
       unset(_OpenSSL_has_dependency_dl)
-      unset(_OpenSSL_has_dependency_threads)
       foreach(_OPENSSL_DEP_LIB IN LISTS _OpenSSL_libs)
         if (_OPENSSL_DEP_LIB STREQUAL "ssl" OR _OPENSSL_DEP_LIB STREQUAL "crypto")
           # ignoring: these are the targets
@@ -141,10 +142,22 @@
       unset(_OPENSSL_DEP_LIB)
     else()
       set(_OpenSSL_has_dependency_dl TRUE)
+    endif()
+    if(_OpenSSL_ldflags_other)
+      unset(_OpenSSL_has_dependency_threads)
+      foreach(_OPENSSL_DEP_LDFLAG IN LISTS _OpenSSL_ldflags_other)
+        if (_OPENSSL_DEP_LDFLAG STREQUAL "-pthread")
+          set(_OpenSSL_has_dependency_threads TRUE)
+          find_package(Threads)
+        endif()
+      endforeach()
+      unset(_OPENSSL_DEP_LDFLAG)
+    else()
       set(_OpenSSL_has_dependency_threads TRUE)
       find_package(Threads)
     endif()
     unset(_OpenSSL_libs)
+    unset(_OpenSSL_ldflags_other)
   else()
     set(_OpenSSL_has_dependencies FALSE)
   endif()
diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake
index 7461a3e..ea8616a 100644
--- a/Modules/GenerateExportHeader.cmake
+++ b/Modules/GenerateExportHeader.cmake
@@ -293,7 +293,7 @@
   set(DEFINE_IMPORT)
   set(DEFINE_NO_EXPORT)
 
-  if (COMPILER_HAS_DEPRECATED_ATTR)
+  if (COMPILER_HAS_DEPRECATED_ATTR AND NOT WIN32)
     set(DEFINE_DEPRECATED "__attribute__ ((__deprecated__))")
   elseif(COMPILER_HAS_DEPRECATED)
     set(DEFINE_DEPRECATED "__declspec(deprecated)")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 53f1136..6fc286a 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 26)
-set(CMake_VERSION_PATCH 20230223)
+set(CMake_VERSION_PATCH 20230225)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index c1b82ab..5f1a2c5 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -975,35 +975,7 @@
     }
   }
 
-  {
-    // Allocate a PACKAGE_ROOT_PATH for the current find_package call.
-    this->Makefile->FindPackageRootPathStack.emplace_back();
-    std::vector<std::string>& rootPaths =
-      this->Makefile->FindPackageRootPathStack.back();
-
-    // Add root paths from <PackageName>_ROOT CMake and environment variables,
-    // subject to CMP0074.
-    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0074)) {
-      case cmPolicies::WARN:
-        this->Makefile->MaybeWarnCMP0074(this->Name);
-        CM_FALLTHROUGH;
-      case cmPolicies::OLD:
-        // OLD behavior is to ignore the <pkg>_ROOT variables.
-        break;
-      case cmPolicies::REQUIRED_IF_USED:
-      case cmPolicies::REQUIRED_ALWAYS:
-        this->Makefile->IssueMessage(
-          MessageType::FATAL_ERROR,
-          cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0074));
-        break;
-      case cmPolicies::NEW: {
-        // NEW behavior is to honor the <pkg>_ROOT variables.
-        std::string const rootVar = this->Name + "_ROOT";
-        this->Makefile->GetDefExpandList(rootVar, rootPaths, false);
-        cmSystemTools::GetPath(rootPaths, rootVar.c_str());
-      } break;
-    }
-  }
+  this->PushFindPackageRootPathStack();
 
   this->SetModuleVariables(components, componentVarDefs);
 
@@ -1129,8 +1101,7 @@
   // Restore original state of "_FIND_" variables set in SetModuleVariables()
   this->RestoreFindDefinitions();
 
-  // Pop the package stack
-  this->Makefile->FindPackageRootPathStack.pop_back();
+  this->PopFindPackageRootPathStack();
 
   if (!this->DebugBuffer.empty()) {
     this->DebugMessage(this->DebugBuffer);
@@ -1834,6 +1805,99 @@
   }
 }
 
+void cmFindPackageCommand::PushFindPackageRootPathStack()
+{
+  // Allocate a PACKAGE_ROOT_PATH for the current find_package call.
+  this->Makefile->FindPackageRootPathStack.emplace_back();
+  std::vector<std::string>& rootPaths =
+    this->Makefile->FindPackageRootPathStack.back();
+
+  // Add root paths from <PackageName>_ROOT CMake and environment variables,
+  // subject to CMP0074.
+  std::string const rootVar = this->Name + "_ROOT";
+  cmValue rootDef = this->Makefile->GetDefinition(rootVar);
+  if (rootDef && rootDef.IsEmpty()) {
+    rootDef = nullptr;
+  }
+  cm::optional<std::string> rootEnv = cmSystemTools::GetEnvVar(rootVar);
+  if (rootEnv && rootEnv->empty()) {
+    rootEnv = cm::nullopt;
+  }
+  switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0074)) {
+    case cmPolicies::WARN:
+      this->Makefile->MaybeWarnCMP0074(rootVar, rootDef, rootEnv);
+      CM_FALLTHROUGH;
+    case cmPolicies::OLD:
+      // OLD behavior is to ignore the <PackageName>_ROOT variables.
+      return;
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::REQUIRED_ALWAYS:
+      this->Makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0074));
+      return;
+    case cmPolicies::NEW: {
+      // NEW behavior is to honor the <PackageName>_ROOT variables.
+    } break;
+  }
+
+  // Add root paths from <PACKAGENAME>_ROOT CMake and environment variables,
+  // if they are different than <PackageName>_ROOT, and subject to CMP0144.
+  std::string const rootVAR = cmSystemTools::UpperCase(rootVar);
+  cmValue rootDEF;
+  cm::optional<std::string> rootENV;
+  if (rootVAR != rootVar) {
+    rootDEF = this->Makefile->GetDefinition(rootVAR);
+    if (rootDEF && (rootDEF.IsEmpty() || rootDEF == rootDef)) {
+      rootDEF = nullptr;
+    }
+    rootENV = cmSystemTools::GetEnvVar(rootVAR);
+    if (rootENV && (rootENV->empty() || rootENV == rootEnv)) {
+      rootENV = cm::nullopt;
+    }
+  }
+
+  switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0144)) {
+    case cmPolicies::WARN:
+      this->Makefile->MaybeWarnCMP0144(rootVAR, rootDEF, rootENV);
+      CM_FALLTHROUGH;
+    case cmPolicies::OLD:
+      // OLD behavior is to ignore the <PACKAGENAME>_ROOT variables.
+      rootDEF = nullptr;
+      rootENV = cm::nullopt;
+      break;
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::REQUIRED_ALWAYS:
+      this->Makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0144));
+      return;
+    case cmPolicies::NEW: {
+      // NEW behavior is to honor the <PACKAGENAME>_ROOT variables.
+    } break;
+  }
+
+  if (rootDef) {
+    cmExpandList(*rootDef, rootPaths);
+  }
+  if (rootDEF) {
+    cmExpandList(*rootDEF, rootPaths);
+  }
+  if (rootEnv) {
+    std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootEnv);
+    std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
+  }
+  if (rootENV) {
+    std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootENV);
+    std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
+  }
+}
+
+void cmFindPackageCommand::PopFindPackageRootPathStack()
+{
+  this->Makefile->FindPackageRootPathStack.pop_back();
+}
+
 void cmFindPackageCommand::ComputePrefixes()
 {
   this->FillPrefixesPackageRedirect();
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 28e00a1..18684c9 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -125,6 +125,9 @@
   void StoreVersionFound();
   void SetConfigDirCacheVariable(const std::string& value);
 
+  void PushFindPackageRootPathStack();
+  void PopFindPackageRootPathStack();
+
   void ComputePrefixes();
   void FillPrefixesPackageRedirect();
   void FillPrefixesPackageRoot();
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 5d761ac..5c7d217 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -688,6 +688,14 @@
     const GeneratorExpressionContent* content,
     cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
+    static auto processList =
+      [](std::string const& arg,
+         std::function<void(std::string&)> transform) -> std::string {
+      auto list = cmExpandedList(arg);
+      std::for_each(list.begin(), list.end(), std::move(transform));
+      return cmJoin(list, ";");
+    };
+
     static std::unordered_map<
       cm::string_view,
       std::function<std::string(cmGeneratorExpressionContext*,
@@ -698,38 +706,49 @@
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "GET_ROOT_NAME"_s, args) &&
-                !args.front().empty()
-              ? cmCMakePath{ args.front() }.GetRootName().String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "GET_ROOT_NAME"_s, args) &&
+                !args.front().empty()) {
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.GetRootName().String();
+              });
+            }
+            return std::string{};
           } },
         { "GET_ROOT_DIRECTORY"_s,
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "GET_ROOT_DIRECTORY"_s,
-                                       args) &&
-                !args.front().empty()
-              ? cmCMakePath{ args.front() }.GetRootDirectory().String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "GET_ROOT_DIRECTORY"_s, args) &&
+                !args.front().empty()) {
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.GetRootDirectory().String();
+              });
+            }
+            return std::string{};
           } },
         { "GET_ROOT_PATH"_s,
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "GET_ROOT_PATH"_s, args) &&
-                !args.front().empty()
-              ? cmCMakePath{ args.front() }.GetRootPath().String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "GET_ROOT_PATH"_s, args) &&
+                !args.front().empty()) {
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.GetRootPath().String();
+              });
+            }
+            return std::string{};
           } },
         { "GET_FILENAME"_s,
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "GET_FILENAME"_s, args) &&
-                !args.front().empty()
-              ? cmCMakePath{ args.front() }.GetFileName().String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "GET_FILENAME"_s, args) &&
+                !args.front().empty()) {
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.GetFileName().String();
+              });
+            }
+            return std::string{};
           } },
         { "GET_EXTENSION"_s,
           [](cmGeneratorExpressionContext* ctx,
@@ -746,9 +765,14 @@
               if (args.front().empty()) {
                 return std::string{};
               }
-              return lastOnly
-                ? cmCMakePath{ args.front() }.GetExtension().String()
-                : cmCMakePath{ args.front() }.GetWideExtension().String();
+              if (lastOnly) {
+                return processList(args.front(), [](std::string& value) {
+                  value = cmCMakePath{ value }.GetExtension().String();
+                });
+              }
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.GetWideExtension().String();
+              });
             }
             return std::string{};
           } },
@@ -766,9 +790,14 @@
               if (args.front().empty()) {
                 return std::string{};
               }
-              return lastOnly
-                ? cmCMakePath{ args.front() }.GetStem().String()
-                : cmCMakePath{ args.front() }.GetNarrowStem().String();
+              if (lastOnly) {
+                return processList(args.front(), [](std::string& value) {
+                  value = cmCMakePath{ value }.GetStem().String();
+                });
+              }
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.GetNarrowStem().String();
+              });
             }
             return std::string{};
           } },
@@ -776,19 +805,24 @@
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "GET_RELATIVE_PART"_s,
-                                       args) &&
-                !args.front().empty()
-              ? cmCMakePath{ args.front() }.GetRelativePath().String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "GET_RELATIVE_PART"_s, args) &&
+                !args.front().empty()) {
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.GetRelativePath().String();
+              });
+            }
+            return std::string{};
           } },
         { "GET_PARENT_PATH"_s,
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "GET_PARENT_PATH"_s, args)
-              ? cmCMakePath{ args.front() }.GetParentPath().String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "GET_PARENT_PATH"_s, args)) {
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.GetParentPath().String();
+              });
+            }
+            return std::string{};
           } },
         { "HAS_ROOT_NAME"_s,
           [](cmGeneratorExpressionContext* ctx,
@@ -904,10 +938,12 @@
                                       normalize ? "CMAKE_PATH,NORMALIZE"_s
                                                 : "CMAKE_PATH"_s,
                                       args.size(), 1)) {
-              auto path =
-                cmCMakePath{ args.front(), cmCMakePath::auto_format };
-              return normalize ? path.Normal().GenericString()
-                               : path.GenericString();
+              return processList(
+                args.front(), [normalize](std::string& value) {
+                  auto path = cmCMakePath{ value, cmCMakePath::auto_format };
+                  value = normalize ? path.Normal().GenericString()
+                                    : path.GenericString();
+                });
             }
             return std::string{};
           } },
@@ -917,11 +953,16 @@
              Arguments& args) -> std::string {
             if (CheckPathParametersEx(ctx, cnt, "APPEND"_s, args.size(), 1,
                                       false)) {
-              cmCMakePath path;
-              for (const auto& p : args) {
-                path /= p;
-              }
-              return path.String();
+              auto const& list = args.front();
+              args.advance(1);
+
+              return processList(list, [&args](std::string& value) {
+                cmCMakePath path{ value };
+                for (const auto& p : args) {
+                  path /= p;
+                }
+                value = path.String();
+              });
             }
             return std::string{};
           } },
@@ -929,20 +970,26 @@
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "REMOVE_FILENAME"_s, args) &&
-                !args.front().empty()
-              ? cmCMakePath{ args.front() }.RemoveFileName().String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "REMOVE_FILENAME"_s, args) &&
+                !args.front().empty()) {
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.RemoveFileName().String();
+              });
+            }
+            return std::string{};
           } },
         { "REPLACE_FILENAME"_s,
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "REPLACE_FILENAME"_s, args, 2)
-              ? cmCMakePath{ args[0] }
-                  .ReplaceFileName(cmCMakePath{ args[1] })
-                  .String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "REPLACE_FILENAME"_s, args, 2)) {
+              return processList(args.front(), [&args](std::string& value) {
+                value = cmCMakePath{ value }
+                          .ReplaceFileName(cmCMakePath{ args[1] })
+                          .String();
+              });
+            }
+            return std::string{};
           } },
         { "REMOVE_EXTENSION"_s,
           [](cmGeneratorExpressionContext* ctx,
@@ -959,9 +1006,14 @@
               if (args.front().empty()) {
                 return std::string{};
               }
-              return lastOnly
-                ? cmCMakePath{ args.front() }.RemoveExtension().String()
-                : cmCMakePath{ args.front() }.RemoveWideExtension().String();
+              if (lastOnly) {
+                return processList(args.front(), [](std::string& value) {
+                  value = cmCMakePath{ value }.RemoveExtension().String();
+                });
+              }
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.RemoveWideExtension().String();
+              });
             }
             return std::string{};
           } },
@@ -979,13 +1031,17 @@
                                         : "REPLACE_EXTENSION"_s,
                                       args.size(), 2)) {
               if (lastOnly) {
-                return cmCMakePath{ args[0] }
-                  .ReplaceExtension(cmCMakePath{ args[1] })
-                  .String();
+                return processList(args.front(), [&args](std::string& value) {
+                  value = cmCMakePath{ value }
+                            .ReplaceExtension(cmCMakePath{ args[1] })
+                            .String();
+                });
               }
-              return cmCMakePath{ args[0] }
-                .ReplaceWideExtension(cmCMakePath{ args[1] })
-                .String();
+              return processList(args.front(), [&args](std::string& value) {
+                value = cmCMakePath{ value }
+                          .ReplaceWideExtension(cmCMakePath{ args[1] })
+                          .String();
+              });
             }
             return std::string{};
           } },
@@ -993,18 +1049,24 @@
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "NORMAL_PATH"_s, args) &&
-                !args.front().empty()
-              ? cmCMakePath{ args.front() }.Normal().String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "NORMAL_PATH"_s, args) &&
+                !args.front().empty()) {
+              return processList(args.front(), [](std::string& value) {
+                value = cmCMakePath{ value }.Normal().String();
+              });
+            }
+            return std::string{};
           } },
         { "RELATIVE_PATH"_s,
           [](cmGeneratorExpressionContext* ctx,
              const GeneratorExpressionContent* cnt,
              Arguments& args) -> std::string {
-            return CheckPathParameters(ctx, cnt, "RELATIVE_PATH"_s, args, 2)
-              ? cmCMakePath{ args[0] }.Relative(args[1]).String()
-              : std::string{};
+            if (CheckPathParameters(ctx, cnt, "RELATIVE_PATH"_s, args, 2)) {
+              return processList(args.front(), [&args](std::string& value) {
+                value = cmCMakePath{ value }.Relative(args[1]).String();
+              });
+            }
+            return std::string{};
           } },
         { "ABSOLUTE_PATH"_s,
           [](cmGeneratorExpressionContext* ctx,
@@ -1018,8 +1080,11 @@
                                       normalize ? "ABSOLUTE_PATH,NORMALIZE"_s
                                                 : "ABSOLUTE_PATH"_s,
                                       args.size(), 2)) {
-              auto path = cmCMakePath{ args[0] }.Absolute(args[1]);
-              return normalize ? path.Normal().String() : path.String();
+              return processList(
+                args.front(), [&args, normalize](std::string& value) {
+                  auto path = cmCMakePath{ value }.Absolute(args[1]);
+                  value = normalize ? path.Normal().String() : path.String();
+                });
             }
             return std::string{};
           } }
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index d963a5a..2fc2974 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -208,32 +208,47 @@
   return true;
 }
 
-void cmMakefile::MaybeWarnCMP0074(std::string const& pkg)
+void cmMakefile::MaybeWarnCMP0074(std::string const& rootVar, cmValue rootDef,
+                                  cm::optional<std::string> const& rootEnv)
 {
-  // Warn if a <pkg>_ROOT variable we may use is set.
-  std::string const varName = pkg + "_ROOT";
-  cmValue var = this->GetDefinition(varName);
-  std::string env;
-  cmSystemTools::GetEnv(varName, env);
-
-  bool const haveVar = cmNonempty(var);
-  bool const haveEnv = !env.empty();
-  if ((haveVar || haveEnv) && this->WarnedCMP0074.insert(varName).second) {
+  // Warn if a <PackageName>_ROOT variable we may use is set.
+  if ((rootDef || rootEnv) && this->WarnedCMP0074.insert(rootVar).second) {
     std::ostringstream w;
     w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0074) << "\n";
-    if (haveVar) {
-      w << "CMake variable " << varName << " is set to:\n"
-        << "  " << *var << "\n";
+    if (rootDef) {
+      w << "CMake variable " << rootVar << " is set to:\n"
+        << "  " << *rootDef << "\n";
     }
-    if (haveEnv) {
-      w << "Environment variable " << varName << " is set to:\n"
-        << "  " << env << "\n";
+    if (rootEnv) {
+      w << "Environment variable " << rootVar << " is set to:\n"
+        << "  " << *rootEnv << "\n";
     }
     w << "For compatibility, CMake is ignoring the variable.";
     this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
   }
 }
 
+void cmMakefile::MaybeWarnCMP0144(std::string const& rootVAR, cmValue rootDEF,
+                                  cm::optional<std::string> const& rootENV)
+{
+  // Warn if a <PACKAGENAME>_ROOT variable we may use is set.
+  if ((rootDEF || rootENV) && this->WarnedCMP0144.insert(rootVAR).second) {
+    std::ostringstream w;
+    w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0144) << "\n";
+    if (rootDEF) {
+      w << "CMake variable " << rootVAR << " is set to:\n"
+        << "  " << *rootDEF << "\n";
+    }
+    if (rootENV) {
+      w << "Environment variable " << rootVAR << " is set to:\n"
+        << "  " << *rootENV << "\n";
+    }
+    w << "For compatibility, find_package is ignoring the variable, but "
+         "code in a .cmake module might still use it.";
+    this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+  }
+}
+
 cmBTStringRange cmMakefile::GetIncludeDirectoriesEntries() const
 {
   return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 7b19c97..3cf6e61 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -1011,7 +1011,10 @@
 
   bool GetDebugFindPkgMode() const;
 
-  void MaybeWarnCMP0074(std::string const& pkg);
+  void MaybeWarnCMP0074(std::string const& rootVar, cmValue rootDef,
+                        cm::optional<std::string> const& rootEnv);
+  void MaybeWarnCMP0144(std::string const& rootVAR, cmValue rootDEF,
+                        cm::optional<std::string> const& rootENV);
   void MaybeWarnUninitialized(std::string const& variable,
                               const char* sourceFilename) const;
   bool IsProjectFile(const char* filename) const;
@@ -1189,6 +1192,7 @@
   bool CheckSystemVars;
   bool CheckCMP0000;
   std::set<std::string> WarnedCMP0074;
+  std::set<std::string> WarnedCMP0144;
   bool IsSourceFileTryCompile;
   mutable bool SuppressSideEffects;
   ImportedTargetScope CurrentImportedTargetScope = ImportedTargetScope::Local;
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 568eca3..1eca586 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -434,7 +434,10 @@
          3, 25, 0, cmPolicies::WARN)                                          \
   SELECT(POLICY, CMP0143,                                                     \
          "Global property USE_FOLDERS treated as ON by default", 3, 26, 0,    \
-         cmPolicies::WARN)
+         cmPolicies::WARN)                                                    \
+  SELECT(POLICY, CMP0144,                                                     \
+         "find_package uses upper-case <PACKAGENAME>_ROOT variables.", 3, 27, \
+         0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 3d61270..1fb0079 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1648,6 +1648,32 @@
   return out;
 }
 
+cm::optional<std::string> cmSystemTools::GetEnvVar(std::string const& var)
+{
+  cm::optional<std::string> result;
+  {
+    std::string value;
+    if (cmSystemTools::GetEnv(var, value)) {
+      result = std::move(value);
+    }
+  }
+  return result;
+}
+
+std::vector<std::string> cmSystemTools::SplitEnvPath(std::string const& value)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  static cm::string_view sep = ";"_s;
+#else
+  static cm::string_view sep = ":"_s;
+#endif
+  std::vector<std::string> paths = cmTokenize(value, sep);
+  for (std::string& p : paths) {
+    SystemTools::ConvertToUnixSlashes(p);
+  }
+  return paths;
+}
+
 #ifndef CMAKE_BOOTSTRAP
 bool cmSystemTools::UnsetEnv(const char* value)
 {
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 09f2bf0..7d55d4b 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -399,6 +399,9 @@
   static std::string RelativeIfUnder(std::string const& top,
                                      std::string const& in);
 
+  static cm::optional<std::string> GetEnvVar(std::string const& var);
+  static std::vector<std::string> SplitEnvPath(std::string const& value);
+
 #ifndef CMAKE_BOOTSTRAP
   /** Remove an environment variable */
   static bool UnsetEnv(const char* value);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index d57b78b..a2a9e09 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -2329,6 +2329,9 @@
         cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0 ||
         cmSystemTools::Strucmp(arg->c_str(), "-INCREMENTAL") == 0) {
       this->Incremental = true;
+    } else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:NO") == 0 ||
+               cmSystemTools::Strucmp(arg->c_str(), "-INCREMENTAL:NO") == 0) {
+      this->Incremental = false;
     } else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0 ||
                cmSystemTools::Strucmp(arg->c_str(), "-MANIFEST:NO") == 0) {
       this->LinkGeneratesManifest = false;
@@ -2353,17 +2356,11 @@
     // pass it to the link command.
     this->ManifestFileRC = intDir + "/manifest.rc";
     this->ManifestFileRes = intDir + "/manifest.res";
-  } 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.emplace_back("/MANIFEST");
-    this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
+    if (this->LinkGeneratesManifest) {
+      this->LinkCommand.emplace_back("/MANIFEST");
+      this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
+    }
   }
 
   return true;
@@ -2497,20 +2494,23 @@
 
 int cmVSLink::LinkNonIncremental()
 {
-  // Run the link command (possibly generates intermediate manifest).
+  // Sort out any manifests.
+  if (this->LinkGeneratesManifest || !this->UserManifests.empty()) {
+    std::string opt =
+      std::string("/MANIFEST:EMBED,ID=") + (this->Type == 1 ? '1' : '2');
+    this->LinkCommand.emplace_back(opt);
+
+    for (auto const& m : this->UserManifests) {
+      opt = "/MANIFESTINPUT:" + m;
+      this->LinkCommand.emplace_back(opt);
+    }
+  }
+
+  // Run the link command.
   if (!RunCommand("LINK", this->LinkCommand, this->Verbose, FORMAT_DECIMAL)) {
     return -1;
   }
-
-  // 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);
+  return 0;
 }
 
 int cmVSLink::RunMT(std::string const& out, bool notify)
diff --git a/Tests/MSManifest/Subdir/CMakeLists.txt b/Tests/MSManifest/Subdir/CMakeLists.txt
index 3b4fccc..68c66fe 100644
--- a/Tests/MSManifest/Subdir/CMakeLists.txt
+++ b/Tests/MSManifest/Subdir/CMakeLists.txt
@@ -5,6 +5,11 @@
   add_test(NAME MSManifest.Single COMMAND
     ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
     -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
+  add_executable(MSManifestNonIncremental main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+  set_property(TARGET MSManifestNonIncremental PROPERTY LINK_FLAGS "/INCREMENTAL:NO")
+  add_test(NAME MSManifest.Single.NonIncremental COMMAND
+    ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifestNonIncremental>
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
   add_executable(MSManifestNone main.c)
   set_property(TARGET MSManifestNone PROPERTY LINK_FLAGS "/MANIFEST:NO")
 elseif(WIN32 AND CMAKE_C_COMPILER_ID MATCHES "Clang")
diff --git a/Tests/MSManifest/Subdir2/CMakeLists.txt b/Tests/MSManifest/Subdir2/CMakeLists.txt
index 0d960ad..bbc70dc 100644
--- a/Tests/MSManifest/Subdir2/CMakeLists.txt
+++ b/Tests/MSManifest/Subdir2/CMakeLists.txt
@@ -10,4 +10,14 @@
   add_test(NAME MSManifest.Multiple COMMAND
     ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSMultipleManifest>
     -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
+  if(MSVC AND NOT MSVC_VERSION LESS 1400)
+    add_executable(MSMultipleManifestNonIncremental main.c
+      ${CMAKE_CURRENT_BINARY_DIR}/test_manifest1.manifest
+      ${CMAKE_CURRENT_BINARY_DIR}/test_manifest2.manifest
+      ${CMAKE_CURRENT_BINARY_DIR}/test_manifest3.manifest)
+    set_property(TARGET MSMultipleManifestNonIncremental PROPERTY LINK_FLAGS "/INCREMENTAL:NO")
+    add_test(NAME MSManifest.Multiple.NonIncremental COMMAND
+      ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSMultipleManifestNonIncremental>
+      -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
+  endif()
 endif()
diff --git a/Tests/RunCMake/GenEx-PATH/ABSOLUTE_PATH.cmake.in b/Tests/RunCMake/GenEx-PATH/ABSOLUTE_PATH.cmake.in
index cc5ff54..d1cb61b 100644
--- a/Tests/RunCMake/GenEx-PATH/ABSOLUTE_PATH.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/ABSOLUTE_PATH.cmake.in
@@ -31,4 +31,28 @@
 endif()
 
 
+######################################
+## tests with list of paths
+######################################
+unset (reference)
+foreach(item IN ITEMS "../../a/d" "/a/d/../e")
+  cmake_path(ABSOLUTE_PATH item BASE_DIRECTORY "/x/y/a/f")
+  list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:ABSOLUTE_PATH,../../a/d;/a/d/../e,/x/y/a/f>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+unset (reference)
+foreach(item IN ITEMS "../../a/d" "/a/d/../e")
+  cmake_path(ABSOLUTE_PATH item BASE_DIRECTORY "/x/y/a/f" NORMALIZE)
+  list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:ABSOLUTE_PATH,NORMALIZE,../../a/d;/a/d/../e,/x/y/a/f>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+
 check_errors("PATH:ABSOLUTE_PATH" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/APPEND.cmake.in b/Tests/RunCMake/GenEx-PATH/APPEND.cmake.in
index ab967a2..1955480 100644
--- a/Tests/RunCMake/GenEx-PATH/APPEND.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/APPEND.cmake.in
@@ -65,4 +65,39 @@
   endif()
 endif()
 
+
+######################################
+## tests with list of paths
+######################################
+unset(reference)
+foreach(item IN ITEMS "/a/b" "/x/y")
+  cmake_path (APPEND result "${item}" "c")
+  list(APPEND reference "${result}")
+endforeach()
+set(output "$<PATH:APPEND,/a/b;/x/y,c>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+unset(reference)
+foreach(item IN ITEMS "a" "c")
+  cmake_path (APPEND item "")
+  list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:APPEND,a;c,>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+unset(reference)
+foreach(item IN ITEMS "a/" "c/")
+  cmake_path (APPEND item "/b")
+  list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:APPEND,a/;c/,/b>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+
 check_errors ("PATH:APPEND" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/CMAKE_PATH.cmake.in b/Tests/RunCMake/GenEx-PATH/CMAKE_PATH.cmake.in
index 41205fa..29ebf16 100644
--- a/Tests/RunCMake/GenEx-PATH/CMAKE_PATH.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/CMAKE_PATH.cmake.in
@@ -50,4 +50,46 @@
 endif()
 
 
+######################################
+## tests with list of paths
+######################################
+set(reference "/x/y/z/../../a/d;/x/y/z/../../b/e")
+set(output "$<PATH:CMAKE_PATH,/x/y/z/../../a/d;/x/y/z/../../b/e>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+unset(reference)
+foreach(path IN ITEMS "/x/y/z/../../a/d" "/x/y/z/../../b/e")
+  cmake_path(SET result NORMALIZE "${path}")
+  list(APPEND reference "${result}")
+endforeach()
+set(output "$<PATH:CMAKE_PATH,NORMALIZE,/x/y/z/../../a/d;/x/y/z/../../b/e>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+if (WIN32)
+  unset(reference)
+  foreach(path IN ITEMS "/x\\y/z\\..\\../a/d" "/x\\y/z\\..\\../b/e")
+    cmake_path(SET result "${path}")
+    list(APPEND reference "${result}")
+  endforeach()
+  set(output "$<PATH:CMAKE_PATH,/x\y/z\..\../a/d;/x\y/z\..\../b/e>")
+  if (NOT output STREQUAL reference)
+    list (APPEND errors "'${output}' instead of '${reference}'")
+  endif()
+
+  unset(reference)
+  foreach(path IN ITEMS "/x\\y/z\\..\\../a/d" "/x\\y/z\\..\\../b/e")
+    cmake_path(SET result NORMALIZE "${path}")
+    list(APPEND reference "${result}")
+  endforeach()
+  set(output "$<PATH:CMAKE_PATH,NORMALIZE,/x\y/z\..\../a/d;/x\y/z\..\../b/e>")
+  if (NOT output STREQUAL reference)
+    list (APPEND errors "'${output}' instead of '${reference}'")
+  endif()
+endif()
+
+
 check_errors("PATH:CMAKE_PATH" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/CMakeLists.txt b/Tests/RunCMake/GenEx-PATH/CMakeLists.txt
index f9748e9..5161b99 100644
--- a/Tests/RunCMake/GenEx-PATH/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-PATH/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.18...3.24)
+cmake_minimum_required(VERSION 3.18...3.25)
 
 project(${RunCMake_TEST} NONE)
 
diff --git a/Tests/RunCMake/GenEx-PATH/GET_ITEM.cmake.in b/Tests/RunCMake/GenEx-PATH/GET_ITEM.cmake.in
index b58998c..e2acde4 100644
--- a/Tests/RunCMake/GenEx-PATH/GET_ITEM.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/GET_ITEM.cmake.in
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0140 NEW)
 
 include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
 unset (errors)
@@ -308,4 +309,126 @@
 endif()
 
 
+######################################
+## third, tests with list of paths
+######################################
+if (WIN32)
+  set (paths "C:/aa/bb/cc.ext1.ext2" "D:/xx/yy/zz.ext3.ext4")
+else()
+  set (paths "/aa/bb/cc.ext1.ext2" "/xx/yy/zz.ext3.ext4")
+endif()
+
+function (compute_reference action)
+  unset(reference)
+  foreach (path IN LISTS paths)
+    cmake_path(GET path ${ARGV} result)
+    list(APPEND reference "${result}")
+  endforeach()
+  if (reference STREQUAL "")
+    # define the list as 2 empty elements
+    set(reference ";")
+  endif()
+
+  return(PROPAGATE reference)
+endfunction()
+
+compute_reference(ROOT_NAME)
+if (WIN32)
+  set(output "$<PATH:GET_ROOT_NAME,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_ROOT_NAME,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "ROOT_NAME returns bad data: ${output}")
+endif()
+
+compute_reference(ROOT_DIRECTORY)
+if (WIN32)
+  set(output "$<PATH:GET_ROOT_DIRECTORY,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_ROOT_DIRECTORY,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "ROOT_DIRECTORY returns bad data: ${output}")
+endif()
+
+compute_reference(ROOT_PATH)
+if (WIN32)
+  set(output "$<PATH:GET_ROOT_PATH,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_ROOT_PATH,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "ROOT_PATH returns bad data: ${output}")
+endif()
+
+compute_reference(FILENAME)
+if (WIN32)
+  set(output "$<PATH:GET_FILENAME,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_FILENAME,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "FILENAME returns bad data: ${output}")
+endif()
+
+compute_reference(EXTENSION)
+if (WIN32)
+  set(output "$<PATH:GET_EXTENSION,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_EXTENSION,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "EXTENSION returns bad data: ${output}")
+endif()
+compute_reference(EXTENSION LAST_ONLY)
+if (WIN32)
+  set(output "$<PATH:GET_EXTENSION,LAST_ONLY,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_EXTENSION,LAST_ONLY,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "EXTENSION LAST_ONLY returns bad data: ${output}")
+endif()
+
+compute_reference(STEM)
+if (WIN32)
+  set(output "$<PATH:GET_STEM,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_STEM,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "STEM returns bad data: ${output}")
+endif()
+compute_reference(STEM LAST_ONLY)
+if (WIN32)
+  set(output "$<PATH:GET_STEM,LAST_ONLY,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_STEM,LAST_ONLY,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "STEM LAST_ONLY returns bad data: ${reference}")
+endif()
+
+compute_reference(RELATIVE_PART)
+if (WIN32)
+  set(output "$<PATH:GET_RELATIVE_PART,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_RELATIVE_PART,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "RELATIVE_PART returns bad data: ${output}")
+endif()
+
+compute_reference(PARENT_PATH)
+if (WIN32)
+  set(output "$<PATH:GET_PARENT_PATH,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+  set (output "$<PATH:GET_PARENT_PATH,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+  list (APPEND errors "PARENT_PATH returns bad data: ${output}")
+endif()
+
+
 check_errors("PATH:GET..." ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/NORMAL_PATH.cmake.in b/Tests/RunCMake/GenEx-PATH/NORMAL_PATH.cmake.in
index e6cc4a3..81e4c0d 100644
--- a/Tests/RunCMake/GenEx-PATH/NORMAL_PATH.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/NORMAL_PATH.cmake.in
@@ -40,4 +40,18 @@
 endif()
 
 
+######################################
+## tests with list of paths
+######################################
+unset (reference)
+foreach(item IN ITEMS "a/./b/.." "x/.//y/z//..")
+  cmake_path(NORMAL_PATH item)
+  list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:NORMAL_PATH,a/./b/..;x/.//y/z//..>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+
 check_errors("PATH:NORMAL_PATH" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/RELATIVE_PATH.cmake.in b/Tests/RunCMake/GenEx-PATH/RELATIVE_PATH.cmake.in
index 11d73ad..7670f4f 100644
--- a/Tests/RunCMake/GenEx-PATH/RELATIVE_PATH.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/RELATIVE_PATH.cmake.in
@@ -61,4 +61,18 @@
 endif()
 
 
+######################################
+## tests with list of paths
+######################################
+unset (reference)
+foreach(item IN ITEMS "/a//d" "/a/b/e")
+  cmake_path(RELATIVE_PATH item BASE_DIRECTORY "/a/b/c")
+  list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:RELATIVE_PATH,/a//d;/a/b/e,/a/b/c>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+
 check_errors("PATH:RELATIVE_PATH" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/REMOVE_ITEM.cmake.in b/Tests/RunCMake/GenEx-PATH/REMOVE_ITEM.cmake.in
index cce4143..a365efe 100644
--- a/Tests/RunCMake/GenEx-PATH/REMOVE_ITEM.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/REMOVE_ITEM.cmake.in
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0140 NEW)
 
 include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
 unset (errors)
@@ -62,4 +63,39 @@
 endif()
 
 
+######################################
+## tests with list of paths
+######################################
+function (compute_reference action)
+  unset(reference)
+  foreach (path IN LISTS paths)
+    cmake_path(${action} path ${ARGN})
+    list(APPEND reference "${path}")
+  endforeach()
+
+  return(PROPAGATE reference)
+endfunction()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REMOVE_FILENAME)
+set(output "$<PATH:REMOVE_FILENAME,a/b/c.e.f;g/h/i.j.k>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "FILENAME: '${output}' instead of '${reference}'")
+endif()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REMOVE_EXTENSION)
+set(output "$<PATH:REMOVE_EXTENSION,a/b/c.e.f;g/h/i.j.k>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
+endif()
+
+set (reference "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REMOVE_EXTENSION LAST_ONLY)
+set(output "$<PATH:REMOVE_EXTENSION,LAST_ONLY,a/b/c.e.f;g/h/i.j.k>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
+endif()
+
+
 check_errors("PATH:REMOVE..." ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/REPLACE_ITEM.cmake.in b/Tests/RunCMake/GenEx-PATH/REPLACE_ITEM.cmake.in
index 5bb04c3..2d02152 100644
--- a/Tests/RunCMake/GenEx-PATH/REPLACE_ITEM.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/REPLACE_ITEM.cmake.in
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0140 NEW)
 
 include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
 unset (errors)
@@ -70,4 +71,39 @@
 endif()
 
 
+######################################
+## tests with list of paths
+######################################
+function (compute_reference action new_value)
+  unset(reference)
+  foreach (path IN LISTS paths)
+    cmake_path(${action} path "${new_value}" ${ARGN})
+    list(APPEND reference "${path}")
+  endforeach()
+
+  return(PROPAGATE reference)
+endfunction()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REPLACE_FILENAME "x.y")
+set(output "$<PATH:REPLACE_FILENAME,a/b/c.e.f;g/h/i.j.k,x.y>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "FILENAME: '${output}' instead of '${reference}'")
+endif()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REPLACE_EXTENSION ".x")
+set(output "$<PATH:REPLACE_EXTENSION,a/b/c.e.f;g/h/i.j.k,.x>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
+endif()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REPLACE_EXTENSION ".x" LAST_ONLY)
+set(output "$<PATH:REPLACE_EXTENSION,LAST_ONLY,a/b/c.e.f;g/h/i.j.k,.x>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
+endif()
+
+
 check_errors("PATH:REPLACE..." ${errors})
diff --git a/Tests/RunCMake/GenerateExportHeader/GEH.cmake b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
index bf9c302..3e35aa3 100644
--- a/Tests/RunCMake/GenerateExportHeader/GEH.cmake
+++ b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
@@ -100,7 +100,9 @@
     set(_platform Win32-Clang)
   elseif(MSVC AND COMPILER_HAS_DEPRECATED)
     set(_platform Win32)
-  elseif((MINGW OR CYGWIN) AND COMPILER_HAS_DEPRECATED)
+  elseif(CYGWIN AND COMPILER_HAS_DEPRECATED)
+    set(_platform Cygwin)
+  elseif(MINGW AND COMPILER_HAS_DEPRECATED)
     set(_platform MinGW)
   else()
     set(_platform WinEmpty)
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h
new file mode 100644
index 0000000..dac4fda
--- /dev/null
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h
@@ -0,0 +1,42 @@
+
+#ifndef LIBSHARED_EXPORT_H
+#define LIBSHARED_EXPORT_H
+
+#ifdef LIBSHARED_STATIC_DEFINE
+#  define LIBSHARED_EXPORT
+#  define LIBSHARED_NO_EXPORT
+#else
+#  ifndef LIBSHARED_EXPORT
+#    ifdef libshared_EXPORTS
+        /* We are building this library */
+#      define LIBSHARED_EXPORT __declspec(dllexport)
+#    else
+        /* We are using this library */
+#      define LIBSHARED_EXPORT __declspec(dllimport)
+#    endif
+#  endif
+
+#  ifndef LIBSHARED_NO_EXPORT
+#    define LIBSHARED_NO_EXPORT
+#  endif
+#endif
+
+#ifndef LIBSHARED_DEPRECATED
+#  define LIBSHARED_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_EXPORT
+#  define LIBSHARED_DEPRECATED_EXPORT LIBSHARED_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_NO_EXPORT
+#  define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+#  ifndef LIBSHARED_NO_DEPRECATED
+#    define LIBSHARED_NO_DEPRECATED
+#  endif
+#endif
+
+#endif /* LIBSHARED_EXPORT_H */
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h
new file mode 100644
index 0000000..b6e2a4a
--- /dev/null
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h
@@ -0,0 +1,42 @@
+
+#ifndef LIBSTATIC_EXPORT_H
+#define LIBSTATIC_EXPORT_H
+
+#ifdef LIBSTATIC_STATIC_DEFINE
+#  define LIBSTATIC_EXPORT
+#  define LIBSTATIC_NO_EXPORT
+#else
+#  ifndef LIBSTATIC_EXPORT
+#    ifdef libstatic_EXPORTS
+        /* We are building this library */
+#      define LIBSTATIC_EXPORT
+#    else
+        /* We are using this library */
+#      define LIBSTATIC_EXPORT
+#    endif
+#  endif
+
+#  ifndef LIBSTATIC_NO_EXPORT
+#    define LIBSTATIC_NO_EXPORT
+#  endif
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED
+#  define LIBSTATIC_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_EXPORT
+#  define LIBSTATIC_DEPRECATED_EXPORT LIBSTATIC_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_NO_EXPORT
+#  define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+#  ifndef LIBSTATIC_NO_DEPRECATED
+#    define LIBSTATIC_NO_DEPRECATED
+#  endif
+#endif
+
+#endif /* LIBSTATIC_EXPORT_H */
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h
index dac4fda..3ba2d2e 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h
@@ -22,7 +22,7 @@
 #endif
 
 #ifndef LIBSHARED_DEPRECATED
-#  define LIBSHARED_DEPRECATED __attribute__ ((__deprecated__))
+#  define LIBSHARED_DEPRECATED __declspec(deprecated)
 #endif
 
 #ifndef LIBSHARED_DEPRECATED_EXPORT
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h
index b6e2a4a..3c7e093 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h
@@ -22,7 +22,7 @@
 #endif
 
 #ifndef LIBSTATIC_DEPRECATED
-#  define LIBSTATIC_DEPRECATED __attribute__ ((__deprecated__))
+#  define LIBSTATIC_DEPRECATED __declspec(deprecated)
 #endif
 
 #ifndef LIBSTATIC_DEPRECATED_EXPORT
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h
index dac4fda..3ba2d2e 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h
@@ -22,7 +22,7 @@
 #endif
 
 #ifndef LIBSHARED_DEPRECATED
-#  define LIBSHARED_DEPRECATED __attribute__ ((__deprecated__))
+#  define LIBSHARED_DEPRECATED __declspec(deprecated)
 #endif
 
 #ifndef LIBSHARED_DEPRECATED_EXPORT
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h
index b6e2a4a..3c7e093 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h
@@ -22,7 +22,7 @@
 #endif
 
 #ifndef LIBSTATIC_DEPRECATED
-#  define LIBSTATIC_DEPRECATED __attribute__ ((__deprecated__))
+#  define LIBSTATIC_DEPRECATED __declspec(deprecated)
 #endif
 
 #ifndef LIBSTATIC_DEPRECATED_EXPORT
diff --git a/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive-stderr.txt
new file mode 100644
index 0000000..3ccd101
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive.cmake b/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive.cmake
new file mode 100644
index 0000000..f0853ee
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 NEW)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive-stderr.txt
new file mode 100644
index 0000000..3ccd101
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive.cmake b/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive.cmake
new file mode 100644
index 0000000..f0853ee
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 NEW)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive-stderr.txt
new file mode 100644
index 0000000..3274b82
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive.cmake b/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive.cmake
new file mode 100644
index 0000000..f1560a9
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 OLD)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive-stderr.txt
new file mode 100644
index 0000000..c02a797
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive.cmake b/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive.cmake
new file mode 100644
index 0000000..f1560a9
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 OLD)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive-stderr.txt
new file mode 100644
index 0000000..3540dc9
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive-stderr.txt
@@ -0,0 +1,63 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
++
+CMake Warning \(dev\) at CMP0144-common.cmake:[0-9]+ \(find_package\):
+  Policy CMP0144 is not set: find_package uses upper-case <PACKAGENAME>_ROOT
+  variables.  Run "cmake --help-policy CMP0144" for policy details\.  Use the
+  cmake_policy command to set the policy and suppress this warning\.
+
+  CMake variable FOO_ROOT is set to:
+
+    [^
+]*/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root
+
+  For compatibility, find_package is ignoring the variable, but code in a
+  \.cmake module might still use it\.
+Call Stack \(most recent call first\):
+  CMP0144-common.cmake:[0-9]+ \(RunTestCase\)
+  CMP0144-WARN-CaseInsensitive.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive.cmake b/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive.cmake
new file mode 100644
index 0000000..10f6b66
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+# (do not set CMP0144)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed-stderr.txt b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed-stderr.txt
new file mode 100644
index 0000000..3ccd101
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed.cmake b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed.cmake
new file mode 100644
index 0000000..10f6b66
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+# (do not set CMP0144)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-stderr.txt
new file mode 100644
index 0000000..b828f05
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-stderr.txt
@@ -0,0 +1,68 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
++
+CMake Warning \(dev\) at CMP0144-common.cmake:[0-9]+ \(find_package\):
+  Policy CMP0144 is not set: find_package uses upper-case <PACKAGENAME>_ROOT
+  variables.  Run "cmake --help-policy CMP0144" for policy details\.  Use the
+  cmake_policy command to set the policy and suppress this warning\.
+
+  CMake variable FOO_ROOT is set to:
+
+    [^
+]*/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root
+
+  Environment variable FOO_ROOT is set to:
+
+    [^
+]*/Tests/RunCMake/find_package/PackageRoot/foo/env_root
+
+  For compatibility, find_package is ignoring the variable, but code in a
+  \.cmake module might still use it\.
+Call Stack \(most recent call first\):
+  CMP0144-common.cmake:[0-9]+ \(RunTestCase\)
+  CMP0144-WARN-CaseSensitive.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive.cmake b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive.cmake
new file mode 100644
index 0000000..10f6b66
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+# (do not set CMP0144)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-common.cmake b/Tests/RunCMake/find_package/CMP0144-common.cmake
new file mode 100644
index 0000000..58eccca
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-common.cmake
@@ -0,0 +1,78 @@
+# (includer selects CMP0144)
+list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+
+function(PrintPath label path)
+  string(REPLACE "${PackageRoot_BASE}" "<base>" out "${path}")
+  message("${label} ${out}")
+endfunction()
+
+macro(RunTestCase)
+  message("----------")
+  PrintPath("FOO_ROOT     :" "'${FOO_ROOT}'")
+  PrintPath("ENV{FOO_ROOT}:" "'$ENV{FOO_ROOT}'")
+  message("")
+
+  find_package(Foo)
+  message("find_package(Foo)")
+  PrintPath("FOO_TEST_FILE_FOO:" "${FOO_TEST_FILE_FOO}")
+  PrintPath("FOO_TEST_FILE_ZOT:" "${FOO_TEST_FILE_ZOT}")
+  PrintPath("FOO_TEST_PATH_FOO:" "${FOO_TEST_PATH_FOO}")
+  PrintPath("FOO_TEST_PATH_ZOT:" "${FOO_TEST_PATH_ZOT}")
+  PrintPath("FOO_TEST_PROG_FOO:" "${FOO_TEST_PROG_FOO}")
+  message("")
+
+  unset(FOO_ROOT)
+  unset(ENV{FOO_ROOT})
+  if(NOT CMAKE_HOST_WIN32)
+    unset(Foo_ROOT)
+    unset(ENV{Foo_ROOT})
+  endif()
+  unset(FOO_TEST_FILE_FOO)
+  unset(FOO_TEST_FILE_ZOT)
+  unset(FOO_TEST_PATH_FOO)
+  unset(FOO_TEST_PATH_ZOT)
+  unset(FOO_TEST_PROG_FOO)
+  unset(FOO_TEST_FILE_FOO CACHE)
+  unset(FOO_TEST_FILE_ZOT CACHE)
+  unset(FOO_TEST_PATH_FOO CACHE)
+  unset(FOO_TEST_PATH_ZOT CACHE)
+  unset(FOO_TEST_PROG_FOO CACHE)
+endmacro()
+
+RunTestCase()
+
+set(FOO_ROOT      ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{FOO_ROOT} ${PackageRoot_BASE}/foo/env_root)
+if(RunCMake_TEST MATCHES "CaseSensitive")
+  if(RunCMake_TEST STREQUAL "CMP0144-WARN-CaseSensitive-Mixed")
+    set(Foo_ROOT      "${FOO_ROOT}")
+    set(ENV{Foo_ROOT} "$ENV{FOO_ROOT}")
+  else()
+    set(Foo_ROOT      ${PackageRoot_BASE}/does_not_exist)
+    set(ENV{Foo_ROOT} ${PackageRoot_BASE}/does_not_exist)
+  endif()
+endif()
+RunTestCase()
+
+set(FOO_ROOT      ${PackageRoot_BASE}/foo/cmake_root)
+if(RunCMake_TEST MATCHES "CaseSensitive")
+  if(RunCMake_TEST STREQUAL "CMP0144-WARN-CaseSensitive-Mixed")
+    set(Foo_ROOT      "${FOO_ROOT}")
+  else()
+    set(Foo_ROOT      ${PackageRoot_BASE}/does_not_exist)
+  endif()
+endif()
+RunTestCase()
+
+set(ENV{FOO_ROOT} ${PackageRoot_BASE}/foo/env_root)
+if(RunCMake_TEST MATCHES "CaseSensitive")
+  if(RunCMake_TEST STREQUAL "CMP0144-WARN-CaseSensitive-Mixed")
+    set(ENV{Foo_ROOT} "$ENV{FOO_ROOT}")
+  else()
+    set(ENV{Foo_ROOT} ${PackageRoot_BASE}/does_not_exist)
+  endif()
+endif()
+RunTestCase()
+
+message("----------")
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index fa41fc1..e7e3a0b 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -55,6 +55,17 @@
 run_cmake(REGISTRY_VIEW-wrong-view)
 run_cmake(REGISTRY_VIEW-propagated)
 
+if(CMAKE_HOST_WIN32)
+  run_cmake(CMP0144-WARN-CaseInsensitive)
+  run_cmake(CMP0144-OLD-CaseInsensitive)
+  run_cmake(CMP0144-NEW-CaseInsensitive)
+else()
+  run_cmake(CMP0144-WARN-CaseSensitive)
+  run_cmake(CMP0144-WARN-CaseSensitive-Mixed)
+  run_cmake(CMP0144-OLD-CaseSensitive)
+  run_cmake(CMP0144-NEW-CaseSensitive)
+endif()
+
 file(
     GLOB SearchPaths_TEST_CASE_LIST
     LIST_DIRECTORIES TRUE