diff --git a/.clang-format b/.clang-format
index 376297d1ffe1401697f6298e32b0e254f100d3e2..c8747035cd5d83f4157652eba6f25472ad460ac4 100644
--- a/.clang-format
+++ b/.clang-format
@@ -64,18 +64,18 @@ IncludeBlocks: 'Regroup'
 IncludeCategories:
   - Regex:           '^<ChimeraTK/'
     Priority:        2
-    SortPriority:    2
     CaseSensitive:   true
   - Regex:           '^<boost/'
-    Priority:        3
-    SortPriority:    3
-    CaseSensitive:   true
-  - Regex:           '<[[:alnum:].]+>'
     Priority:        4
-    SortPriority:        4
-  - Regex:           '.*'
+    CaseSensitive:   true
+  - Regex:           '^<.*/'
+    Priority:        3
+  - Regex:           '^".*"'
     Priority:        1
-    SortPriority:    0
+  - Regex:           '^<[[:alnum:]_]+>'
+    Priority:        6
+  - Regex:           '^<.*>'
+    Priority:        5
 SortUsingDeclarations: 'false'
 SpaceAfterCStyleCast: 'false'
 SpaceAfterTemplateKeyword: 'false'
diff --git a/cmake/Doxyfile.in b/cmake/Doxyfile.in
index a48cbecfe239b422ded327a94bf21b1952d1b199..6a7d17b61a18aa2782d17637f06bc283e40fb20c 100644
--- a/cmake/Doxyfile.in
+++ b/cmake/Doxyfile.in
@@ -59,10 +59,7 @@ GENERATE_LATEX         = NO
 LATEX_CMD_NAME         = latex
 EXTERNAL_GROUPS        = NO
 EXTERNAL_PAGES         = NO
-DOT_NUM_THREADS        = 4
 TEMPLATE_RELATIONS     = YES
-CALL_GRAPH             = YES
-CALLER_GRAPH           = YES
 DOT_IMAGE_FORMAT       = svg
 INTERACTIVE_SVG        = YES
 DOT_GRAPH_MAX_NODES    = 120
diff --git a/cmake/create_cmake_config_files.cmake b/cmake/create_cmake_config_files.cmake
index 9be96d82b9b4d556c1ea61b985873812fe7bb591..14ac975aebb7781222a3a6d08a4edd87febd3223 100644
--- a/cmake/create_cmake_config_files.cmake
+++ b/cmake/create_cmake_config_files.cmake
@@ -1,23 +1,23 @@
-#######################################################################################################################
+# ######################################################################################################################
 # create_cmake_config_files.cmake
 #
 # Create the Find${PROJECT_NAME}.cmake cmake macro and the ${PROJECT_NAME}-config shell script and installs them.
 #
 # Expects the following input variables:
-#   ${PROJECT_NAME}_SOVERSION - version of the .so library file (or just MAJOR.MINOR without the patch level)
-#   ${PROJECT_NAME}_MEXFLAGS - (optional) mex compiler flags
+# ${PROJECT_NAME}_SOVERSION - version of the .so library file (or just MAJOR.MINOR without the patch level)
+# ${PROJECT_NAME}_MEXFLAGS - (optional) mex compiler flags
 #
 # and only required, if project does not yet provide cmake-export:
-#   ${PROJECT_NAME}_INCLUDE_DIRS - list include directories needed when compiling against this project
-#   ${PROJECT_NAME}_LIBRARY_DIRS - list of library directories needed when linking against this project
-#   ${PROJECT_NAME}_LIBRARIES - list of additional libraries needed when linking against this project. The library
-#                               provided by the project will be added automatically
-#   ${PROJECT_NAME}_CXX_FLAGS - list of additional C++ compiler flags needed when compiling against this project
-#   ${PROJECT_NAME}_LINKER_FLAGS - list of additional linker flags needed when linking against this project
+# ${PROJECT_NAME}_INCLUDE_DIRS - list include directories needed when compiling against this project
+# ${PROJECT_NAME}_LIBRARY_DIRS - list of library directories needed when linking against this project
+# ${PROJECT_NAME}_LIBRARIES - list of additional libraries needed when linking against this project. The library
+# provided by the project will be added automatically
+# ${PROJECT_NAME}_CXX_FLAGS - list of additional C++ compiler flags needed when compiling against this project
+# ${PROJECT_NAME}_LINKER_FLAGS - list of additional linker flags needed when linking against this project
 #
