diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5f00ea1439fc6faf693272fa2203c1dfe021abb..afddc85cd764e782d35e569b6570a826e4e93e0f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -106,6 +106,12 @@ if(BORNAGAIN_DEBUG_OPTIMIZATION)
   include(commons/DebugOptimization)
 endif()
 
+## recurse into the given subdirectories
+
+# BornAgain components are build as separate shared libraries
+set(CoreComponents "Fit;Core")
+set(AllComponents "${CoreComponents};GUI")
+
 # code analysis
 include(BornAgain/LineLength)
 if(BORNAGAIN_COVERAGE)
@@ -113,18 +119,7 @@ if(BORNAGAIN_COVERAGE)
   include(BornAgain/Coverage)
 endif()
 
-## recurse into the given subdirectories
-
-if(BORNAGAIN_USERMANUAL)
-    add_subdirectory(Doc/UserManual)
-endif()
-if(CONFIGURE_MANPAGE)
-    add_subdirectory(Doc/man)
-endif()
-if(CONFIGURE_DOXY)
-    add_subdirectory(Doc/Doxygen)
-endif()
-
+# third-party code
 add_subdirectory(ThirdParty/common)
 add_subdirectory(ThirdParty/Fit)
 add_subdirectory(ThirdParty/Core)
@@ -132,30 +127,46 @@ if(BORNAGAIN_GUI)
     add_subdirectory(ThirdParty/GUI)
 endif()
 
+# from here on our own code, occasionally scrutinized by clang-tidy
 if(BORNAGAIN_TIDY)
     set(CMAKE_CXX_CLANG_TIDY "clang-tidy") # has effect only if compiler is clang; uses .clang-tidy
 endif()
 
-add_subdirectory(Fit)
+# core components
+foreach(lib ${CoreComponents})
+    add_subdirectory(${lib})
+endforeach()
 if(BORNAGAIN_PYTHON)
     add_dependencies(BornAgainFit swig_runtime)
 endif()
-add_subdirectory(Tests/UnitTests/Fit)
 
-add_subdirectory(Core)
+# core tests
+add_subdirectory(Tests/UnitTests/Fit)
 add_subdirectory(Tests/UnitTests/Core)
 add_subdirectory(Tests/UnitTests/Numeric)
 add_subdirectory(Tests/Performance/Core)
 
+# GUI
 if(BORNAGAIN_GUI)
     add_subdirectory(GUI)
     add_subdirectory(Tests/UnitTests/GUI)
     add_subdirectory(Tests/Performance/GUI)
 endif()
 
-# functional tests (ctest)
+# TODO: split Core / GUI
 add_subdirectory(Tests/Functional)
 
+# documentation
+if(BORNAGAIN_USERMANUAL)
+    add_subdirectory(Doc/UserManual)
+endif()
+if(CONFIGURE_MANPAGE)
+    add_subdirectory(Doc/man)
+endif()
+if(CONFIGURE_DOXY)
+    add_subdirectory(Doc/Doxygen)
+endif()
+
 # after-install message
 add_subdirectory(cmake)
 
diff --git a/auto/Wrap/doxygenCore.i b/auto/Wrap/doxygenCore.i
index 9217eac640840aa23dadc91b8ff336aaa51efb6c..4142d83265c1e11f7fa798992a9cd2a0682fb805 100644
--- a/auto/Wrap/doxygenCore.i
+++ b/auto/Wrap/doxygenCore.i
@@ -16757,7 +16757,7 @@ C++ includes: ZLimits.h
 Returns true if two doubles agree within machine epsilon. 
 ";
 
-%feature("docstring")  algo::min_value "bool Iterator double algo::min_value(const Iterator &begin, const Iterator &end, const Evaluator &evaluate)
+%feature("docstring")  algo::min_value "double algo::min_value(const Iterator &begin, const Iterator &end, const Evaluator &evaluate)
 
 Returns the minimum value of function evaluate as applied to the elements of an iterator range. 
 ";
diff --git a/auto/Wrap/doxygenFit.i b/auto/Wrap/doxygenFit.i
index 991d3930171e23828a4a42bd98f6edd4677c8333..f50d330c0ed6af0e9fab355f5bfd75b082f79939 100644
--- a/auto/Wrap/doxygenFit.i
+++ b/auto/Wrap/doxygenFit.i
@@ -1427,11 +1427,6 @@ Returns horizontal line of 80 characters length with section name in it.
 
 
 // File: namespaceNumeric.xml
-%feature("docstring")  Numeric::AreAlmostEqual "bool Numeric::AreAlmostEqual(double a, double b, double tolerance)
-
-Returns true if two doubles agree within epsilon*tolerance. 
-";
-
 %feature("docstring")  Numeric::GetAbsoluteDifference "double Numeric::GetAbsoluteDifference(double a, double b)
 
 Returns the absolute value of the difference between a and b. 
diff --git a/cmake/BornAgain/LineLength.cmake b/cmake/BornAgain/LineLength.cmake
index a35f95e78b1c2cdfd59a66f06c1ac8374e5734dc..8c5977e9c4fc22f86c42ed80b947601b330c5228 100644
--- a/cmake/BornAgain/LineLength.cmake
+++ b/cmake/BornAgain/LineLength.cmake
@@ -3,7 +3,7 @@ set(WEB_LEN_LIM 85) # maximum line length of code for display in web docs
 
 if(NOT MSVC)
 
-    foreach(dir "Core" "Fit" "GUI")
+    foreach(dir ${AllComponents})
         file(GLOB_RECURSE src1 ${dir}/*.cpp)
         file(GLOB_RECURSE src2 ${dir}/*.h)
         add_test(NAME "LineLength.Cpp.${dir}"
@@ -12,7 +12,7 @@ if(NOT MSVC)
             ${src1} ${src2})
     endforeach()
 
-    foreach(dir "Core" "Fit" "GUI")
+    foreach(dir ${AllComponents})
         file(GLOB_RECURSE src1 ${dir}/*CMakeLists.txt)
         add_test(NAME "LineLength.CMake.${dir}"
             COMMAND ${Python3_EXECUTABLE}