diff --git a/Core/Computation/ProfileHelper.h b/Core/Computation/ProfileHelper.h
index 6938805e033a4726ed93cefccb36b5942ec75936..849f02b33171104fa3d17fa6dcee7e2b8ffb94b2 100644
--- a/Core/Computation/ProfileHelper.h
+++ b/Core/Computation/ProfileHelper.h
@@ -21,6 +21,8 @@
 #include <utility>
 #include <vector>
 
+class ProcessedSample;
+
 //! Object that can generate the material profile of a sample as a function of depth.
 //!
 //! The generated profile contains the complex SLD for SLD materials and the parameters
@@ -28,8 +30,6 @@
 //!
 //! @ingroup algorithms_internal
 
-class ProcessedSample;
-
 class BA_CORE_API_ ProfileHelper
 {
 public:
diff --git a/Core/Fitting/FitPrintService.h b/Core/Fitting/FitPrintService.h
index 6d799e5a1ab3d40f38c8091bc93287765189bef1..00230a48ccd9e2baaf6631428350f0b35bca0297 100644
--- a/Core/Fitting/FitPrintService.h
+++ b/Core/Fitting/FitPrintService.h
@@ -15,7 +15,7 @@
 #ifndef FITPRINTSERVICE_H
 #define FITPRINTSERVICE_H
 
-#include "TimeInterval.h"
+#include "WallclockTimer.h"
 #include "WinDllMacros.h"
 #include <string>
 
@@ -36,8 +36,8 @@ private:
     std::string parameterString(const FitObjective& objective);
     std::string fitResultString(const FitObjective& objective);
 
-    TimeInterval m_run_time;
-    TimeInterval m_last_call_time;
+    WallclockTimer m_run_time;
+    WallclockTimer m_last_call_time;
 };
 
 #endif
diff --git a/Core/Instrument/RectangularDetector.h b/Core/Instrument/RectangularDetector.h
index 5a788e0b298e9e612b6613b1d0f15e7422c62e98..f6fb098c6fbfee1b7d51f52afeedeb97ea3addf3 100644
--- a/Core/Instrument/RectangularDetector.h
+++ b/Core/Instrument/RectangularDetector.h
@@ -18,7 +18,29 @@
 #include "IDetector2D.h"
 #include "IPixel.h"
 
-class RectangularPixel;
+//! A pixel in a RectangularDetector.
+
+class BA_CORE_API_ RectangularPixel : public IPixel
+{
+public:
+    RectangularPixel(kvector_t corner_pos, kvector_t width, kvector_t height);
+
+    RectangularPixel* clone() const override;
+    RectangularPixel* createZeroSizePixel(double x, double y) const override;
+    kvector_t getK(double x, double y, double wavelength) const override;
+    kvector_t getPosition(double x, double y) const;
+    double getIntegrationFactor(double x, double y) const override;
+    double getSolidAngle() const override;
+
+private:
+    kvector_t normalizeLength(const kvector_t direction, double length) const;
+    double calculateSolidAngle() const;
+    kvector_t m_corner_pos;
+    kvector_t m_width;
+    kvector_t m_height;
+    double m_solid_angle;
+    kvector_t m_normal;
+};
 
 //! A flat rectangular detector with axes and resolution function.
 //! @ingroup detector
@@ -108,26 +130,4 @@ private:
     kvector_t m_v_unit;
 };
 
-class BA_CORE_API_ RectangularPixel : public IPixel
-{
-public:
-    RectangularPixel(kvector_t corner_pos, kvector_t width, kvector_t height);
-
-    RectangularPixel* clone() const override;
-    RectangularPixel* createZeroSizePixel(double x, double y) const override;
-    kvector_t getK(double x, double y, double wavelength) const override;
-    kvector_t getPosition(double x, double y) const;
-    double getIntegrationFactor(double x, double y) const override;
-    double getSolidAngle() const override;
-
-private:
-    kvector_t normalizeLength(const kvector_t direction, double length) const;
-    double calculateSolidAngle() const;
-    kvector_t m_corner_pos;
-    kvector_t m_width;
-    kvector_t m_height;
-    double m_solid_angle;
-    kvector_t m_normal;
-};
-
 #endif // RECTANGULARDETECTOR_H