-#######################################################################################################################
+# ######################################################################################################################
 
-#######################################################################################################################
+# ######################################################################################################################
 #
 # IMPORTANT NOTE:
 #
@@ -27,12 +27,13 @@
 # If you have modified this file inside a project despite this warning, make sure to cherry-pick all your changes
 # into the project-template repository immediately.
 #
-#######################################################################################################################
+# ######################################################################################################################
 
 macro(handleGeneratorExprs var)
     # Unfortunately, I do not see a solution for correct generator expression handling by cmake. So instead, do some simple replacements.
     # $<INSTALL_INTERFACE:path> defines path relative to install location.
     string(REGEX REPLACE "\\$<INSTALL_INTERFACE:([^ ;]*)>" "${CMAKE_INSTALL_PREFIX}/\\1" ${var} "${${var}}")
+
     # remove any other generator expression
     string(REGEX REPLACE "\\$<.*>" "" ${var} "${${var}}")
 endmacro()
@@ -41,25 +42,32 @@ endmacro()
 # arg is allowed to be space-separated or ;-separated list
 macro(appendToList list arg)
     string(REPLACE " " ";" appendToList_args "${arg}")
+
     foreach(item ${appendToList_args})
         handleGeneratorExprs(item)
         string(FIND " ${${list}} " " ${item} " appendToList_pos)
-        if (${appendToList_pos} EQUAL -1)
+
+        if(${appendToList_pos} EQUAL -1)
             string(APPEND ${list} " ${item}")
+
             # strip leading spaces since they might cause problems
             string(REGEX REPLACE "^[ \t]+" "" ${list} "${${list}}")
         endif()
     endforeach()
 endmacro()
+
 # prepend element-wise to (space-separated!) list, but only if not yet existing
 # arg is allowed to be space-separated or ;-separated list
 macro(prependToList list arg)
     string(REPLACE " " ";" prependToList_args "${arg}")
+
     foreach(item ${prependToList_args})
         handleGeneratorExprs(item)
         string(FIND " ${${list}} " " ${item} " prependToList_pos)
-        if (${prependToList_pos} EQUAL -1)
+
+        if(${prependToList_pos} EQUAL -1)
             string(PREPEND ${list} "${item} ")
+
             # strip trailing spaces since they might cause problems
             string(REGEX REPLACE "[ \t]+$" "" ${list} "${${list}}")
         endif()
@@ -69,7 +77,9 @@ endmacro()
 # this defines architecture-dependent ${CMAKE_INSTALL_LIBDIR}
 include(GNUInstallDirs)
 
-# for lib, which might be lib File or linker flag or imported target, 
+include(cmake/get_imported_target_cxx_standard.cmake)
+
+# for lib, which might be lib File or linker flag or imported target,
 # puts recursively resolved library list into ${linkLibs}, which will contain a library file list
 # and recursively resolve link flags into ${linkFlags}
 # Note, since some projects ignore libDirs, we put them also into linkFlags.
@@ -79,19 +89,22 @@ function(resolveImportedLib lib linkLibs linkFlags libDirs incDirs cxxFlags)
     set(libDirs1 "")
     set(incDirs1 "")
     set(cxxFlags1 "")
-    if(lib MATCHES "/")         # library name contains slashes: link against the a file path name
+
+    if(lib MATCHES "/") # library name contains slashes: link against the a file path name
         appendToList(linkLibs1 "${lib}")
     elseif(lib MATCHES "^[ \t]*-l")
         # library name does not contain slashes but already the -l option: directly quote it
         # although technically a linker flag, we put it to lib list because order matters sometimes
         appendToList(linkLibs1 "${lib}")
-    elseif(lib MATCHES "::")    # library name is an imported target - we need to resolve it for Makefiles
-        if (NOT TARGET ${lib})
+    elseif(lib MATCHES "::") # library name is an imported target - we need to resolve it for Makefiles
+        if(NOT TARGET ${lib})
             message(FATAL_ERROR "dependency ${lib} not available as target, maybe find_package was forgotten?")
         endif()
+
         get_target_property(_libraryType ${lib} TYPE)
+
         # boost exports appear as UNKNOWN_LIBRARY but also have target location