diff --git a/Core/Instrument/SphericalDetector.h b/Core/Instrument/SphericalDetector.h
index 60c489ea52d14ddb25d84f3df79a38204f8eee64..e999d1b720a98a6bcd8ef07b97fc6eaa61c7e265 100644
--- a/Core/Instrument/SphericalDetector.h
+++ b/Core/Instrument/SphericalDetector.h
@@ -18,8 +18,26 @@
 #include "IDetector2D.h"
 #include "IPixel.h"
 
+//! A pixel in a SphericalDetector
+
+class BA_CORE_API_ SphericalPixel : public IPixel
+{
+public:
+    SphericalPixel(const Bin1D& alpha_bin, const Bin1D& phi_bin);
+
+    SphericalPixel* clone() const override;
+    SphericalPixel* createZeroSizePixel(double x, double y) const override;
+    kvector_t getK(double x, double y, double wavelength) const override;
+    double getIntegrationFactor(double x, double y) const override;
+    double getSolidAngle() const override;
+
+private:
+    double m_alpha, m_phi;
+    double m_dalpha, m_dphi;
+    double m_solid_angle;
+};
+
 //! A spherical detector with axes and resolution function.
-//! SphericalDetector
 //! @ingroup detector
 
 class BA_CORE_API_ SphericalDetector : public IDetector2D
@@ -61,21 +79,4 @@ protected:
     size_t getIndexOfSpecular(const Beam& beam) const override;
 };
 
-class BA_CORE_API_ SphericalPixel : public IPixel
-{
-public:
-    SphericalPixel(const Bin1D& alpha_bin, const Bin1D& phi_bin);
-
-    SphericalPixel* clone() const override;
-    SphericalPixel* createZeroSizePixel(double x, double y) const override;
-    kvector_t getK(double x, double y, double wavelength) const override;
-    double getIntegrationFactor(double x, double y) const override;
-    double getSolidAngle() const override;
-
-private:
-    double m_alpha, m_phi;
-    double m_dalpha, m_dphi;
-    double m_solid_angle;
-};
-
 #endif // SPHERICALDETECTOR_H
diff --git a/Core/Instrument/SampleBuilderNode.cpp b/Core/Multilayer/SampleBuilderNode.cpp
similarity index 100%
rename from Core/Instrument/SampleBuilderNode.cpp
rename to Core/Multilayer/SampleBuilderNode.cpp
diff --git a/Core/Instrument/SampleBuilderNode.h b/Core/Multilayer/SampleBuilderNode.h
similarity index 100%
rename from Core/Instrument/SampleBuilderNode.h
rename to Core/Multilayer/SampleBuilderNode.h
diff --git a/Core/Instrument/SampleProvider.cpp b/Core/Multilayer/SampleProvider.cpp
similarity index 100%
rename from Core/Instrument/SampleProvider.cpp
rename to Core/Multilayer/SampleProvider.cpp
diff --git a/Core/Instrument/SampleProvider.h b/Core/Multilayer/SampleProvider.h
similarity index 100%
rename from Core/Instrument/SampleProvider.h
rename to Core/Multilayer/SampleProvider.h
diff --git a/Core/Parametrization/ParameterDistribution.h b/Core/Parametrization/ParameterDistribution.h
index 8d3c1cd8c4e6ba3dfcbff9c651fdec67664a7aac..94538cdc2e74b49d8887640c047419b2461b4ca8 100644
--- a/Core/Parametrization/ParameterDistribution.h
+++ b/Core/Parametrization/ParameterDistribution.h
@@ -23,6 +23,8 @@
 
 class IDistribution1D;
 