-        if ((${_libraryType} MATCHES SHARED_LIBRARY) OR (${_libraryType} MATCHES STATIC_LIBRARY) OR (${_libraryType} MATCHES UNKNOWN_LIBRARY))
+        if((${_libraryType} MATCHES SHARED_LIBRARY) OR(${_libraryType} MATCHES STATIC_LIBRARY) OR(${_libraryType} MATCHES UNKNOWN_LIBRARY))
             if(";${lib};" MATCHES ";.*::${PROJECT_NAME};")
                 # We cannot find target library location of this project via target properties at this point.
                 # Therefore, we simply assume that by convention, all our libs are installed into ${CMAKE_INSTALL_PREFIX}/lib.
@@ -101,17 +114,22 @@ function(resolveImportedLib lib linkLibs linkFlags libDirs incDirs cxxFlags)
                 appendToList(linkLibs1 "-l${PROJECT_NAME}")
             else()
                 get_property(lib_loc TARGET ${lib} PROPERTY LOCATION)
-                #message("imported target ${lib} is actual library. location=${lib_loc}")
+
+                # message("imported target ${lib} is actual library. location=${lib_loc}")
                 appendToList(linkLibs1 "${lib_loc}")
             endif()
         endif()
+
         get_target_property(_linkLibs ${lib} INTERFACE_LINK_LIBRARIES)
-        if (NOT "${_linkLibs}" MATCHES "-NOTFOUND")
+
+        if(NOT "${_linkLibs}" MATCHES "-NOTFOUND")
             message(VERBOSE "imported target ${lib} is interface, recursively go over its interface requirements ${_linkLibs}")
+
             foreach(_lib ${_linkLibs})
-                if (${lib} STREQUAL ${_lib})
+                if(${lib} STREQUAL ${_lib})
                     message(FATAL_ERROR "self-reference in dependencies of ${_lib}! Aborting recursion.")
                 endif()
+
                 resolveImportedLib(${_lib} linkLibs2 linkFlags2 libDirs2 incDirs2 cxxFlags2)
                 appendToList(linkLibs1 "${linkLibs2}")
                 appendToList(linkFlags1 "${linkFlags2}")
@@ -122,25 +140,37 @@ function(resolveImportedLib lib linkLibs linkFlags libDirs incDirs cxxFlags)
         endif()
 
         get_target_property(_incDirs ${lib} INTERFACE_INCLUDE_DIRECTORIES)
-        if (_incDirs)
+
+        if(_incDirs)
             appendToList(incDirs1 "${_incDirs}")
         endif()
+
         get_target_property(_cxxFlags ${lib} INTERFACE_COMPILE_OPTIONS)
-        if (_cxxFlags)
+
+        if(_cxxFlags)
             appendToList(cxxFlags1 "${_cxxFlags}")
         endif()
+
         get_target_property(_cxxFlags ${lib} INTERFACE_COMPILE_DEFINITIONS)
-        if (_cxxFlags)
+
+        if(_cxxFlags)
             foreach(flag ${_cxxFlags})
                 appendToList(cxxFlags1 "-D${flag}")
             endforeach()
         endif()
+
+        get_imported_target_cxx_standard(${lib} _cxxStandardFlag)
+        appendToList(cxxFlags1 "${_cxxStandardFlag}")
+
         get_target_property(_linkFlags ${lib} INTERFACE_LINK_OPTIONS)
-        if (_linkFlags)
+
+        if(_linkFlags)
             appendToList(linkFlags1 "${_linkFlags}")
         endif()
+
         get_target_property(_linkDirs ${lib} INTERFACE_LINK_DIRECTORES)
-        if (_linkDirs)
+
+        if(_linkDirs)
             foreach(flag ${_linkDirs})
                 handleGeneratorExprs(flag)
                 appendToList(linkFlags1 "-L${flag}")
@@ -151,11 +181,12 @@ function(resolveImportedLib lib linkLibs linkFlags libDirs incDirs cxxFlags)
     else()
         # link against library with -l option
         handleGeneratorExprs(lib)
+
         # although technically a linker flag, we put it to lib list because for some linker flags, it is important
         # that they come before libs
         appendToList(linkLibs1 "-l${lib}")
     endif()
-    
+
     set(${linkLibs} "${linkLibs1}" PARENT_SCOPE)
     set(${linkFlags} "${linkFlags1}" PARENT_SCOPE)
     set(${libDirs} "${libDirs1}" PARENT_SCOPE)
@@ -163,13 +194,12 @@ function(resolveImportedLib lib linkLibs linkFlags libDirs incDirs cxxFlags)
     set(${cxxFlags} "${cxxFlags1}" PARENT_SCOPE)
 endfunction()
 
-
 # if we already have cmake-exports for this project:
 # sets the vars ${PROJECT_NAME}_INCLUDE_DIRS, ${PROJECT_NAME}_CXX_FLAGS, ${PROJECT_NAME}_LIBRARY_DIRS,
 # ${PROJECT_NAME}_LINKER_FLAGS, and ${PROJECT_NAME}_LIBRARIES
 # so that compatibility layer is provided automatically.
 if(${PROVIDES_EXPORTED_TARGETS})
-    #  imported targets should be namespaced, so define namespaced alias
+    # imported targets should be namespaced, so define namespaced alias
     add_library(ChimeraTK::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
 
     resolveImportedLib(ChimeraTK::${PROJECT_NAME} linkLibs linkFlags libDirs incDirs cxxFlags)
@@ -181,11 +211,11 @@ if(${PROVIDES_EXPORTED_TARGETS})
     message(VERBOSE "  old cxxflags: ${${PROJECT_NAME}_CXX_FLAGS}")
     message(VERBOSE "  old incDirs: ${${PROJECT_NAME}_INCLUDE_DIRS}")
     message(VERBOSE "  old libDirs: ${${PROJECT_NAME}_LIBRARY_DIRS}")
-    set(${PROJECT_NAME}_INCLUDE_DIRS "${incDirs}" )
-    set(${PROJECT_NAME}_LIBRARY_DIRS "${libDirs}" )
-    set(${PROJECT_NAME}_LIBRARIES "${linkLibs}" )
-    set(${PROJECT_NAME}_CXX_FLAGS "${cxxFlags}" )
-    set(${PROJECT_NAME}_LINKER_FLAGS "${linkFlags}" )
+    set(${PROJECT_NAME}_INCLUDE_DIRS "${incDirs}")
+    set(${PROJECT_NAME}_LIBRARY_DIRS "${libDirs}")
+    set(${PROJECT_NAME}_LIBRARIES "${linkLibs}")
+    set(${PROJECT_NAME}_CXX_FLAGS "${cxxFlags}")
+    set(${PROJECT_NAME}_LINKER_FLAGS "${linkFlags}")
     message(VERBOSE "will be overwritten by automatically generated compatibility layer from cmake-exports,")
     message(VERBOSE "  new libset: ${${PROJECT_NAME}_LIBRARIES}")
     message(VERBOSE "  new linkflags: ${${PROJECT_NAME}_LINKER_FLAGS}")
@@ -198,16 +228,18 @@ endif()
 set(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "${${PROJECT_NAME}_CXX_FLAGS}")
 
 string(REPLACE " " ";" LIST "${${PROJECT_NAME}_INCLUDE_DIRS}")
+
 foreach(INCLUDE_DIR ${LIST})
-  appendToList(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "-I${INCLUDE_DIR}")
+    appendToList(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "-I${INCLUDE_DIR}")
 endforeach()
 
 # some old code still might call linker flags _LINK_FLAGS, also include that
 appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${${PROJECT_NAME}_LINK_FLAGS}")
 
 string(REPLACE " " ";" LIST "${${PROJECT_NAME}_LIBRARY_DIRS}")
+
 foreach(LIBRARY_DIR ${LIST})
-  appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "-L${LIBRARY_DIR}")
+    appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "-L${LIBRARY_DIR}")
 endforeach()
 
 if(${PROVIDES_EXPORTED_TARGETS})
@@ -216,20 +248,23 @@ if(${PROVIDES_EXPORTED_TARGETS})
 else()
     # recursive resolution of linker flags is necessary, since dependencies could contain imported targets
     string(REPLACE " " ";" LIST "${PROJECT_NAME} ${${PROJECT_NAME}_LIBRARIES}")
+
     foreach(LIBRARY ${LIST})
         resolveImportedLib(${LIBRARY} linkLibs linkFlags libDirs incDirs cxxFlags)
-        
+
         appendToList(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "${cxxFlags}")