+//! A parametric distribution function, for use with any model parameter.
+
 class BA_CORE_API_ ParameterDistribution : public IParameterized
 {
 public:
diff --git a/Core/Scattering/Rotations.h b/Core/Scattering/Rotations.h
index 59e3cb3dc1560e10d7c392971dc096d124d66644..f0f4ae1d23df5ea5c818e915c5a4974f50c8556c 100644
--- a/Core/Scattering/Rotations.h
+++ b/Core/Scattering/Rotations.h
@@ -46,6 +46,8 @@ BA_CORE_API_ IRotation* createProduct(const IRotation& left, const IRotation& ri
 
 bool IsZRotation(const IRotation& rot);
 
+//! The identity rotation, which leaves everything in place.
+
 class BA_CORE_API_ IdentityRotation : public IRotation
 {
 public:
@@ -61,6 +63,8 @@ public:
     bool isIdentity() const { return true; }
 };
 
+//! A rotation about the x axis.
+
 class BA_CORE_API_ RotationX : public IRotation
 {
 public:
@@ -79,6 +83,8 @@ protected:
     double m_angle;
 };
 
+//! A rotation about the y axis.
+
 class BA_CORE_API_ RotationY : public IRotation
 {
 public:
@@ -97,6 +103,8 @@ protected:
     double m_angle;
 };
 
+//! A rotation about the z axis.
+
 class BA_CORE_API_ RotationZ : public IRotation
 {
 public:
@@ -115,6 +123,8 @@ protected:
     double m_angle;
 };
 
+//! A sequence of rotations about the z-x'-z'' axes.
+
 class BA_CORE_API_ RotationEuler : public IRotation
 {
 public:
diff --git a/Fit/Kernel/Kernel.cpp b/Fit/Kernel/Kernel.cpp
index bf1ed98a8f4074a2fb602f8e2f96292de274a26a..e122a873822a7b72edd498cd1537f4348179177c 100644
--- a/Fit/Kernel/Kernel.cpp
+++ b/Fit/Kernel/Kernel.cpp
@@ -46,15 +46,15 @@ MinimizerResult Kernel::minimize(fcn_scalar_t fcn, const Parameters& parameters)
 {
     setParameters(parameters);
 
-    m_time_interval.start();
+    m_timer.start();
     if (m_minimizer->requiresResiduals())
         throw std::runtime_error(
             "Error in Kernel::minimize: the chosen minimizer requires residuals computation. "
             "Please use FitObjective::evaluate_residuals with this minimizer.");
     auto result = m_minimizer->minimize_scalar(fcn, parameters);
-    m_time_interval.stop();
+    m_timer.stop();
 
-    result.setDuration(m_time_interval.runTime());
+    result.setDuration(m_timer.runTime());
     return result;
 }
 
@@ -62,11 +62,11 @@ MinimizerResult Kernel::minimize(fcn_residual_t fcn, const Parameters& parameter
 {
     setParameters(parameters);
 
-    m_time_interval.start();
+    m_timer.start();
     auto result = m_minimizer->minimize_residual(fcn, parameters);
-    m_time_interval.stop();
+    m_timer.stop();
 
-    result.setDuration(m_time_interval.runTime());
+    result.setDuration(m_timer.runTime());
     return result;
 }
 
diff --git a/Fit/Kernel/Kernel.h b/Fit/Kernel/Kernel.h
index 338232d74d638db8f85614e967630b67db1cea86..7dadf939f673a3c2a294b7f4c28cb092659a84c6 100644
--- a/Fit/Kernel/Kernel.h
+++ b/Fit/Kernel/Kernel.h
@@ -18,7 +18,7 @@
 #include "KernelTypes.h"
 #include "MinimizerResult.h"
 #include "Parameters.h"
-#include "TimeInterval.h"
+#include "WallclockTimer.h"
 #include "WinDllMacros.h"
 #include <functional>
 #include <memory>
@@ -51,7 +51,7 @@ private:
 
     Parameters m_parameters;
     std::unique_ptr<IMinimizer> m_minimizer;
-    TimeInterval m_time_interval;
+    WallclockTimer m_timer;
 };
 
 } // namespace Fit
diff --git a/Fit/Tools/TimeInterval.cpp b/Fit/Tools/TimeInterval.cpp
deleted file mode 100644
index 6bf76e8ad0734c1a51117d0130b2c7099d354cfe..0000000000000000000000000000000000000000
--- a/Fit/Tools/TimeInterval.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Fit/Tools/TimeInterval.cpp
-//! @brief     Implements TimeInterval class.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "TimeInterval.h"
-#include <chrono>
-
-using clock_used = std::chrono::high_resolution_clock;
-using duration_unit = std::chrono::milliseconds;
-
-class TimeIntervalImp
-{
-public:
-    std::chrono::time_point<clock_used> m_start_time;
-    std::chrono::time_point<clock_used> m_end_time;
-    bool m_is_running;
-    TimeIntervalImp() : m_is_running(false) {}
-};
-
-TimeInterval::TimeInterval() : m_imp(new TimeIntervalImp) {}
-
-TimeInterval::~TimeInterval() = default;
-
-void TimeInterval::start()
-{
-    m_imp->m_is_running = true;
-    m_imp->m_start_time = clock_used::now();
-}
-
-void TimeInterval::stop()
-{
-    m_imp->m_is_running = false;
-    m_imp->m_end_time = clock_used::now();
-}
-
-double TimeInterval::runTime() const
-{
-    duration_unit diff =
-        m_imp->m_is_running
-            ? std::chrono::duration_cast<duration_unit>(clock_used::now() - m_imp->m_start_time)
-            : std::chrono::duration_cast<duration_unit>(m_imp->m_end_time - m_imp->m_start_time);
-
-    return diff.count() / 1000.;
-}
diff --git a/Fit/Tools/WallclockTimer.cpp b/Fit/Tools/WallclockTimer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..04194862c5a76d16e53da4ef229f044e423ce81c
--- /dev/null
+++ b/Fit/Tools/WallclockTimer.cpp
@@ -0,0 +1,54 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Fit/Tools/WallclockTimer.cpp
+//! @brief     Implements WallclockTimer class.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "WallclockTimer.h"
+#include <chrono>
+
+using clock_used = std::chrono::high_resolution_clock;
+using duration_unit = std::chrono::seconds;
+
+//! Internal state of a WallclockTimer object.
+
+struct WallclockTimerState
+{
+    std::chrono::time_point<clock_used> m_start_time;
+    std::chrono::time_point<clock_used> m_end_time;
+    bool m_is_running {false};
+};
+
+WallclockTimer::WallclockTimer() : m_state(new WallclockTimerState) {}
+WallclockTimer::~WallclockTimer() = default;
+
+void WallclockTimer::start()
+{
+    m_state->m_is_running = true;
+    m_state->m_start_time = clock_used::now();
+}
+
+void WallclockTimer::stop()
+{
+    m_state->m_is_running = false;
+    m_state->m_end_time = clock_used::now();
+}
+
+double WallclockTimer::runTime() const
+{
+    duration_unit diff =
+        m_state->m_is_running
+            ? std::chrono::duration_cast<duration_unit>(clock_used::now() - m_state->m_start_time)
+            : std::chrono::duration_cast<duration_unit>(
+                m_state->m_end_time - m_state->m_start_time);
+
+    return diff.count();
+}
diff --git a/Fit/Tools/TimeInterval.h b/Fit/Tools/WallclockTimer.h
similarity index 64%
rename from Fit/Tools/TimeInterval.h
rename to Fit/Tools/WallclockTimer.h
index 7860087add9342da2c6724d6b3e376962419fbe5..d0d90e9869e6b9da971216c51a719beac11d0448 100644
--- a/Fit/Tools/TimeInterval.h
+++ b/Fit/Tools/WallclockTimer.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Fit/Tools/TimeInterval.h
-//! @brief     Defines TimeInterval class.
+//! @file      Fit/Tools/WallclockTimer.h
+//! @brief     Defines WallclockTimer class.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -18,22 +18,24 @@
 #include "WinDllMacros.h"
 #include <memory>
 
-class TimeIntervalImp;
+struct WallclockTimerState;
 
-class BA_CORE_API_ TimeInterval
+//! A timer for measuring real (wall-clock) time spent between 'start' and 'stop' commands.
+
+class BA_CORE_API_ WallclockTimer
 {
 public:
-    TimeInterval();
-    ~TimeInterval();
+    WallclockTimer();
+    ~WallclockTimer();
 
     void start();
     void stop();
 
-    //! returns run time in sec.msec
+    //! returns run time in sec.
     double runTime() const;
 
 private:
-    std::unique_ptr<TimeIntervalImp> m_imp;
+    std::unique_ptr<WallclockTimerState> m_state;
 };
 
 #endif // TIMEINTERVAL_H
diff --git a/GUI/coregui/Views/CommonWidgets/UpdateTimer.cpp b/GUI/coregui/Views/CommonWidgets/UpdateTimer.cpp
index 34663cffc6ed1edaed6d8bc42ea60ab476726b92..f98d3a224ddc9c29f5454d532a8bb003b32e0d34 100644
--- a/GUI/coregui/Views/CommonWidgets/UpdateTimer.cpp
+++ b/GUI/coregui/Views/CommonWidgets/UpdateTimer.cpp
@@ -31,7 +31,7 @@ void UpdateTimer::reset()
     m_is_busy = false;
 }
 
-void UpdateTimer::setTimeInterval(int timerInterval)
+void UpdateTimer::setWallclockTimer(int timerInterval)
 {
     m_timer_interval = timerInterval;
 }
diff --git a/GUI/coregui/Views/CommonWidgets/UpdateTimer.h b/GUI/coregui/Views/CommonWidgets/UpdateTimer.h
index 1ee51f3b2c1c00273e6c1638919bdc8c86641dd3..ab3706fa212e25bbca14a47473efa4f75331d731 100644
--- a/GUI/coregui/Views/CommonWidgets/UpdateTimer.h
+++ b/GUI/coregui/Views/CommonWidgets/UpdateTimer.h
@@ -33,7 +33,7 @@ public:
 
     void reset();
 
-    void setTimeInterval(int timerInterval);
+    void setWallclockTimer(int timerInterval);
 
 signals:
     void timeToUpdate();
diff --git a/GUI/coregui/mainwindow/AutosaveController.cpp b/GUI/coregui/mainwindow/AutosaveController.cpp
index 5971f018f5e6fb524a258a656ca660893e2fc35b..627ebcdade5239cc3b52cbcbd18f466d2ef4f33f 100644
--- a/GUI/coregui/mainwindow/AutosaveController.cpp
+++ b/GUI/coregui/mainwindow/AutosaveController.cpp
@@ -51,7 +51,7 @@ void AutosaveController::setDocument(ProjectDocument* document)
 void AutosaveController::setAutosaveTime(int timerInterval)
 {
     m_timer->reset();
-    m_timer->setTimeInterval(timerInterval);
+    m_timer->setWallclockTimer(timerInterval);
 }
 
 //! Returns the name of autosave directory.
diff --git a/Tests/Functional/TestMachinery/Benchmark.h b/Tests/Functional/TestMachinery/Benchmark.h
index 6f440e0cab436d673e46cccd5b3175bcd33b7802..cefe8b2c84822dd598a5098954d3baf34c6efcfe 100644
--- a/Tests/Functional/TestMachinery/Benchmark.h
+++ b/Tests/Functional/TestMachinery/Benchmark.h
@@ -16,7 +16,7 @@
 #define BENCHMARK_H
 
 #include "OrderedMap.h"
-#include "TimeInterval.h"
+#include "WallclockTimer.h"
 #include "WinDllMacros.h"
 #include <functional>
 #include <map>
@@ -27,16 +27,16 @@ class BA_CORE_API_ Duration
 public:
     Duration() : m_totalTime(0) {}
 
-    void start() { m_time_interval.start(); }
+    void start() { m_timer.start(); }
     void stop()
     {
-        m_time_interval.stop();
-        m_totalTime += m_time_interval.runTime();
+        m_timer.stop();
+        m_totalTime += m_timer.runTime();
     }
     double runTime() const { return m_totalTime; }
 
 private:
-    TimeInterval m_time_interval;
+    WallclockTimer m_timer;
     double m_totalTime;
 };