-        
+
         string(REPLACE " " ";" LIST "${incDirs}")
+
         foreach(INCLUDE_DIR ${LIST})
             appendToList(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "-I${INCLUDE_DIR}")
         endforeach()
-        
+
         # for some linker flags, it is important that they come before the libs
         prependToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${linkFlags}")
         appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${linkLibs}")
         string(REPLACE " " ";" LIST "${libDirs}")
+
         foreach(LIBRARY_DIR ${LIST})
             appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "-L${LIBRARY_DIR}")
         endforeach()
@@ -237,37 +272,40 @@ else()
 endif()
 
 set(${PROJECT_NAME}_PUBLIC_DEPENDENCIES_L "")
+
 foreach(DEPENDENCY ${${PROJECT_NAME}_PUBLIC_DEPENDENCIES})
-    # we only care about required dependencies: if some lib has an optional dependency and is built against it 
+    # we only care about required dependencies: if some lib has an optional dependency and is built against it
     # after it has been found, the dependency became mandatory for downstream libs.
     # Note, keyword REQUIRED as not according to spec but it works...
     string(APPEND ${PROJECT_NAME}_PUBLIC_DEPENDENCIES_L "find_package(${DEPENDENCY} REQUIRED)\n")
 endforeach()
 
 if(TARGET ${PROJECT_NAME})
-  # set _HAS_LIBRARY only if we have a true library, interface libraries (introduced for imported targets,
-  #  e.g. header-only library) don't count.
-  get_target_property(targetLoc ${PROJECT_NAME} TYPE)
-  if(NOT "INTERFACE_LIBRARY" MATCHES "${targetLoc}")
-    set(${PROJECT_NAME}_HAS_LIBRARY 1)
-  endif()  
+    # set _HAS_LIBRARY only if we have a true library, interface libraries (introduced for imported targets,
+    # e.g. header-only library) don't count.
+    get_target_property(targetLoc ${PROJECT_NAME} TYPE)
+
+    if(NOT "INTERFACE_LIBRARY" MATCHES "${targetLoc}")
+        set(${PROJECT_NAME}_HAS_LIBRARY 1)
+    endif()
 else()
-  set(${PROJECT_NAME}_HAS_LIBRARY 0)
+    set(${PROJECT_NAME}_HAS_LIBRARY 0)
 endif()
 
-
 # we have nested @-statements, so we have to parse twice:
 
 # create the cmake find_package configuration file
 set(PACKAGE_INIT "@PACKAGE_INIT@") # replacement handled later, so leave untouched here
 cmake_policy(SET CMP0053 NEW) # less warnings about irrelevant stuff in comments
 configure_file(cmake/PROJECT_NAMEConfig.cmake.in.in "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake.in" @ONLY)
+
 if(${PROVIDES_EXPORTED_TARGETS})
-    # we will configure later
+# we will configure later
 else()
     set(PACKAGE_INIT "") # required to avoid parse error
     configure_file(${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake.in "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" @ONLY)
 endif()
+
 configure_file(cmake/PROJECT_NAMEConfigVersion.cmake.in.in "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake.in" @ONLY)
 configure_file(${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" @ONLY)
 
@@ -285,24 +323,24 @@ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config DESTINATION
 # install configuration file for pkgconfig
 install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc" DESTINATION share/pkgconfig COMPONENT dev)
 
-
 if(${PROVIDES_EXPORTED_TARGETS})
-    #  imported targets should be namespaced, so define namespaced alias
+    # imported targets should be namespaced, so define namespaced alias
     add_library(ChimeraTK::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
 
     # generate and install export file
     install(EXPORT ${PROJECT_NAME}Targets
-            FILE ${PROJECT_NAME}Targets.cmake
-            NAMESPACE ChimeraTK::
-            DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+        FILE ${PROJECT_NAME}Targets.cmake
+        NAMESPACE ChimeraTK::
+        DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
     )
 
     include(CMakePackageConfigHelpers)
+
     # create config file
     # although @ONLY arg is not supported, this behaves in the same way.
     configure_package_config_file("${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
-      "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
-      INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+        "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+        INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
     )
 
     # remove any previously installed share/cmake-xx/Modules/Find<ProjectName>.cmake from this project since it does not harmonize with new Config
@@ -310,16 +348,15 @@ if(${PROVIDES_EXPORTED_TARGETS})
     install(CODE "FILE(REMOVE ${CMAKE_INSTALL_PREFIX}/${fileToRemove})")
 else()
     # install same cmake configuration file another time into the Modules cmake subdirectory for compatibility reasons
-    # We do this only if we did not move yet to exported target, since it does not harmonize 
+    # We do this only if we did not move yet to exported target, since it does not harmonize
     install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
-      DESTINATION share/cmake-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}/Modules RENAME Find${PROJECT_NAME}.cmake COMPONENT dev)
-
+        DESTINATION share/cmake-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}/Modules RENAME Find${PROJECT_NAME}.cmake COMPONENT dev)
 endif()
 
 # install cmake find_package configuration file
 install(FILES
-          "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
-          "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
-        DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
-        COMPONENT dev
+    "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+    "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+    COMPONENT dev
 )
diff --git a/cmake/get_imported_target_cxx_standard.cmake b/cmake/get_imported_target_cxx_standard.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..715a24dced0bd7f8bb74f4b74a58512a34b9dea0
--- /dev/null
+++ b/cmake/get_imported_target_cxx_standard.cmake
@@ -0,0 +1,72 @@
+# ######################################################################################################################
+# get_imported_target_cxx_standard.cmake
+#
+# Define function to obtain the compiler flag for the C++ standard required by an imported target (defined via
+# target_compile_features()), querying recursively the dependencies as well. If multiple standards are required by
+# different dependencies, the greatest standard will be picked.
+#
+# Usage:
+#
+# get_imported_target_cxx_standard(MyImportedTarget NameOfVariableToPutFlagIn)
+#
+# ######################################################################################################################
+
+# ######################################################################################################################
+#
+# IMPORTANT NOTE:
+#
+# DO NOT MODIFY THIS FILE inside a project. Instead update the project-template repository and pull the change from
+# there. Make sure to keep the file generic, since it will be used by other projects, too.
+#
+# If you have modified this file inside a project despite this warning, make sure to cherry-pick all your changes
+# into the project-template repository immediately.
+#
+# ######################################################################################################################
+
+# Internal helper function
+function(collect_compile_features_recursive target compile_features)
+  get_target_property(features ${target} INTERFACE_COMPILE_FEATURES)
+
+  if(features)
+    foreach(f ${features})
+      list(APPEND ${compile_features} ${f})
+    endforeach()
+  endif()
+
+  get_target_property(deps ${target} INTERFACE_LINK_LIBRARIES)
+
+  foreach(dep ${deps})
+    if(TARGET ${dep})
+      collect_compile_features_recursive(${dep} ${compile_features})
+    endif()
+  endforeach()
+
+  set(${compile_features} ${${compile_features}} PARENT_SCOPE)
+endfunction()
+
+# ######################################################################################################################
+
+# Main function to be called by the user
+function(get_imported_target_cxx_standard target required_standard_flag)
+  collect_compile_features_recursive(${target} my_compile_features)
+
+  set(required_standard 0)
+
+  foreach(feature ${my_compile_features})
+    if(feature MATCHES "cxx_std_([0-9]+)")
+      if(CMAKE_MATCH_1 GREATER required_standard)
+        set(required_standard ${CMAKE_MATCH_1})
+      endif()
+    endif()
+  endforeach()
+
+  if(required_standard GREATER 0)
+    set(flag "-std=c++${required_standard}")
+  else()
+    set(flag "")
+  endif()
+
+  set(${required_standard_flag} ${flag} PARENT_SCOPE)
+endfunction()
+
+# ######################################################################################################################
diff --git a/cmake/version_info_template.h.in b/cmake/version_info_template.h.in
index 7659c54752fd6a342b50129c39ca4af422ca9cbd..5483e2eb7fea621217ce90f6a614725d3c2a2e01 100644
--- a/cmake/version_info_template.h.in
+++ b/cmake/version_info_template.h.in
@@ -6,4 +6,5 @@ namespace ChimeraTK::VersionInfo {
   const int minor{${${PROJECT_NAME}_MINOR_VERSION_INT}};
   const int applicationPatch{${${PROJECT_NAME}_PATCH_VERSION_INT}};
 
+  static constexpr const char * soVersion = "${${PROJECT_NAME}_SOVERSION}";
 } // namespace ChimeraTK::VersionInfo