diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1c09b7c56953f87522a2b2a22099bf7c4b72d145..e7aa2cfb74b80c5eff04d5ce6a40f8a3214778c6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -310,8 +310,14 @@ integration_tests_cc7_lcg95:
 doc:
   stage: build
   needs: ["no_needs"]
+  image: gitlab-registry.cern.ch/ci-tools/ci-worker:cc7
   tags:
     - cvmfs
+  before_script:
+    - source /cvmfs/sft.cern.ch/lcg/views/LCG_95apython3/x86_64-centos7-gcc8-opt/setup.sh
+    - python3 -m venv --clear env
+    - source env/bin/activate
+    - pip install -r doc/requirements.txt
   script:
     - mkdir build
     - cd build
diff --git a/CMakeLists.txt b/CMakeLists.txt
index db0ed3980922d8882b3f93fec80b6b35ceebb8e8..5986d6af8a5b135d66d7acd226afc0d5f6a8a7d4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,6 +75,7 @@ if(ACTS_BUILD_TGEO_PLUGIN)
 endif()
 if(ACTS_BUILD_DOC)
   find_package(Doxygen 1.8.11 REQUIRED)
+  find_package(Sphinx REQUIRED)
 endif()
 
 # core library, core plugins, and other components
diff --git a/cmake/FindSphinx.cmake b/cmake/FindSphinx.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..2dbf0d938acb9bb765db8ef20e5e60bf25c92c14
--- /dev/null
+++ b/cmake/FindSphinx.cmake
@@ -0,0 +1,16 @@
+# Find the Sphinx documentation generator.
+#
+# This module defines the following variables:
+#   Sphinx_FOUND - whether Sphinx was found or not
+#   Sphinx_EXECUTABLE - Sphinx executable if if was found
+#
+
+find_program(
+  Sphinx_EXECUTABLE
+  NAMES sphinx-build sphinx-build-3
+  DOC "Sphinx documentation generator")
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+  Sphinx
+  REQUIRED_VARS Sphinx_EXECUTABLE)
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c78f6c0d00c9a12a0ff1fefbef4904cb3f58d404
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1,2 @@
+# autogenerated by sphinx
+api
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 87cb658c71f4a1710c64eebfc0424c44f5392cb5..da9f3f2e7cd6b597c390efcb1fe2044abd030953 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -1,18 +1,44 @@
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxygen.config.in ${CMAKE_CURRENT_BINARY_DIR}/doxygen.config @ONLY)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/figures/ActsLogo.gif ${CMAKE_CURRENT_BINARY_DIR}/ActsLogo.gif COPYONLY)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DoxygenLayout.xml ${CMAKE_CURRENT_BINARY_DIR}/DoxygenLayout.xml COPYONLY)
+set(doc_sources
+  index.rst
+  authors.rst
+  ../AUTHORS.md
+  license.rst
+  ../LICENSE
+  integration/atlas.md
+  integration/fcc.md
+  integration/integration.rst
+  modules/eventdata.md
+  modules/geometry.md
+  modules/magnetic_field.rst
+  modules/material.rst
+  modules/modules.rst
+  modules/propagation.md
+  plugins/dd4hep.rst
+  plugins/digitization.rst
+  plugins/identification.rst
+  plugins/plugins.rst
+  plugins/tgeo.rst
+  utilities/grid_axis.md
+  utilities/logging.rst
+  utilities/units.rst
+  utilities/utilities.rst
+)
 
+configure_file(conf.py.in ${CMAKE_CURRENT_BINARY_DIR}/conf.py @ONLY)
+configure_file(doxygen.config.in ${CMAKE_CURRENT_BINARY_DIR}/doxygen.config @ONLY)
 add_custom_target(
-  doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxygen.config
-	WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-	COMMENT "Generating API documentation with Doxygen" VERBATIM)
+  doc
+  COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxygen.config
+  COMMAND ${Sphinx_EXECUTABLE} -b html -d ${CMAKE_CURRENT_BINARY_DIR}/doctrees -j auto -c ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/html
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMENT "Generate html documentation with Doxygen and Sphinx"
+  VERBATIM
+  SOURCES
+    doxygen_layout.xml
+    ${CMAKE_CURRENT_BINARY_DIR}/doxygen.config
+    ${CMAKE_CURRENT_BINARY_DIR}/conf.py
+    ${doc_sources})
 
-install(
-  DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/figures
-  DESTINATION ${CMAKE_INSTALL_DOCDIR}/html/doc OPTIONAL)
 install(
   DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
   DESTINATION ${CMAKE_INSTALL_DOCDIR} OPTIONAL)
-install(
-  FILES ${CMAKE_CURRENT_BINARY_DIR}/Acts.tag
-  DESTINATION ${CMAKE_INSTALL_DOCDIR} OPTIONAL)
diff --git a/doc/Modules.hpp b/doc/Modules.hpp
deleted file mode 100644
index 01ae1349550fd33255d0f383b82e782a2d93f7b6..0000000000000000000000000000000000000000
--- a/doc/Modules.hpp
+++ /dev/null
@@ -1,436 +0,0 @@
-// This file is part of the Acts project.
-//
-// Copyright (C) 2016-2018 CERN for the benefit of the Acts project
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#pragma once
-// clang-format off
-
-/// @defgroup Design Design and concept descriptions
-/// @brief description of general concepts used in Acts
-
-/// @defgroup Logging Debug output options
-/// @ingroup Design
-/// @brief description of debug output options
-///
-/// The Acts logging facility supports several severity levels which allow you
-/// to control the amount of information displayed at run-time. Logger objects
-/// can easily be created using the Acts::getDefaultLogger function which
-/// should be sufficient to get you started. In case you need more customized
-/// debug output, you can make use of the output decorators defined in
-/// Acts::Logging or even write your own implementation of
-/// Acts::Logging::OutputDecorator.
-///
-/// In order to add debug messages to your program, you should use the provided
-/// macros for the different severity levels:
-/// - #ACTS_VERBOSE
-/// - #ACTS_DEBUG
-/// - #ACTS_INFO
-/// - #ACTS_WARNING
-/// - #ACTS_ERROR
-/// - #ACTS_FATAL
-///
-/// All of these macros require that a function <tt>logger()</tt> returning a
-/// Acts::Logger object is available in the scope in which the macros are used.
-/// Inside classes containing an Acts::Logger object as member variable, this
-/// could be achieved by providing a private class method called <tt>logger()</tt>
-/// (for an example see e.g. Acts::CylinderVolumeBuilder::logger). Inside free
-/// functions or member methods with local logger objects, the same effect can
-/// be achieved by using the macro #ACTS_LOCAL_LOGGER which is provided for your
-/// convenience.
-///
-/// @par Code example illustrating the usage
-/// @code{.cpp}
-/// #include <fstream>
-/// #include <memory>
-/// #include "Acts/Utilities/Logger.hpp"
-///
-/// void myFunction() {
-///    // open the logfile
-///    std::ofstream logfile("log.txt");
-///
-///    // setup a logger instance for >= INFO messages, streaming into the log file
-///    // make sure you do NOT call the variable 'logger'
-///    std::unique_ptr<const Acts::Logger> myLogger
-///        = Acts::getDefaultLogger("MyLogger", Acts::Logging::INFO, &logfile);
-///
-///    // make sure the Acts debug macros can work with your logger
-///    ACTS_LOCAL_LOGGER(myLogger);
-///
-///    ACTS_VERBOSE("This message will not appear in the logfile.");
-///    ACTS_INFO("But this one will: Hello World!");
-///
-///    // do not forget to close the logfile
-///    logfile.close();
-/// }
-/// @endcode
-///
-/// In case you are using Acts in another framework which comes with its own
-/// logging facility (e.g. Gaudi) you can pipe the logging output from Acts
-/// tools and algorithms to your framework's logging system by supplying different
-/// implementations of:
-/// - Acts::Logging::OutputFilterPolicy (for mapping logging levels)
-/// - Acts::Logging::OutputPrintPolicy (for passing the Acts output to your internal logging system)
-///
-/// Since Acts makes extensive use of Acts::getDefaultLogger to provide
-/// sufficient information for debugging, you would need to provide a modified
-/// implementation of this function (using your output filter and printing
-/// policies) to also pipe this output to your framework.
-///
-/// Changing the implementation of an already defined function is a non-trivial
-/// task in C++. We recommend the following approach using the possibility to inject
-/// custom code by pre-loading shared libraries with <tt>LD_PRELOAD</tt>. You
-/// need to provide an appropriate implementation for a function of the following
-/// signature into a separate source file and compile it in a shared library
-///
-/// @code{.cpp}
-/// namespace Acts {
-///   std::unique_ptr<const Logger> getDefaultLogger(const std::string&,
-///                                                  const Logging::Level&,
-///                                                  std::ostream*);
-/// }
-/// @endcode
-///
-/// Then you can run your executable, which uses Acts tools and algorithms, in
-/// the following way (tested under Unix)
-///
-/// @code{bash}
-/// LD_PRELOAD=<YOUR_SHARED_LIBRARY> path/to/your/exectuable
-/// @endcode
-///
-/// For an example have a look at CustomDefaultLogger.cpp which you can use as follows:
-///
-/// @code{bash}
-/// cd <ACTS/INSTALL/DIRECTORY>
-/// source bin/setup.sh
-/// LD_PRELOAD=lib/libActsCustomLogger.so bin/Examples/ActsGenericDetector
-/// @endcode
-
-/// @defgroup Core Core classes
-/// @brief Acts core classes
-
-/// @defgroup Detector Tracking geometry
-/// @ingroup Core
-/// @brief Description of the tracking geometry
-
-/// @defgroup EventData Event data model
-/// @ingroup Core
-/// @brief Event data model
-
-/// @defgroup Extrapolation Track extrapolation
-/// @ingroup Core
-/// @brief Algorithms for extrapolation of track parameters
-
-/// @defgroup Fitter Track fitters
-/// @ingroup Core
-/// @brief Algorithms for track fitting
-
-/// @defgroup Layers Layers
-/// @ingroup Core
-/// @brief Description of detector layers
-
-/// @defgroup MagneticField Magnetic field
-/// @ingroup Core
-/// @brief Description of magnetic field configurations
-///
-/// This module collects information about classes and typedefs useful for
-/// describing different magnetic field configurations.
-///
-/// Acts is independent of the magnetic field implementation used.
-/// Algorithms which need magnetic field information (e.g. Acts::RungeKuttaEngine,
-/// Acts::AtlasStepper, Acts::EigenStepper) are templated on the magnetic field.
-/// The requirements for the magnetic field implementation are the implementation of the following functions:
-/// @todo implement concept for magnetic field implementation
-/// @code
-/// // retrieve field at given position
-/// Acts::Vector3D getField(const Acts::Vector3D& position) const
-/// // retrieve magnetic field cell at given position
-/// // where Cache is the specific Cache struct defined by the magnetic field implementation
-/// Acts::Vector3D getField(const Acts::Vector3D& position, Cache& cache) const
-/// // retrieve gradient of magnetic field value
-/// Acts::Vector3D getFieldGradient(const Acts::Vector3D& position, Acts::ActsMatrixD<3, 3>& derivative) const
-/// // check whether given 3D position is inside this field cell
-/// bool isInside(const Acts::Vector3D& position) const
-/// @endcode
-///
-/// Each magnetic field implementation expects to be passed a reference to an 
-/// implementation specific cache object. This can usually be achieved through
-/// <tt>typename BField::Cache cache</tt>, where @c BField is a template parameter.
-///
-/// Acts comes with these implementations of this (implicit) interface:
-///
-/// <B>1. Constant magnetic field implementation</B>
-///
-/// Should be used to describe a constant magnetic field.
-/// The Acts::ConstantBField returns a given constant magnetic field value at every point and can be set by the
-/// user either at construction or with a set function.
-///
-/// <B>2. Interpolated magnetic field  implementation</B>
-///
-/// For more complex magnetic field implementations the Acts::InterpolatedBFieldMap can be used.
-///
-/// The Acts::InterpolatedBFieldMap internally uses a field mapper which follows
-/// the <a href="http://www.boost.org/doc/libs/1_55_0/doc/html/boost_typeerasure/basic.html">boost concept</a>
-/// Acts::concept::AnyFieldLookup. This allows users to provide their own field mapper implementation
-/// using the Acts::InterpolatedBFieldMap interface.
-///
-/// Acts provides a default field mapper implementation: Acts::InterpolatedBFieldMap::FieldMapper, which maps global cartesian 3D positions
-/// to magnetic field values. It uses an underlying grid which follows the <a href="http://www.boost.org/doc/libs/1_55_0/doc/html/boost_typeerasure/basic.html">boost concept</a>
-/// Acts::concept::AnyNDimGrid which can be a grid of any dimension and allows users to provide their own
-/// grid implementation. Furthermore users also need to provide two functions in order to use the Acts::InterpolatedBFieldMap::FieldMapper:
-/// 1. a function mapping cartesian global 3D coordinates onto the grid coordinates (of dimension N)
-/// 2. a function calculating cartesian global 3D coordinates of the magnetic field with the local N dimensional field and the global 3D position as an input
-///
-/// A default Acts::detail::Grid implementation is provided following the Acts::concept::AnyNDimGrid,
-/// which is flexible (using template parameters) on the dimension of the grid and the value stored in the grid.
-///
-/// Two convenience functions in order ease the creation of an Acts::InterpolatedBFieldMap::FieldMapper e.g. when reading in a field map from a file,
-/// are provided:
-/// 1. Acts::InterpolatedBFieldMap::FieldMapper<2, 2> fieldMapperRZ()
-/// 2. Acts::InterpolatedBFieldMap::FieldMapper<3, 3> fieldMapperXYZ()
-///
-/// <B>3. SharedBField</B>
-/// 
-/// Wraps another @c BField type, which it holds as a @c shared_ptr. The instance can then be copied without having to duplicate
-/// the underlying field implementation. This is useful in the case of a large B-Field map.
-
-/// @defgroup Material Material
-/// @ingroup Core
-/// @brief Description of material properties
-
-/// @defgroup Surfaces Geometric surfaces
-/// @ingroup Core
-/// @brief Description of geometric surfaces
-
-/// @defgroup Tools Tools
-/// @ingroup Core
-/// @brief Geometry building tools
-
-/// @defgroup Utilities Helper classes
-/// @ingroup Core
-/// @brief Helper utilities
-
-/// @defgroup Volumes Volumes
-/// @ingroup Core
-/// @brief Description of geometric volumes
-
-/// @defgroup Examples Examples
-/// @brief Acts Examples
-
-
-/// @defgroup Plugins Plugins
-/// @brief Acts extensions
-
-/// @defgroup DD4hepPlugins DD4hepPlugins
-/// @ingroup Plugins
-/// @brief Build Acts tracking geometry from \a %DD4hep input.
-///
-/// The DD4hepPlugin allows building of the Acts TrackingGeometry from <a href="http://aidasoft.web.cern.ch/DD4hep">DD4hep</a> input.
-/// \a %DD4hep uses <a href="https://root.cern.ch">ROOT</a> TGeo as an underlying geometry model.
-///
-/// <B>General</B>
-///
-/// The basic input for building the detector are a detector description in the
-/// XML file format and a corresponding detector constructor written in C++. These
-/// two components have to be changed accordingly. Detector constructors use these
-/// XML files as an input and construct a detector in the \a %DD4hep geometry format.
-/// The whole detector is segmented into different detector parts, e.g. barrels
-/// and endcaps which describe different sub-detectors. Since these sub-detectors
-/// are built differently, they need different detector constructors. In this way
-/// one detector description in XML can use various detector constructors, needed
-/// for the different kinds of detector parts.
-///
-/// In the detector description model of \a %DD4hep any detector is a tree of instances
-/// of the so-called \a DetElement class. This \a DetElement class provides all needed
-/// detector information, e.g. readout segmentation, geometrical information,
-/// environmental conditions. This tree is parallel to the volume tree, which
-/// provides the TGeoVolumes and their placements.
-/// The relation between these two trees is one-directional, i.e. every volume can be
-/// accessed via its corresponding \a DetElement, but not vice versa.
-/// Not every supporting material will be declared as a detector element, hence, the
-/// geometrical tree can have a deeper hierarchy structure. In order to access both,
-/// detector specific and geometrical information, the conversion to the tracking
-/// geometry navigates through the detector tree.
-/// The \a DetElement can also be extended, to add specific features or to access
-/// information. This extension mechanism is used during the translation process.
-///
-/// <B>ActsExtensions</B>
-///
-/// \a %DD4hep provides a special extension mechanism for the \a DetElement which allows to
-/// add custom features. In Acts this functionality is used for the conversion from
-/// \a %DD4hep into Acts.
-/// The extensions are used to indicate certain volumes, e.g. if a \a DetElement is the
-/// beam pipe or if a \a DetElement is a layer carrying the sensitive modules. In addition
-/// the extensions are used in order to distinguish if a sub detector is a barrel (described
-/// as a cylinder volume in Acts) or an endcap (which is described as a disc volume in Acts).
-/// Furthermore the
-/// extensions are used to hand over specific information needed for tracking, e.g.
-/// paramters for material mapping.
-/// Please find further information in Acts::ActsExtension.
-///
-/// <B>DD4hepDetectorElement</B>
-///
-/// In Acts the surfaces describing the sensitive modules of a detector are directly
-/// linked to these of the initial geometry input. In the case of \a %DD4hep the
-/// Acts::DD4hepDetectorElement was introduced which is the direct link of Acts to \a %DD4hep.
-/// In the case for tracking relevant paramters in the \a %DD4hep geometry description
-/// are changed (e.g. alignment) it will be automatically changed in Acts.
-///
-/// <B>Build</B>
-///
-/// The DD4hepPlugin is only build on demand. The DD4hepPlugin depends on the TGeoPlugin
-/// therefore both Plugins need to be installed.
-/// During the cmake configuration the flags \c ACTS_BUILD_DD4HEP_PLUGIN and \c ACTS_BUILD_TGEO_PLUGIN need to be set \a ON.
-/// In addition \a ROOT and \a %DD4hep need to be added to the \c CMAKE_PREFIX_PATH. When using the DD4hepPlugin
-/// both the TGeoPlugin and the DD4hepPlugin components need to be loaded in the user's CMake configuration.
-///
-/// <B>Prerequisites</B>
-///
-/// To guarantee a working translation from \a %DD4hep input to Acts geometry the
-/// following conditions need to be met:
-///
-/// * The detector needs to have a barrel-endcap structure:
-///   Every hierarchy of subdetectors (e.g. PixelDetector,
-///   StripDetector,..)
-///   needs to be decomposed of
-///   1) {barrel}
-///   2) {barrel + 2 endcaps}
-///   3) {2 endcaps} - in case there is no barrel at this stage (e.g. forward end caps)
-///
-/// * If a hierachy is not only a single barrel but is decomposed of a barrel
-///   and its corresponding endcaps they need to be grouped together in an assembly
-///   using the \c DD4hep_SubdetectorAssembly constructor which is provided by
-///   \a %DD4hep.
-///   Example of usage in xml file (where \c Barrel0, \c nEndCap0 and \c
-///   pEndCap0
-///   are sub detectors defined in the file \c PixelTracker.xml):
-///   @code
-///   <include ref="PixelTracker.xml"/>
-///   <detectors>
-///     <detector id="1" name="PixelTracker" type="DD4hep_SubdetectorAssembly"
-///      vis="BlueVisTrans">
-///       <shape name="PixelEnvelope" type="Tube" rmin="Env0_rmin"
-///        rmax="Env0_rmax" dz="Env0_dz" material="Air"/>
-///         <composite name="Barrel0"/>
-///         <composite name="nEndCap0"/>
-///         <composite name="pEndCap0"/>
-///     </detector>
-///   </detectors>
-///   @endcode
-///
-///   If a user wants to create his/her own constructor to group these
-///   volumes together the type needs to be set to "compound".
-///
-///
-///	* Since the translation walks trough the \a DetElement tree the following
-/// objects
-///   need to be declared as a \a %DD4hep \a DetElement:
-/// 	- the subvolumes e.g. \b barrel, \b endcap, \b beampipe (they are usually
-/// build
-/// with
-///		  different \a %DD4hep constructors and are therefore \a %DD4hep \a DetElement's
-/// per
-/// 	  default)
-/// 	- \b layers when containing sensitive material and/or the layer should
-/// carry
-/// 	  material (which will be mapped on the layer if indicated), or the layer is sensitive itself
-///       @note the layer does not need to be a direct child of the volume (barrel or endcap), it can be nested in substructures
-///
-///	    - sensitive detector modules
-///		  @note the sensitive detector modules need to be placed in a layer however it can be nested in substructures (can be a component of a modules) i.e. it does not need to be a direct child of the layer
-///
-///	* The Tracking geometry needs to be built from bottom to top to ensure navigation. Therefore the different hierachies need to be sorted ascending. Per default the sub detectors are sorted by the id of their dd4hep::DetElement. In case another sorting needs to be applied, the users can provide their own function
-///
-/// * The Acts::ActsExtension's need to be used during the detector construction
-///    indicating if a \a DetElement
-///		- is a barrel
-///		- is an endcap
-///		- is the beampipe
-///		- is a layer
-///
-/// There are two modes building the layers around the sensitive detector modules:
-/// * The \a DetElements containing the sensitive modules have a geometrical shape
-/// 	- the boundaries of the layers in Acts are taken directly from the given shape
-/// * The \a DetElements containing the sensitive modules have no specific shape (assembliy)
-/// 	- the boundaries of the layers are calculated automatically by adding a tolerance to the geometric extension of the contained surfaces
-///		- the tolerances in r and z need to be set for every \a DetElement representing layer using envelopeR and envelopeZ in the Acts::ActsExtension's
-///
-/// The volumes are automatically build around the layers:
-/// 	- the boundaries for the volumes are calculated automatically by adding a tolerance to the geometric extension of the contained layers
-///		- the parameters layerEnvelopeR and layerEnvelopeZ (tolerances) need to be set in the Acts::convertDD4hepDetector() function
-///
-/// Furthermore parameters can be handed over for material mapping or the axes
-///   orientation of modules.
-///
-///
-/// Summing up the \a DetElement tree in \a %DD4hep should have the following
-/// structure:
-/// \image html DD4hepPlugin_DetElementStructure.jpg
-///
-/// It is also possible to translate a very simple detector geometry, which just
-/// consists of cylindrical (for a barrel) or disc (for endcaps) layers which
-/// either have material, or, are declared sensitive in dd4hep themselves
-/// without containing any detector modules.
-///
-/// <B>Usage</B>
-///
-/// To receive the Acts::TrackingGeometry the user should use the global function
-/// Acts::convertDD4hepDetector(), where he/she needs to hand over the
-/// world \a DetElement of \a %DD4hep.
-/// For a valid translation the user needs to make sure, that all prerequisites
-/// described above are met and that the right
-/// Acts::ActsExtension's are added during the \a %DD4hep construction.
-
-
-/// @defgroup MaterialPlugins MaterialPlugins
-/// @ingroup Plugins
-/// @brief Map material onto the Acts geometry.
-///
-/// The MaterialPlugins allow to map material from a detailed full detector geometry onto the simplfied Acts geometry.
-/// The material is mapped onto layers of the tracking geometry which are marked to carry support material. The marking
-/// is done during the geometry building process. The material can be mapped onto either, the inner, the outer
-/// boundary surface or the central (representing) Acts::Surface of the Acts::Layer. The Acts::Material is described on a two dimensional
-/// grid for each layer (Acts::BinnedSurfaceMaterial). The user defines the granularity of the grid during the geometry building process.
-/// @note The DD4hepPlugin offers the possiility to mark layers which should carry material and to determine the
-/// grid granularity, using the class Acts::ActsExtension.
-///
-/// Following the Acts philosophy the material mapping is agnostic to any file format and software used to create or store
-/// the material maps. The material should be stored in instances of the class Acts::MaterialTrack. This material track record
-/// represents a track starting from a certain position, in a certain direction, containing all material along this
-/// track. The material along the material track record ist stored as a container of Acts::MaterialStep instances. Each material
-/// step contains the material and its thickness at a certain position.
-///
-/// The material mapping process can be split into two subprocesses:
-/// * material assignment
-/// * material averaging
-///
-/// <B>Material Assignment</B>
-/// During the material assignment process the decision onto which layer each material step will be assigned is done.
-/// To assign a Acts::MaterialTrack the function Acts::MaterialMapping::mapMaterial() should be used.
-/// This function extrapolates through the tracking detector, with the start position and direction given by the
-/// material track record and collects all layers marked to carry material. Then it loops through all material steps
-/// of the material track record and assigns the material of each step to the closest layer :
-///
-/// \image html MaterialAssignment.jpeg"Example of material assignment onto the inner boundary surface of the layers. The green points are assigned to the current inner layer, the red to the next inner layer."
-///
-/// <B>Material Averaging</B>
-/// During the material mapping the user can decide to average the material whenever he/she prefers by using
-/// the function Acts::MaterialMapping::averageLayerMaterial(). In the end when all material track records have been mapped one
-/// should use the function Acts::MaterialMapping::finalizeLayerMaterial() in order to finalize the process.
-///
-///
-/// The full material mapping process should be done in the framework of the user.
-///
-/// Possible workflow:
-/// * Create material map(s) of full detector geometry using Acts::MaterialTrack
-/// * Read in material map(s) and go through all collected material track records
-///		- use Acts::MaterialMapping::mapMaterial() for each material track record
-/// * Use Acts::MaterialMapping::averageLayerMaterial() - once per run
-/// * In the end of the process use Acts::MaterialMapping::finalizeLayerMaterial() which assigns the final material to the layers
-
-/// @defgroup Contributing Contribution guide
-
-// clang-format on
diff --git a/doc/authors.rst b/doc/authors.rst
new file mode 100644
index 0000000000000000000000000000000000000000..dce47901360af2344794e31d82282611091080c4
--- /dev/null
+++ b/doc/authors.rst
@@ -0,0 +1,7 @@
+Authors
+=======
+
+Detailed contributor information can also be found on `Gitlab
+<https://gitlab.cern.ch/acts/acts-core/graphs/master>`_.
+
+.. include:: ../AUTHORS
diff --git a/doc/conf.py.in b/doc/conf.py.in
new file mode 100644
index 0000000000000000000000000000000000000000..0f00f210a3fb2e4428588c0bffd92cef467bded5
--- /dev/null
+++ b/doc/conf.py.in
@@ -0,0 +1,94 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# http://www.sphinx-doc.org/en/master/config
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+import sphinx_bootstrap_theme
+from recommonmark.transform import AutoStructify
+
+# -- Project information ------------------------------------------------------
+
+project = '@PROJECT_NAME@'
+author = 'The Acts authors'
+copyright = '2014–2019 CERN for the benefit of the Acts project'
+version = '@PROJECT_VERSION@'
+release = '@PROJECT_VERSION@'
+
+# -- General configuration ----------------------------------------------------
+
+extensions = [
+    'sphinx.ext.mathjax',
+    'recommonmark',
+    'sphinx_markdown_tables',
+    'breathe',
+    'exhale'
+]
+source_suffix = {
+    '.rst': 'restructuredtext',
+    '.md': 'markdown',
+}
+master_doc = 'index'
+# cpp as default language
+primary_domain = 'cpp'
+highlight_language = 'cpp'
+smartquotes = True
+
+# -- Breathe Doxygen/Sphinx bridge configuration ------------------------------
+
+breathe_projects = { '@PROJECT_NAME@': '@CMAKE_CURRENT_BINARY_DIR@/xml/' }
+breathe_default_project = '@PROJECT_NAME@'
+breathe_domain_by_extension = {
+    'cpp': 'cpp',
+    'hpp': 'cpp',
+    'ipp': 'cpp',
+}
+breathe_default_members = ('members', 'undoc-members')
+
+# -- Exhale Doxygen API documentation generation configuratio -----------------
+
+exhale_args = {
+    'containmentFolder': '@CMAKE_CURRENT_SOURCE_DIR@/api',
+    'rootFileName': 'api.rst',
+    'rootFileTitle': 'API',
+    'doxygenStripFromPath': '@PROJECT_SOURCE_DIR@',
+    'createTreeView': True,
+    'treeViewIsBootstrap': True,
+}
+
+# -- Options for HTML output --------------------------------------------------
+
+html_theme = 'bootstrap'
+html_theme_path = sphinx_bootstrap_theme.get_html_theme_path()
+html_theme_options = {
+  'navbar_sidebarrel': False, # no prev/next links in navigation bar
+  'navbar_links': [
+    ('API', 'api/api'),
+    ('Gitlab', 'https://gitlab.cern.ch/acts/acts-core', True),
+  ],
+  'navbar_fixed_top': False,
+}
+html_logo = '@CMAKE_CURRENT_SOURCE_DIR@/figures/ActsLogo.gif'
+html_static_path = []
+html_copy_source = False
+html_show_sourcelink = False
+html_show_sphinx = False
+
+# -- Markdown bridge setup hook (must come last, not sure why) ----------------
+
+def setup(app):
+    app.add_config_value('recommonmark_config', {
+        'enable_math': True,
+        'enable_inline_math': True,
+        }, True)
+    app.add_transform(AutoStructify)
diff --git a/doc/doxygen.config.in b/doc/doxygen.config.in
index 56f058e980ea059e0f1ebbc7b0db0498065c39b0..97223fe45c85c77eea619e838ae2f760c99d03dc 100644
--- a/doc/doxygen.config.in
+++ b/doc/doxygen.config.in
@@ -38,27 +38,27 @@ PROJECT_NAME           = @PROJECT_NAME@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = @Acts_VERSION@
+PROJECT_NUMBER         = @PROJECT_VERSION@
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
 # quick idea about the purpose of the project. Keep the description short.
 
-PROJECT_BRIEF          = "Reference Guide"
+PROJECT_BRIEF          =
 
 # With the PROJECT_LOGO tag one can specify a logo or an icon that is included
 # in the documentation. The maximum height of the logo should not exceed 55
 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
 # the logo to the output directory.
 
-PROJECT_LOGO           = ActsLogo.gif
+PROJECT_LOGO           =
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
 # into which the generated documentation will be written. If a relative path is
 # entered, it will be relative to the location where doxygen was started. If
 # left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       =
+OUTPUT_DIRECTORY       = @CMAKE_CURRENT_BINARY_DIR@
 
 # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
 # directories (in 2 levels) under the output directory of each output format and
@@ -140,7 +140,7 @@ INLINE_INHERITED_MEMB  = NO
 # shortest path that makes the file name unique will be used
 # The default value is: YES.
 
-FULL_PATH_NAMES        = NO
+FULL_PATH_NAMES        = YES
 
 # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
 # Stripping is only done if one of the specified strings matches the left-hand
@@ -152,7 +152,7 @@ FULL_PATH_NAMES        = NO
 # will be relative from the directory where doxygen is started.
 # This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
-STRIP_FROM_PATH        =
+STRIP_FROM_PATH        = @PROJECT_SOURCE_DIR@
 
 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
 # path mentioned in the documentation of a class, which tells the reader which
@@ -161,7 +161,14 @@ STRIP_FROM_PATH        =
 # specify the list of include paths that are normally passed to the compiler
 # using the -I flag.
 
-STRIP_FROM_INC_PATH    =
+STRIP_FROM_INC_PATH    = @PROJECT_SOURCE_DIR@/Core/include \
+                         @PROJECT_SOURCE_DIR@/Legacy/include \
+                         @PROJECT_SOURCE_DIR@/Plugins/DD4hep/include \
+                         @PROJECT_SOURCE_DIR@/Plugins/Digitization/include \
+                         @PROJECT_SOURCE_DIR@/Plugins/Geant4/include \
+                         @PROJECT_SOURCE_DIR@/Plugins/Identification/include \
+                         @PROJECT_SOURCE_DIR@/Plugins/Json/include \
+                         @PROJECT_SOURCE_DIR@/Plugins/TGeo/include
 
 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
 # less readable) file names. This can be useful is your file systems doesn't
@@ -177,7 +184,7 @@ SHORT_NAMES            = NO
 # description.)
 # The default value is: NO.
 
-JAVADOC_AUTOBRIEF      = NO
+JAVADOC_AUTOBRIEF      = YES
 
 # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
 # line (until the first dot) of a Qt-style comment as the brief description. If
@@ -422,7 +429,7 @@ EXTRACT_ALL            = YES
 # be included in the documentation.
 # The default value is: NO.
 
-EXTRACT_PRIVATE        = YES
+EXTRACT_PRIVATE        = NO
 
 # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
 # scope will be included in the documentation.
@@ -434,7 +441,7 @@ EXTRACT_PACKAGE        = NO
 # included in the documentation.
 # The default value is: NO.
 
-EXTRACT_STATIC         = YES
+EXTRACT_STATIC         = NO
 
 # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
 # locally in source files will be included in the documentation. If set to NO,
@@ -442,7 +449,7 @@ EXTRACT_STATIC         = YES
 # for Java sources.
 # The default value is: YES.
 
-EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_CLASSES  = NO
 
 # This flag is only useful for Objective-C code. If set to YES, local methods,
 # which are defined in the implementation section but not in the interface are
@@ -459,7 +466,7 @@ EXTRACT_LOCAL_METHODS  = NO
 # are hidden.
 # The default value is: NO.
 
-EXTRACT_ANON_NSPACES   = YES
+EXTRACT_ANON_NSPACES   = NO
 
 # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
 # undocumented members inside documented classes or files. If set to NO these
@@ -482,14 +489,14 @@ HIDE_UNDOC_CLASSES     = NO
 # included in the documentation.
 # The default value is: NO.
 
-HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_FRIEND_COMPOUNDS  = YES
 
 # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
 # documentation blocks found inside the body of a function. If set to NO, these
 # blocks will be appended to the function's detailed documentation block.
 # The default value is: NO.
 
-HIDE_IN_BODY_DOCS      = NO
+HIDE_IN_BODY_DOCS      = YES
 
 # The INTERNAL_DOCS tag determines if documentation that is typed after a
 # \internal command is included. If the tag is set to NO then the documentation
@@ -544,7 +551,7 @@ FORCE_LOCAL_INCLUDES   = NO
 # documentation for inline members.
 # The default value is: YES.
 
-INLINE_INFO            = YES
+INLINE_INFO            = NO
 
 # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
 # (detailed) documentation of file and class members alphabetically by member
@@ -629,7 +636,7 @@ GENERATE_DEPRECATEDLIST= YES
 # sections, marked by \if <section_label> ... \endif and \cond <section_label>
 # ... \endcond blocks.
 
-ENABLED_SECTIONS       = detail
+ENABLED_SECTIONS       =
 
 # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
 # initial value of a variable or macro / define can have for it to appear in the
@@ -654,7 +661,7 @@ SHOW_USED_FILES        = YES
 # (if specified).
 # The default value is: YES.
 
-SHOW_FILES             = YES
+SHOW_FILES             = NO
 
 # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
 # page. This will remove the Namespaces entry from the Quick Index and from the
@@ -684,7 +691,7 @@ FILE_VERSION_FILTER    =
 # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
 # tag is left empty.
 
-LAYOUT_FILE            =
+LAYOUT_FILE            = @CMAKE_CURRENT_SOURCE_DIR@/doxygen_layout.xml
 
 # The CITE_BIB_FILES tag can be used to specify one or more bib files containing
 # the reference definitions. This must be a list of .bib files. The .bib
@@ -705,7 +712,7 @@ CITE_BIB_FILES         =
 # messages are off.
 # The default value is: NO.
 
-QUIET                  = NO
+QUIET                  = YES
 
 # The WARNINGS tag can be used to turn on/off the warning messages that are
 # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
@@ -721,7 +728,7 @@ WARNINGS               = YES
 # will automatically be disabled.
 # The default value is: YES.
 
-WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_UNDOCUMENTED   = NO
 
 # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
 # potential errors in the documentation, such as not documenting some parameters
@@ -759,7 +766,7 @@ WARN_FORMAT            = "$file:$line: $text"
 # messages should be written. If left blank the output is written to standard
 # error (stderr).
 
-WARN_LOGFILE           = doxygen.log
+WARN_LOGFILE           =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the input files
@@ -773,11 +780,7 @@ WARN_LOGFILE           = doxygen.log
 
 INPUT                  = @PROJECT_SOURCE_DIR@/Core \
                          @PROJECT_SOURCE_DIR@/Legacy \
-                         @PROJECT_SOURCE_DIR@/Plugins \
-                         @PROJECT_SOURCE_DIR@/Tests \
-                         @PROJECT_SOURCE_DIR@/doc/Modules.hpp \
-                         @PROJECT_SOURCE_DIR@/README.md \
-                         @PROJECT_SOURCE_DIR@/CONTRIBUTING.md
+                         @PROJECT_SOURCE_DIR@/Plugins
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -804,8 +807,7 @@ INPUT_ENCODING         = UTF-8
 
 FILE_PATTERNS          = *.cpp \
                          *.hpp \
-                         *.ipp \
-                         *.md
+                         *.ipp
 
 # The RECURSIVE tag can be used to specify whether or not subdirectories should
 # be searched for input files as well.
@@ -836,8 +838,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = */test/* \
-                         */doc/*
+EXCLUDE_PATTERNS       =  */detail/*
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -848,7 +849,9 @@ EXCLUDE_PATTERNS       = */test/* \
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories use the pattern */test/*
 
-EXCLUDE_SYMBOLS        =
+EXCLUDE_SYMBOLS        = Acts::detail \
+                         nlohmann \
+                         std
 
 # The EXAMPLE_PATH tag can be used to specify one or more files or directories
 # that contain example code fragments that are included (see the \include
@@ -874,7 +877,7 @@ EXAMPLE_RECURSIVE      = NO
 # that contain images that are to be included in the documentation (see the
 # \image command).
 
-IMAGE_PATH             = @PROJECT_SOURCE_DIR@/doc/figures/
+IMAGE_PATH             =
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program
@@ -930,7 +933,7 @@ FILTER_SOURCE_PATTERNS =
 # (index.html). This can be useful if you have a project on for instance GitHub
 # and want to reuse the introduction page also for the doxygen output.
 
-USE_MDFILE_AS_MAINPAGE = @PROJECT_SOURCE_DIR@/README.md
+USE_MDFILE_AS_MAINPAGE =
 
 #---------------------------------------------------------------------------
 # Configuration options related to source browsing
@@ -1027,7 +1030,7 @@ VERBATIM_HEADERS       = YES
 # generated with the -Duse-libclang=ON option for CMake.
 # The default value is: NO.
 
-CLANG_ASSISTED_PARSING = NO
+#CLANG_ASSISTED_PARSING = NO
 
 # If clang assisted parsing is enabled you can provide the compiler with command
 # line options that you would normally use when invoking the compiler. Note that
@@ -1035,7 +1038,7 @@ CLANG_ASSISTED_PARSING = NO
 # specified with INPUT and INCLUDE_PATH.
 # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
 
-CLANG_OPTIONS          =
+#CLANG_OPTIONS          =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the alphabetical class index
@@ -1070,7 +1073,7 @@ IGNORE_PREFIX          =
 # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
 # The default value is: YES.
 
-GENERATE_HTML          = YES
+GENERATE_HTML          = NO
 
 # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
 # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@@ -1078,7 +1081,7 @@ GENERATE_HTML          = YES
 # The default directory is: html.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_OUTPUT            = html
+HTML_OUTPUT            = html/doxygen
 
 # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
 # generated HTML page (for example: .htm, .php, .asp).
@@ -1894,7 +1897,7 @@ MAN_LINKS              = NO
 # captures the structure of the code including all documentation.
 # The default value is: NO.
 
-GENERATE_XML           = NO
+GENERATE_XML           = YES
 
 # The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
 # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@@ -2182,7 +2185,7 @@ DOT_NUM_THREADS        = 0
 # The default value is: Helvetica.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOT_FONTNAME           = FreeSans
+DOT_FONTNAME           =
 
 # The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
 # dot graphs.
diff --git a/doc/DoxygenLayout.xml b/doc/doxygen_layout.xml
similarity index 79%
rename from doc/DoxygenLayout.xml
rename to doc/doxygen_layout.xml
index 962bdc634934e697125b2244b7e219e94713cfe1..971deb801261e603e7ae2d840f145225c5a3e549 100644
--- a/doc/DoxygenLayout.xml
+++ b/doc/doxygen_layout.xml
@@ -1,22 +1,35 @@
 <doxygenlayout version="1.0">
-  <!-- Generated by doxygen 1.8.11 -->
+  <!-- Generated by doxygen 1.8.15 -->
   <!-- Navigation index tabs for HTML output -->
   <navindex>
-    <tab type="user" visible="yes" title="Acts Home Page" url="https://cern.ch/acts"/>
-    <tab type="mainpage" visible="yes" title=""/>
+    <tab type="user" visible="yes" title="Acts" url="../index.html"/>
+    <tab type="mainpage" visible="no" title=""/>
     <tab type="pages" visible="no" title="" intro=""/>
-    <tab type="user" visible="yes" title="Contribution Guide" url="group__Contributing.html"/>
-    <tab type="modules" visible="yes" title="" intro=""/>
+    <tab type="modules" visible="no" title="" intro=""/>
     <tab type="namespaces" visible="yes" title="">
       <tab type="namespacelist" visible="yes" title="" intro=""/>
       <tab type="namespacemembers" visible="yes" title="" intro=""/>
     </tab>
+    <tab type="interfaces" visible="yes" title="">
+      <tab type="interfacelist" visible="yes" title="" intro=""/>
+      <tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
+      <tab type="interfacehierarchy" visible="yes" title="" intro=""/>
+    </tab>
     <tab type="classes" visible="yes" title="">
       <tab type="classlist" visible="yes" title="" intro=""/>
       <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
       <tab type="hierarchy" visible="yes" title="" intro=""/>
       <tab type="classmembers" visible="yes" title="" intro=""/>
     </tab>
+    <tab type="structs" visible="yes" title="">
+      <tab type="structlist" visible="yes" title="" intro=""/>
+      <tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
+    </tab>
+    <tab type="exceptions" visible="yes" title="">
+      <tab type="exceptionlist" visible="yes" title="" intro=""/>
+      <tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
+      <tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
+    </tab>
     <tab type="files" visible="yes" title="">
       <tab type="filelist" visible="yes" title="" intro=""/>
       <tab type="globals" visible="yes" title="" intro=""/>
@@ -89,8 +102,13 @@
     <memberdecl>
       <nestednamespaces visible="yes" title=""/>
       <constantgroups visible="yes" title=""/>
+      <interfaces visible="yes" title=""/>
       <classes visible="yes" title=""/>
+      <structs visible="yes" title=""/>
+      <exceptions visible="yes" title=""/>
       <typedefs title=""/>
+      <sequences title=""/>
+      <dictionaries title=""/>
       <enums title=""/>
       <functions title=""/>
       <variables title=""/>
@@ -100,6 +118,8 @@
     <memberdef>
       <inlineclasses title=""/>
       <typedefs title=""/>
+      <sequences title=""/>
+      <dictionaries title=""/>
       <enums title=""/>
       <functions title=""/>
       <variables title=""/>
@@ -115,11 +135,16 @@
     <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
     <sourcelink visible="yes"/>
     <memberdecl>
+      <interfaces visible="yes" title=""/>
       <classes visible="yes" title=""/>
+      <structs visible="yes" title=""/>
+      <exceptions visible="yes" title=""/>
       <namespaces visible="yes" title=""/>
       <constantgroups visible="yes" title=""/>
       <defines title=""/>
       <typedefs title=""/>
+      <sequences title=""/>
+      <dictionaries title=""/>
       <enums title=""/>
       <functions title=""/>
       <variables title=""/>
@@ -130,6 +155,8 @@
       <inlineclasses title=""/>
       <defines title=""/>
       <typedefs title=""/>
+      <sequences title=""/>
+      <dictionaries title=""/>
       <enums title=""/>
       <functions title=""/>
       <variables title=""/>
@@ -149,6 +176,8 @@
       <classes visible="yes" title=""/>
       <defines title=""/>
       <typedefs title=""/>
+      <sequences title=""/>
+      <dictionaries title=""/>
       <enums title=""/>
       <enumvalues title=""/>
       <functions title=""/>
@@ -168,6 +197,8 @@
       <inlineclasses title=""/>
       <defines title=""/>
       <typedefs title=""/>
+      <sequences title=""/>
+      <dictionaries title=""/>
       <enums title=""/>
       <enumvalues title=""/>
       <functions title=""/>
diff --git a/doc/figures/ActsLogo.gif b/doc/figures/ActsLogo.gif
index 376c84e3e7116ff31103758fe1a3eac2daadb404..25726402af0244512a031552fe4fafa9602efa1e 100644
Binary files a/doc/figures/ActsLogo.gif and b/doc/figures/ActsLogo.gif differ
diff --git a/doc/figures/geometry/CylinderBounds.png b/doc/figures/geometry/CylinderBounds.png
new file mode 100644
index 0000000000000000000000000000000000000000..a749784f3bbbf35d775b0c4661c7d87dc6dde2a4
Binary files /dev/null and b/doc/figures/geometry/CylinderBounds.png differ
diff --git a/doc/figures/geometry/CylinderLayer.png b/doc/figures/geometry/CylinderLayer.png
new file mode 100644
index 0000000000000000000000000000000000000000..9021e50102917b7217156187ede228db26279385
Binary files /dev/null and b/doc/figures/geometry/CylinderLayer.png differ
diff --git a/doc/figures/geometry/CylinderVolumeBounds.png b/doc/figures/geometry/CylinderVolumeBounds.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b38ca16759f3c4009c212d616df898aea0cd51f
Binary files /dev/null and b/doc/figures/geometry/CylinderVolumeBounds.png differ
diff --git a/doc/figures/geometry/DetectorElement.png b/doc/figures/geometry/DetectorElement.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e49cdc5f2a48b5416c784ff5f965c5133c3893c
Binary files /dev/null and b/doc/figures/geometry/DetectorElement.png differ
diff --git a/doc/figures/geometry/DiscBounds.png b/doc/figures/geometry/DiscBounds.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0fbeae549b0b084ae5454e919c5cf04b0e53a7c
Binary files /dev/null and b/doc/figures/geometry/DiscBounds.png differ
diff --git a/doc/figures/geometry/DiscLayerAB.png b/doc/figures/geometry/DiscLayerAB.png
new file mode 100644
index 0000000000000000000000000000000000000000..54676e2a73595af7ffb9f24bc553c1d9196c34b6
Binary files /dev/null and b/doc/figures/geometry/DiscLayerAB.png differ
diff --git a/doc/figures/geometry/DiscLayerEB.png b/doc/figures/geometry/DiscLayerEB.png
new file mode 100644
index 0000000000000000000000000000000000000000..50b4e3bbbf93a46cf7e53ffa9c422e45f62d9658
Binary files /dev/null and b/doc/figures/geometry/DiscLayerEB.png differ
diff --git a/doc/figures/geometry/GlueingABC.png b/doc/figures/geometry/GlueingABC.png
new file mode 100644
index 0000000000000000000000000000000000000000..7dd04babbea8406ac9e6cacce00f04e825db1043
Binary files /dev/null and b/doc/figures/geometry/GlueingABC.png differ
diff --git a/doc/figures/geometry/GlueingBC.png b/doc/figures/geometry/GlueingBC.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5358a25bbe4c76942bae4a72da4b874693ebb89
Binary files /dev/null and b/doc/figures/geometry/GlueingBC.png differ
diff --git a/doc/figures/geometry/LayerArray.png b/doc/figures/geometry/LayerArray.png
new file mode 100644
index 0000000000000000000000000000000000000000..aeb7a8c1482b9090352041bd679ad9bafee24e8e
Binary files /dev/null and b/doc/figures/geometry/LayerArray.png differ
diff --git a/doc/figures/geometry/NavigationABC.png b/doc/figures/geometry/NavigationABC.png
new file mode 100644
index 0000000000000000000000000000000000000000..cc323e9b9c9758c51d49a785ecd3b1e733d63c25
Binary files /dev/null and b/doc/figures/geometry/NavigationABC.png differ
diff --git a/doc/figures/geometry/PlaneBounds.png b/doc/figures/geometry/PlaneBounds.png
new file mode 100644
index 0000000000000000000000000000000000000000..9aa2e71cf0c0fd67fcdfa0592939461522af61ad
Binary files /dev/null and b/doc/figures/geometry/PlaneBounds.png differ
diff --git a/doc/figures/geometry/VolumeBounds.png b/doc/figures/geometry/VolumeBounds.png
new file mode 100644
index 0000000000000000000000000000000000000000..b013a59aa1904d278760e3908fae0a49e2cfa947
Binary files /dev/null and b/doc/figures/geometry/VolumeBounds.png differ
diff --git a/doc/figures/integration_fcc/BField_FCCSW_ACTS.png b/doc/figures/integration_fcc/BField_FCCSW_ACTS.png
new file mode 100644
index 0000000000000000000000000000000000000000..e58286ea36cfd358b624e9d123c7face78f81e9d
Binary files /dev/null and b/doc/figures/integration_fcc/BField_FCCSW_ACTS.png differ
diff --git a/doc/figures/integration_fcc/BField_FCCSW_ACTS1.png b/doc/figures/integration_fcc/BField_FCCSW_ACTS1.png
new file mode 100644
index 0000000000000000000000000000000000000000..db0060a7e601b603c5f4478189879c8ebb2d40e5
Binary files /dev/null and b/doc/figures/integration_fcc/BField_FCCSW_ACTS1.png differ
diff --git a/doc/figures/integration_fcc/DetElement.png b/doc/figures/integration_fcc/DetElement.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8552e15622102ad18c6dbdc142512b5bc6857af
Binary files /dev/null and b/doc/figures/integration_fcc/DetElement.png differ
diff --git a/doc/figures/integration_fcc/FCCSW_ACTS.png b/doc/figures/integration_fcc/FCCSW_ACTS.png
new file mode 100644
index 0000000000000000000000000000000000000000..f353423d45b3bffdbed279a071486391cf8606f6
Binary files /dev/null and b/doc/figures/integration_fcc/FCCSW_ACTS.png differ
diff --git a/doc/figures/integration_fcc/FCCSW_digitization.png b/doc/figures/integration_fcc/FCCSW_digitization.png
new file mode 100644
index 0000000000000000000000000000000000000000..f31621c7bce19af07d75cd95552827cd29b3e0de
Binary files /dev/null and b/doc/figures/integration_fcc/FCCSW_digitization.png differ
diff --git a/doc/figures/integration_fcc/FCCSW_extrapolationTest.png b/doc/figures/integration_fcc/FCCSW_extrapolationTest.png
new file mode 100644
index 0000000000000000000000000000000000000000..57c6973b224d25fbe8e0b6446e66a3f1dad9e564
Binary files /dev/null and b/doc/figures/integration_fcc/FCCSW_extrapolationTest.png differ
diff --git a/doc/figures/integration_fcc/FCCSW_extrapolationTool.png b/doc/figures/integration_fcc/FCCSW_extrapolationTool.png
new file mode 100644
index 0000000000000000000000000000000000000000..df0855ad5eec88555f195c9df798323399252ff9
Binary files /dev/null and b/doc/figures/integration_fcc/FCCSW_extrapolationTool.png differ
diff --git a/doc/figures/integration_fcc/GaudiLogger.png b/doc/figures/integration_fcc/GaudiLogger.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee1592a70fa77b9d3c776fdc9f3fc9d1722e5879
Binary files /dev/null and b/doc/figures/integration_fcc/GaudiLogger.png differ
diff --git a/doc/figures/integration_fcc/Gaudi_ACTS.png b/doc/figures/integration_fcc/Gaudi_ACTS.png
new file mode 100644
index 0000000000000000000000000000000000000000..89daa9250dff0476ce5affea2d2eed9ec880553f
Binary files /dev/null and b/doc/figures/integration_fcc/Gaudi_ACTS.png differ
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..71b21e5b4ca37c07f72248abc8d585dcd9d69a0d
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,33 @@
+A Common Tracking Software
+==========================
+
+This project contains an experiment-independent set of track reconstruction
+tools. The main philosophy is to provide high-level track reconstruction modules
+that can be used for any tracking detector. The description of the tracking
+detector's geometry is optimized for efficient navigation and fast
+extrapolation of tracks. Converters for several common geometry description
+languages exist. Having a highly performant, yet largely customizable
+implementation of track reconstruction algorithms was a primary objective for
+the design of this toolset. Additionally, the applicability to real-life HEP
+experiments plays major role in the development process. Apart from algorithmic
+code, this project also provides an event data model for the description of
+track parameters and measurements.
+
+Key features of this project include:
+
+*   tracking geometry description which can be constructed from TGeo, DD4Hep, or GDML input,
+*   simple and efficient event data model,
+*   performant and highly flexible algorithms for track propagation and fitting,
+*   basic seed finding algorithms.
+
+
+.. toctree::
+    :maxdepth: 2
+
+    modules/modules
+    plugins/plugins
+    utilities/utilities
+    integration/integration
+    api/api
+    authors
+    license
diff --git a/doc/integration/atlas.md b/doc/integration/atlas.md
new file mode 100644
index 0000000000000000000000000000000000000000..a8c1e1d56c252c64ca9fa39ad66045875112e2fb
--- /dev/null
+++ b/doc/integration/atlas.md
@@ -0,0 +1,103 @@
+# Using Acts from Athena
+
+First steps have been taken towards use *Acts* inside *Athena*. The current goal
+is to demonstrate that the Acts geometry design can accomodate current and
+future ATLAS tracking geometries without requiring dedicated modifications in
+the library.  This means building an `Acts::TrackingGeometry`, which contains a
+hierarchy of `TrackingVolume`s. These, in turn, encompass layers of detector
+elements.  Having done this, `Acts` can be used to propagate particles through
+the geometry. This allows the testing of the navigation that is required to
+follow a particle trajectory through the detector.
+
+Since Acts is designed to be configurable, the construction of the layer
+structure is delegated to a `LayerBuilder` utility object. A `LayerBuilder`
+object, that is aware of Athena and the way the detector geometry is acessible
+within it, can provide Acts with all the information that is needed to construct
+the tracking geometry.
+
+```cpp
+Acts::SurfaceArrayCreator::Config sacCfg;
+sacCfg.surfaceMatcher = matcher; // <- allows injection of Identifier info
+
+auto surfaceArrayCreator = std::make_shared<Acts::SurfaceArrayCreator>(
+sacCfg,
+Acts::getDefaultLogger("SurfaceArrayCreator", Acts::Logging::VERBOSE));
+
+...
+
+GeoModelLayerBuilder::Config cfg;
+// layer builder gets the detector manager
+cfg.mng = static_cast<const InDetDD::SiDetectorManager*>(manager);
+gmLayerBuilder = std::make_shared<const GMLB>(cfg,
+Acts::getDefaultLogger("GMLayBldr", Acts::Logging::VERBOSE));
+
+Acts::CylinderVolumeBuilder::Config cvbConfig;
+cvbConfig.layerEnvelopeR = {0, 0};
+cvbConfig.layerEnvelopeZ       = 2;
+cvbConfig.trackingVolumeHelper = cvh;
+// ...
+cvbConfig.layerBuilder         = gmLayerBuilder;
+
+Acts::TrackingGeometryBuilder::Config tgbConfig;
+tgbConfig.trackingVolumeHelper   = cylinderVolumeHelper;
+tgbConfig.trackingVolumeBuilders = volumeBuilders;
+auto trackingGeometryBuilder
+  = std::make_shared<const Acts::TrackingGeometryBuilder>(tgbConfig);
+
+std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry
+  = trackingGeometryBuilder->trackingGeometry();
+```
+
+Tracking surfaces in Acts are coupled to a detector element object, which needs
+to fulfill a certain interface. A dedicated detector element class, which can
+wrap an ATLAS detector element object, was written. At this point, the class
+tries to abstract away some differences between detector elements from the
+different ATLAS subdetectors, which are irrelevant to Acts and allow the
+`LayerBuilder` to be less verbose. The detector identification helpers are an
+example for this. The detector element needs to provide a transform which
+describes the transition into the local reference frame of it's active surface.
+In this case, the transform is stored as a pointer and returned as a const
+reference when requested. This should in principle allow for changes of the
+transforms transparently to Acts. This would be helpful as an initial approach
+to support handling of alignment, since no dedicated infrastructure for
+alignment is in place within Acts.
+
+## Current ATLAS Inner Detector
+
+The detector managers allow access to all the detector elements. The layer
+builder loops over all elements and wraps them into a Acts detector element.
+Subsequently, the identifiers attached to the detector elements allow figuring
+out which detector part and layer the elements belong to. The elements are thus
+collected into buckets for each layer in each component. The elements are then
+handed over to the *LayerCreator* utility, which is part of the Acts core, and
+is versatile enough to handle ATLAS geometries. Identifier information can be
+injected into the *LayerCreator*, which allows determining layer size and
+binning automatically.
+
+In the case of the TRT, the layer builder currently uses the `TRT_Numerology` to
+figure out the number of layers without looping over elements. The detector
+manager provides a method which allows access to detector elements based on the
+indices returned by `TRT_Numerology`. As of now, every straw is translated into
+a detector element in Acts. The endcaps are built as 160 separate disc layers
+containing one layer of straws. In the barrel, there is one layer per barrel
+ring. The binning is not optimal at this point, an arbitrary $\phi$ binning
+should work reasonably well.
+
+## ITk
+
+With some modifications, the layer builder can build the ITk geometry in
+`20.20`. One adjustment is the fact that the meaning of the identifier parts
+*eta_module* and *layer_disk* changed for the Pixel endcaps. In the ID,
+*layer_disk* enumerates the endcap themselves, while *eta_module* enumerates the
+rings in $r$. In `20.20`, *eta_module* enumerates the $z$-position of rings,
+while *layer_disk* enumerates the rings in $r$. A problem arises here, because
+*eta_module* now only enumerates rings present in a given *eta_module*. This
+way, the identifier cannot be used which elements belong to the same layer (in
+the Acts sense).
+
+## Design
+
+Currently, the tracking geometry is built from inside one algorithm. The
+particle propagation loop also runs within the algorithm. This will need to be
+reworked, so that access to the Acts tracking geometry is available in a
+reusable way.
diff --git a/doc/integration/fcc.md b/doc/integration/fcc.md
new file mode 100644
index 0000000000000000000000000000000000000000..a8ac23b7a038f1135f524bd3ec6c2cbf9537060f
--- /dev/null
+++ b/doc/integration/fcc.md
@@ -0,0 +1,131 @@
+# Usage for the Future Circular Collider study
+
+Acts is used as tracking toolkit for the [Future Circular Collider
+(FCC)](https://fcc.web.cern.ch/Pages/default.aspx) design study. The FCC
+Software suite FCCSW uses [Gaudi](http://gaudi.web.cern.ch/gaudi/) as an event
+processing framework, [DD4hep (Detector Description for High Energy
+Physics)](https://dd4hep.web.cern.ch/dd4hep/) for the geometry description and
+[Geant4](http://geant4.web.cern.ch/geant4/) as a simulation package. This
+chapter describes the currently ongoing integration and usage of Acts in FCCSW.
+Acts makes use of a plugin mechanism to allow interfacing experiment software
+where necessary, e.g. geometry, identification, event data model, magnetic
+field. In the core part Acts reduces the dependencies to a minimum using
+configuration structs which can be interfaced by the user. For more information
+please see the general [integration](#integration) chapter.
+
+## Integration of Acts into FCCSW
+
+Gaudi Services, Tools and Algorithms are used to interface to Acts. They either
+use provided functionality directly or act as wrapper internally holding an
+instance of the Acts Object. Using the python job option the Acts tools can be
+configured (using their [configuration](#integration_configuration) structs) by
+the user at runtime:
+
+![Alt Image Text](/figures/integration_fcc/Gaudi_ACTS.png "Gaudi_ACTS")
+
+In FCCSW the tracking toolkit is not only used for track fitting but has various
+applications. For instance the [magnetic field service](fcc_bField) of FCCSW is
+based on the Acts implementation. Another example is the application of fast
+simulation using the [extrapolation](#fcc_extrapolation) through the tracking
+geometry. Since for the FCChh conceptual design study no specific detector
+technologies are selected yet, Acts is used to perform geometric
+[digitization](#fcc_digitization).  
+
+![Alt Image Text](/figures/integration_fcc/FCCSW_ACTS.png "Gaudi_ACTS")
+
+## Forwarding logging messages to Gaudi
+
+As explained [here](#integration_output), the Acts logging messages can be
+forwarded to the Gaudi message service during an event by overloading the
+default Acts logging implementation. In the following one can see, for example,
+overload of the Acts print policy (definition how and where to print):
+
+![Alt Image Text](/figures/integration_fcc/GaudiLogger.png "GaudiLogger")
+
+## <a name="fcc_geoTranslation">Geometry Translation</a>
+
+In FCCSW we require to have one common source of detector description for all
+applications, including the differnt types of simulation and reconstruction. In
+order to allow fast reconstruction Acts internally uses a simplfied tracking
+geometry.    For automatic and consistent geometry translation from DD4hep the
+[plugin mechanism]() was used and a DD4hepPlugin established. The DD4hepPlugin
+provides a convenience function handing back the world volume of the Acts
+tracking geometry from the DD4hep detector.    Inside FCCSW a tracking geometry
+service was established which calls the function and hands back the Acts
+tracking geometry.   The sensitive surfaces in the tracking geometry have a
+direct link to the underlying detector element of Acts, which allows to handle
+conditions data and alignment.
+
+![Alt Image Text](/figures/integration_fcc/DetElement.png "BField")
+
+## <a name="fcc_bField">Magnetic Field implementation</a>
+
+As explained [here](#integration_bField), Acts is agnostic to the magnetic field
+implementation, as long as it follows the given magnetic field `concept`. For
+convenience Acts provides already two different magentic field implementations
+which are being used inside FCCSW. Firstly a configurable constant magnetic
+field service and an interpolated magnetic field service which linearly
+interpolates the magnetic field within cells of a given grid. To stay
+independent from the file format Acts provides convenience methods to facilitate
+creating the grid from std vectors of grid points. Reading in the values from
+the actual file (e.g. root, txt/csv) happens inside FCCSW. The two configurable
+FCC magnetic field service implementations (constant and interpolated) hold the
+dedicated Acts magnetic field implementation as a member and forward the calls
+to it:
+
+![Alt Image Text](/figures/integration_fcc/BField_FCCSW_ACTS.png "BField")
+
+The FCChh magnetic field map which acts as input for the FCC interpolated
+magnetic service can be easily configured using the gaudi job option file:
+
+![Alt Image Text](/figures/integration_fcc/BField_FCCSW_ACTS1.png "BField1")
+ 
+## <a name="fcc_extrapolation">Extrapolation</a>
+
+The extrapolation through the tracking geometry is used during reconstruction. A
+second application of the extrapolation through the tracking geometry is for
+fast simulation. In order to allow both applications to use the extrapolation
+with different configuration a Gaudi Tool which holds an instance to the Acts
+extrapolation was created. This tool can be configured differently for both
+applications at runtime:
+
+![Alt Image Text](/figures/integration_fcc/FCCSW_extrapolationTool.png "extrapolation1")
+
+The extrapolation tool can then be used by an Gaudi algorithm which handles the
+translations from and to the FCC edm. For example in the ExtrapolationTest below
+the reads in generated particles from the event store and after extrapolating
+through the tracking geometry, translates the output into FCC track hits:
+
+![Alt Image Text](/figures/integration_fcc/FCCSW_extrapolationTest.png "extrapolation2")
+
+## <a name="fcc_digitization">Geometric Digitization</a>
+
+Because the specific detector technologies which will be used for the future
+hadron hadron collider are not known yet the Acts geometric digitzation tools
+are being implemented for FCChh.
+
+Every detector element inside Acts holds a pointer to a `DigitizationModule`.
+The digitization module has information about readout relevant information e.g.
+segmentation, readout drift direction, lorentz angle. The `DD4hepPlugin` enables
+either automatic translation from the given readout information from DD4hep
+during the conversion or the possibility that the user can append the
+digitization module. The first version creates one digitzation module for every
+sensitive surface which is very expensive in CPU. Since many sensitive detector
+elements will have the same readout segmentation, the second variation allows
+the user to once create a shared instance of a digitization module and append it
+to many mdoules. Convenience functions which hand back the Acts digitization
+module from a given dd4hep readout have been created. The Acts geometric
+digitization determines the cells hit by a particle given the hit position and
+the momentum direction. Afterwards the clusters are created from the pixels
+using a connected components analysis algorithm from boost. The user can decide
+if pixels sharing a common corner or a common edge should be merged.
+
+Using the Acts digitzation tools one can emulate digital readout as well as
+analogue readout which smears the energy deposit in the cells.   Below one can
+see how the `GeometricTrackerDigitizer`, which is currently being developed
+inside FCCSW and uses the Acts digitization tools, can be used in the python job
+options. It reads in hits (`digiTrackHitAssociation`) produced by FCC geant4
+full simulation and writes out `trackClusters` to the FCC event store:    
+
+
+![Alt Image Text](/figures/integration_fcc/FCCSW_digitization.png "digitization")
diff --git a/doc/integration/integration.rst b/doc/integration/integration.rst
new file mode 100644
index 0000000000000000000000000000000000000000..54e4be635fb5c0c9c33c3a8d67cb4ba51812e11d
--- /dev/null
+++ b/doc/integration/integration.rst
@@ -0,0 +1,11 @@
+Experiment integration
+======================
+
+The Acts project aims to be experiment-independent. Integration into the
+following experimental reconstruction frameworks are currently being developed.
+
+.. toctree::
+    :maxdepth: 1
+
+    atlas
+    fcc
diff --git a/doc/license.rst b/doc/license.rst
new file mode 100644
index 0000000000000000000000000000000000000000..946d49bc9866b3ef3b8de68f0c17c91662e76441
--- /dev/null
+++ b/doc/license.rst
@@ -0,0 +1,9 @@
+License
+=======
+
+Acts is licensed under the `Mozilla Public License Version 2.0
+<http://mozilla.org/MPL/2.0/>`_. The full text of the license can be found
+below.
+
+.. literalinclude:: ../LICENSE
+    :language: none
diff --git a/doc/modules/eventdata.md b/doc/modules/eventdata.md
new file mode 100644
index 0000000000000000000000000000000000000000..c50f12a951af3fbc0b46a8a6791c008a58ac914c
--- /dev/null
+++ b/doc/modules/eventdata.md
@@ -0,0 +1,173 @@
+# Event data
+
+## Track parametrization
+
+A trajectory in a magnetic field is generally parameterized by a set of at least
+five parameters (when being bound to a surface). Two different categories are
+used in Acts: so-called bound parameters, i.e. parameter bound to a surface and
+curvilinear parameters. Curvilinear parameters are defined in an implicit planar
+and normal (to the track) reference plane that follows the track. The center of
+the implicitly defined plane is at the current track position, while the normal
+vector points along the momentum direction. Per definition the local parameters
+of a curvilinear parametrization are thus fixed to (0,0).
+
+In Acts the parametrization is can be changed, provided the according
+transformations into global coordinates are given, it can be changed by adapting
+the relevant `coordinate_transformation` definition. This shows an excerpt of
+the default implementation:
+
+```cpp
+namespace Acts {
+namespace detail {
+  /**
+   * @brief helper structure summarizing coordinate transformations
+   */
+  struct coordinate_transformation
+  {
+    typedef ActsVector<ParValue_t, Acts::NGlobalPars> ParVector_t;
+
+    static ActsVectorD<3>
+    parameters2globalPosition(const ParVector_t& pars, const Surface& s)
+    {
+      ActsVectorD<3> globalPosition;
+      s.localToGlobal(ActsVectorD<2>(pars(Acts::eLOC_0), pars(Acts::eLOC_1)),
+                      parameters2globalMomentum(pars),
+                      globalPosition);
+      return globalPosition;
+    }
+
+    static ActsVectorD<3>
+    parameters2globalMomentum(const ParVector_t& pars)
+    {
+      ActsVectorD<3> momentum;
+      double         p     = std::abs(1. / pars(Acts::eQOP));
+      double         phi   = pars(Acts::ePHI);
+      double         theta = pars(Acts::eTHETA);
+      momentum << p * sin(theta) * cos(phi), p * sin(theta) * sin(phi),
+          p * cos(theta);
+
+      return momentum;
+    }
+
+    static ParVector_t
+    global2curvilinear(const ActsVectorD<3>&,
+                       const ActsVectorD<3>& mom,
+                       double                charge)
+    {
+      ParVector_t parameters;
+      parameters << 0, 0, mom.phi(), mom.theta(),
+          ((std::abs(charge) < 1e-4) ? 1. : charge) / mom.mag();
+
+      return parameters;
+    }
+  // ...
+  };
+} // end of namespace detail
+} // end of namespace Acts
+```
+
+The default parametrization is chosen to be the ATLAS parameterisation:
+
+```cpp
+namespace Acts {
+enum ParDef : unsigned int {
+  eLOC_0    = 0,  ///< first coordinate in local surface frame
+  eLOC_1    = 1,  ///< second coordinate in local surface frame
+  eLOC_R    = eLOC_0,
+  eLOC_PHI  = eLOC_1,
+  eLOC_RPHI = eLOC_0,
+  eLOC_Z    = eLOC_1,
+  eLOC_X    = eLOC_0,
+  eLOC_Y    = eLOC_1,
+  eLOC_D0   = eLOC_0,
+  eLOC_Z0   = eLOC_1,
+  ePHI      = 2,  ///< phi direction of momentum in global frame
+  eTHETA    = 3,  ///< theta direction of momentum in global frame
+  eQOP = 4,  ///< charge/momentum for charged tracks, for neutral tracks it is
+             /// 1/momentum
+  NGlobalPars
+};
+```
+
+Changing the default parameter definition and transformation needs recompilation
+of the Acts Software and redefinition of the relevant plugin:
+ 
+```cmake
+target_compile_definitions (Acts::Core PUBLIC -DACTS_PARAMETER_DEFINITIONS_PLUGIN="${ACTS_PARAMETER_DEFINITIONS_PLUGIN}")
+```
+
+### Neutral and charged representations
+
+Track parameters come in a charged and neutral flavor, the flavor is defined using a template parameter,
+which either is a `ChargedPolicy` class for charged track parameter representation:
+
+```cpp
+namespace Acts {
+    typedef SingleTrackParameters<ChargedPolicy>            TrackParameters;
+    typedef SingleCurvilinearTrackParameters<ChargedPolicy> CurvilinearParameters;
+    typedef SingleBoundTrackParameters<ChargedPolicy>       BoundParameters;
+}  // end of namespace Acts
+```
+
+Or, respectively, a `NeutralPolicy` object
+
+```cpp
+namespace Acts {
+    typedef SingleTrackParameters<NeutralPolicy> NeutralParameters;
+    typedef SingleCurvilinearTrackParameters<NeutralPolicy>
+                                              NeutralCurvilinearParameters;
+    typedef SingleBoundTrackParameters<NeutralPolicy> NeutralBoundParameters;
+} // end of namespace Acts  
+```
+
+### Multi-variant representation
+
+Multi-variant fitters, such as the Gaussian Sum filter rely on a multi-component
+description of the track, which requires the definition of multi-variant track
+parameters. For Acts, as Propagator and Extrapolator are written for type
+templates, a multi-variant definition of track parametrization is *planned* in
+order to integrate directly with the core software.
+
+## Measurements
+
+Measurements exist as *uncalibrated* and *calibrated* types. While
+*uncalibrated* measurements are the direct output of the data formation, during
+the track fit, when trajectory information (or information about the trajectory
+hypothesis) is available, certain calibration steps can help to improve the
+track fit quality.
+
+### Uncalibrated measurements
+
+Measurements in a detector can be one to many-dimensional (covering the full
+range up to the full track parametrization).
+
+```cpp
+template <typename Identifier, ParID_t... params>
+class Measurement
+{
+  // check type conditions
+  static_assert(std::is_copy_constructible<Identifier>::value,
+                "'Identifier' must be copy-constructible");
+  static_assert(std::is_move_constructible<Identifier>::value,
+                "'Identifier' must be move-constructible");
+  static_assert(std::is_copy_assignable<Identifier>::value,
+                "'Identifier' must be copy-assignable");
+  static_assert(std::is_move_assignable<Identifier>::value,
+                "'Identifier' must be move-assignable");
+
+private:
+  // private typedef's
+  typedef ParameterSet<params...>
+      ParSet_t;  ///< type of the underlying ParameterSet object
+// ...
+};
+```
+          
+In order to minimize the computational cost (and differently from the original
+ATLAS code base), the dimension of the measurement has to be fixed at compile
+time.          
+
+### Calibrated measurements
+
+Calibrated measurements are temporary objects needed for track fitting and
+belonging to a track. *Still to be defined*
diff --git a/doc/modules/geometry.md b/doc/modules/geometry.md
new file mode 100644
index 0000000000000000000000000000000000000000..c4de41001e4c181631700bfd600d6d3d30273a58
--- /dev/null
+++ b/doc/modules/geometry.md
@@ -0,0 +1,278 @@
+# Geometry module
+
+The Acts geometry model is strongly based on the ATLAS Tracking geometry. Its
+core is built on a surface-based description that make up all geometry objects
+of higher complexity. This design has been chosen as the surface objects can be
+used together with the track propagation module and thus all geometry objects
+become natively integrated into the tracking software.
+
+## GeometryObject base class and GeometryID
+
+All geometry objects in Acts inherit from a virtual `GeometryObject` base class
+
+    /// @class GeometryObject
+    ///
+    /// Base class to provide GeometryID interface:
+    /// - simple set and get
+    ///
+    /// It also provides the binningPosition method for
+    /// Geometry geometrical object to be binned in BinnedArrays
+    ///
+    class GeometryObject
+    {
+    public:
+     /// default constructor
+     GeometryObject() : m_geoID(0) {}
+    
+     /// constructor from a ready-made value
+     ///
+     /// @param geoID the geometry identifier of the object
+     GeometryObject(const GeometryID& geoID) : m_geoID(geoID) {}
+    
+     /// assignment operator
+     ///
+     /// @param geoID the source geoID
+     GeometryObject&
+     operator=(const GeometryObject& geoID)
+     {
+       if (&geoID != this) {
+         m_geoID = geoID.m_geoID;
+       }
+       return *this;
+     }
+    
+     /// Return the value
+     /// @return the geometry id by reference
+     const GeometryID&
+     geoID() const;
+    
+     /// Force a binning position method
+     ///
+     /// @param bValue is the value in which you want to bin
+     ///
+     /// @return vector 3D used for the binning schema
+     virtual const Vector3D
+     binningPosition(BinningValue bValue) const = 0;
+    
+     /// Implement the binningValue
+     ///
+     /// @param bValue is the dobule in which you want to bin
+     ///
+     /// @return float to be used for the binning schema
+     double
+     binningPositionValue(BinningValue bValue) const;
+    
+     /// Set the value
+     ///
+     /// @param geoID the geometry identifier to be assigned
+     void
+     assignGeoID(const GeometryID& geoID);
+    
+    protected:
+     GeometryID m_geoID;
+    };
+
+This class ensures that a unique `GeometryID` is assigned to every geometry
+object. The `GeometryID` is mainly used for fast identification of the type of
+the geometry object (as most are either extensions or containers of the
+`Surface` objects) and for the identification of the geometry surfaces after
+building, e.g. for the uploading/assigning of material to the surface after
+creation. The `GeometryID` uses a simple masking procedure for applying an
+identification schema.
+
+It is used for Acts internal applications, such as material mapping, but not for
+`EventData` and `Geometry` identification in an experiment setup, for this the
+`Identifier` class is to be used and/or defined.
+
+    typedef uint64_t geo_id_value;
+    
+    namespace Acts {
+    
+    /// @class GeometryID
+    ///
+    ///  Identifier for Geometry nodes - packing the
+    ///  - (Sensitive) Surfaces    - uses counting through sensitive surfaces
+    ///  - (Approach)  Surfaces    - uses counting approach surfaces
+    ///  - (Layer)     Surfaces    - uses counting confined layers
+    ///  - (Boundary)  Surfaces    - uses counting through boundary surfaces
+    ///  - Volumes                 - uses counting given by TrackingGeometry
+    class GeometryID
+    {
+    public:
+      const static geo_id_value volume_mask    = 0xff00000000000000;
+      const static geo_id_value boundary_mask  = 0x00ff000000000000;
+      const static geo_id_value layer_mask     = 0x0000ff0000000000;
+      const static geo_id_value approach_mask  = 0x000000f000000000;
+      const static geo_id_value sensitive_mask = 0x0000000ffff00000;
+      const static geo_id_value channel_mask   = 0x00000000000fffff;
+      ...
+    };
+
+
+## Surface classes
+
+The `Surface` class builds the core class of all geometry objects and can be
+used natively with the propagation and extrapolation modules. The common
+`Surface` virtual base defines the public interface of all surfaces. The
+different concrete `Surface` classes are defined by their respective native
+local coordinate system, while different shapes on surfaces are defined by
+`SurfaceBounds` classes which every surface must provide. In case of boundless
+surfaces, a special `InfiniteBounds` class is available.
+
+| Surface Type          | Local Coordinates | Bound Types available                                                                       |
+|:----------------------|-------------------|:--------------------------------------------------------------------------------------------|
+| `ConeSurface`         | [rphi, z]         | `ConeBounds`                                                                                |
+| `CylinderSurface`     | [r, phi]          | `CylinderBounds`                                                                            |
+| `DiscSurface`         | [r, phi]          | `RadialBounds`, `DiscTrapezoidalBounds`                                                     |
+| `PlaneSurface`        | [x, y]            | `RectangleBounds`, `TrapezoidalBounds`, `TriangleBounds`, `InfiniteBounds`, `EllipseBounds` |
+| `PerigeeSurface`, `StrawSurface` | [d, z] | `CylinderBounds`                                                                            |
+
+![CylinderBounds](/figures/geometry/CylinderBounds.png)
+![DiscBounds](/figures/geometry/DiscBounds.png)
+![PlaneBounds](/figures/geometry/PlaneBounds.png)
+
+## Layer classes
+
+The `Layer` class is an extension of the `Surface` class that allows the
+definition of sub surfaces (sensitive surfaces for modules, or extra material
+surfaces).
+
+The Layer can simply correspond to a 'virtual' surface in the detector
+description or represent a more complex object that may contain:
+
+* a representing surface, which is accessible via a `representingSurface()`
+* method an array of contained surfaces, accessible via `surfaceArray()` method
+* approach surfaces (i.e. boundary surface of the volume occupied by the layer)
+* surface material description on any of the confined surfaces
+   
+The following illustration shows an x-y view of a cylinder layer with planar
+detection modules:
+
+![CylinderLayer](/figures/geometry/CylinderLayer.png)
+
+Modules can be sorted onto layer using all supported binning methods described
+through the `SurfaceArray` class, the binning can be adjusted to fit as good as
+possible.
+
+![DiscLayerEB](/figures/geometry/DiscLayerEB.png)
+
+The un-occupied space in a volume which contains a layer array is filled with
+objects of type `NavigationLayer`, which allows that in a fully static geometry
+setup, every single point in a volume can be associated with a layer. Layer
+objects are confined together in a special `LayerArray` class and can be
+contained by a `TrackingVolume`.
+
+![LayerArray](/figures/geometry/LayerArray.png)
+
+
+## Volume classes
+
+The `Volume` class is a container of `BoundarySurface` objects, where each
+`BoundarySurface` is an extension of the `Surface` class with additional
+information about the attached Volumes. The normal vector of the surface
+defines an *inside* (opposite w.r.t. the normal vector) and an *outside* (along
+w.r.t. the normal vector) direction. Either a single volume or an array of
+volumes can be attached to a volume.
+
+The simples volume class is just a collection of surfaces, where the
+`TrackingVolume` describes a volume that can contain:
+
+* an array of contained layers
+* an array of contained volumes (as a container volume)
+* an array of contained volumes (as *floating* objects)
+* a volume based material description
+
+The shape of the volume is defined by `VolumeBounds` classes that create the
+corresponding bounding surfaces and register the attachment to the volume itself
+at creation.
+
+![VolumeBounds](/figures/geometry/VolumeBounds.png)
+![CylinderVolumeBounds](/figures/geometry/CylinderVolumeBounds.png)
+
+## Material description
+
+Two types of material description exist, one for a surface based material, one
+for a volume based material. They will be dealt with differently in the
+extrapolation.
+
+The basic information for any material is:
+
+* the radiation length X0 the nuclear interaction length L0 the atomic weight A
+* the atomic charge Z the density of the material
+
+This information is confined together in the `Material` class.
+
+Surface based material extends this material information by representative
+thickness, the corresponding object is called `MaterialProperties`. The
+thickness hereby can be arbitrarily chosen in order to regulate the material
+budget, it does not have to represent the actual thickness of a detector
+element. To attach it to a surface, a dedicated `SurfaceMaterial` class (or it's
+extensions) is used, which allows to also describe binned material.
+
+Possible extensions are:
+
+ * `HomogeneousSurfaceMaterial`, homogeneous material description on a surface
+ * `BinnedSurfaceMaterial`, an arbitrarily binned material description with a
+    corresponding `BinUtility` object
+ * `ProtoSurfaceMaterial`, only binning description (without material) to be
+   used in the material mapping process
+
+# Geometry building
+
+The geometry building procedure follows the ATLAS TrackingGeometry philosophy of
+a static frame of *glued* volumes, that lead the navigation flow through the
+geometry,
+
+## Attaching a 3D detector geometry
+
+Usually, a 3D detector model geometry exists, which is either native to the full
+detector simulation (Geant4) or is translated into it. This model, however, is
+in general too detailed for track reconstruction: navigating through the
+detailed detector geometry
+
+For most part of the track reconstruction, only a surface based description of
+the detector is needed, in order to allow (surface based) material integration
+and parametrization/ prediction of trajectories on detection surfaces. It is thus
+necessary that the detection surfaces are described to full detail in the
+reconstruction geometry (called `TrackingGeometry`). This is guaranteed by a
+proxy mechanism that connects the detection elements (conveniently called
+`DetectorElement`) to `Surface` object in the reconstruction:
+
+![DetectorElement](/figures/geometry/DetectorElement.png)
+
+### Existing plugins for 3D geometry libraries
+
+Very simple helper methods for 3D libraries exist, they are certainly not
+optimised, but used for templating:
+
+* `TGeoDetectorElement` connects a TGeo volume to a `Surface`
+* `DD4HepDetectorElement` connects a DD4Hep volume (based on TGeo) to a `Surface`
+
+## Layer building
+
+`Surface` object that are to be grouped on a layer should be put into a
+`SurfaceArray` and provided to the layer. Certain helper tools exist to ease the
+translation and create appropriate binning structure: The`SurfaceArrayCreator`
+can create cylindrical, disc-like & planar layers, where the dimensions of the
+layer are determined by parsing the provided surfaces. Additionally, an envelope
+covering the surfaces can be chosen.
+
+## Volume building, packing, and gluing
+
+The philosophy of the `TrackingGeometry` is a fully connective geometry setup,
+i.e. `TrackingVolume` objects are either pure containers for other contained
+`TrackingVolume` instances (where the contained volumes fully fill the space of
+the container volume), or are fully attached via the boundary surface mechanism.
+The boundary surfaces then act as portals from one `TrackingVolume` into the
+next one along the trajectory.
+
+The process to create a fully connected tracking geometry is called glueing.
+Wherever possible, common boundary surfaces are *shared*, where this is not
+possible, they are *attached*.
+
+![GlueingBC](/figures/geometry/GlueingBC.png)
+![GlueingABC](/figures/geometry/GlueingABC.png)
+![NavigationABC](/figures/geometry/NavigationABC.png)
+
+For cylindrical detector setups, a dedicated `CylinderVolumeBuilder` is
+provided, which performs a variety of volume building, packing and gluing.
diff --git a/doc/modules/magnetic_field.rst b/doc/modules/magnetic_field.rst
new file mode 100644
index 0000000000000000000000000000000000000000..687477ed87e90fa2e0034b606d11889c3c0ee530
--- /dev/null
+++ b/doc/modules/magnetic_field.rst
@@ -0,0 +1,73 @@
+Magnetic field
+==============
+
+This module collects information about classes and typedefs useful for
+describing different magnetic field configurations. Acts is independent of the
+magnetic field implementation used. Algorithms which need magnetic field
+information (e.g. :class:`Acts::RungeKuttaEngine`, :class:`Acts::AtlasStepper`,
+:class:`Acts::EigenStepper`) are templated on the magnetic field. The
+requirements for the magnetic field implementation are the implementation of the
+following functions:
+
+.. code-block::
+
+    // retrieve field at given position
+    Acts::Vector3D getField(const Acts::Vector3D& position) const
+    // retrieve magnetic field cell at given position
+    // where Cache is the specific Cache struct defined by the magnetic field implementation
+    Acts::Vector3D getField(const Acts::Vector3D& position, Cache& cache) const
+    // retrieve gradient of magnetic field value
+    Acts::Vector3D getFieldGradient(const Acts::Vector3D& position, Acts::ActsMatrixD<3, 3>&     derivative) const
+    // check whether given 3D position is inside this field cell
+    bool isInside(const Acts::Vector3D& position) const
+
+Each magnetic field implementation expects to be passed a reference to an
+implementation specific cache object. This can usually be achieved through
+``typename BField::Cache cache``, where ``BField`` is a template parameter. Acts
+comes with the following implementations of this (implicit) interface.
+
+Constant magnetic field implementation
+--------------------------------------
+
+Should be used to describe a constant magnetic field. The
+:class:`Acts::ConstantBField` returns a given constant magnetic field value at
+every point and can be set by the user either at construction or with a set
+function.
+
+Interpolated magnetic field implementation
+------------------------------------------
+
+For more complex magnetic field implementations the
+:class:`Acts::InterpolatedBFieldMap` can be used. The
+:class:`Acts::InterpolatedBFieldMap` internally uses a field mapper which
+follows :any:`Acts::concept::AnyFieldLookup` concept. This allows users to
+provide their own field mapper implementation using the
+:class:`Acts::InterpolatedBFieldMap` interface. Acts provides a default field
+mapper implementation :class:`Acts::InterpolatedBFieldMap::FieldMapper`, which
+maps global cartesian 3D positions to magnetic field values. It uses an
+underlying grid which follows the :any:`Acts::concept::AnyNDimGrid` concept which can be
+a grid of any dimension and allows users to provide their own grid
+implementation. Furthermore users also need to provide two functions in order to
+use the :class:`Acts::InterpolatedBFieldMap::FieldMapper`:
+
+#.  A function mapping cartesian global 3D coordinates onto the grid coordinates
+    of dimension N.
+#.  A function calculating cartesian global 3D coordinates of the magnetic field
+    with the local N dimensional field and the global 3D position as an input.
+
+A default :class:`Acts::detail::Grid` implementation is provided following the
+`Acts::concept::AnyNDimGrid`, which is flexible (using template parameters) on
+the dimension of the grid and the value stored in the grid. Two convenience
+functions are provided to  ease the creation of an
+:class:`Acts::InterpolatedBFieldMap::FieldMapper` e.g. when reading in a field
+map from a file, are provided:
+
+#.  :func:`Acts::InterpolatedBFieldMap::FieldMapper<2, 2> Acts::FieldMapperRZ()`
+#.  :func:`Acts::InterpolatedBFieldMap::FieldMapper<3, 3> Acts::fieldMapperXYZ()`
+
+SharedBField
+------------
+
+Wraps another ``BField`` type, which it holds as a ``std::shared_ptr<...>``. The
+instance can then be copied without having to duplicate the underlying field
+implementation. This is useful in the case of a large B-Field map.
diff --git a/doc/modules/material.rst b/doc/modules/material.rst
new file mode 100644
index 0000000000000000000000000000000000000000..db06a5e8d6a9b57be91289c08719d9087cff783f
--- /dev/null
+++ b/doc/modules/material.rst
@@ -0,0 +1,77 @@
+Material
+========
+
+.. note::
+
+    This was originally written for the materials plugin that has been merged
+    into the material module
+
+The material module allow to map material from a detailed full detector geometry
+onto the simplified Acts geometry. The material is mapped onto layers of the
+tracking geometry which are marked to carry support material. The marking is
+done during the geometry building process. The material can be mapped onto
+either, the inner, the outer boundary surface or the central (representing)
+:class:`Acts::Surface` of the :class:`Acts::Layer`. The :class:`Acts::Material`
+is described on a two dimensional grid for each layer
+(:class:`Acts::BinnedSurfaceMaterial`). The user defines the granularity of the
+grid during the geometry building process.
+
+.. note::
+
+    The :doc:`/plugins/dd4hep` offers the possibility to mark layers which should
+    carry material and to determine the grid granularity, using the class
+    :class:`Acts::ActsExtension`.
+
+Following the Acts philosophy the material mapping is agnostic to any file
+format and software used to create or store the material maps. The material
+should be stored in instances of the class :class:`Acts::MaterialTrack`. This
+material track record represents a track starting from a certain position, in a
+certain direction, containing all material along this track. The material along
+the material track record is stored as a container of
+:class:`Acts::MaterialStep` instances. Each material step contains the material
+and its thickness at a certain position.
+
+The material mapping process can be split into two subprocesses:
+
+*   Material assignment
+*   Material averaging
+
+Material assignment
+-------------------
+
+During the material assignment process the decision onto which layer each
+material step will be assigned is done. To assign a :class:`Acts::MaterialTrack`
+the function :func:`Acts::MaterialMapping::mapMaterial()` should be used. This
+function extrapolates through the tracking detector, with the start position and
+direction given by the material track record and collects all layers marked to
+carry material. Then it loops through all material steps of the material track
+record and assigns the material of each step to the closest layer:
+
+.. figure:: /figures/MaterialAssignment.jpeg
+
+    Example of material assignment onto the inner boundary surface of the
+    layers. The green points are assigned to the current inner layer, the red to
+    the next inner layer."
+
+Material averaging
+------------------
+
+During the material mapping the user can decide to average the material whenever
+he/she prefers by using the function
+:func:`Acts::MaterialMapping::averageLayerMaterial()`. In the end when all
+material track records have been mapped one should use the function
+:func:`Acts::MaterialMapping::finalizeLayerMaterial()` in order to finalize the
+process.
+
+The full material mapping process should be done in the framework of the user.
+
+Possible workflow:
+
+* Create material map(s) of full detector geometry using :class:`Acts::MaterialTrack`.
+* Read in material map(s) and go through all collected material track records.
+  Use :func:`Acts::MaterialMapping::mapMaterial()` for each material track
+  record.
+* Use :func:`Acts::MaterialMapping::averageLayerMaterial()` once per run.
+* In the end of the process use
+  :func:`Acts::MaterialMapping::finalizeLayerMaterial()` which assigns the
+  final material to the layers.
diff --git a/doc/modules/modules.rst b/doc/modules/modules.rst
new file mode 100644
index 0000000000000000000000000000000000000000..01d2281ff73b1f0bc7cacd4abde7a032e66ab245
--- /dev/null
+++ b/doc/modules/modules.rst
@@ -0,0 +1,15 @@
+Modules
+=======
+
+The Acts functionality is grouped into modules, where each module contains
+tools related to one particular subject, i.e. experiment geometry or
+vertexing.
+
+.. toctree::
+    :maxdepth: 1
+
+    eventdata
+    geometry
+    magnetic_field
+    material
+    propagation
diff --git a/doc/modules/propagation.md b/doc/modules/propagation.md
new file mode 100644
index 0000000000000000000000000000000000000000..1b38940dccaba90181729b7599202d3bde228834
--- /dev/null
+++ b/doc/modules/propagation.md
@@ -0,0 +1,123 @@
+# Propagation and extrapolation
+
+The track propagation is an essential part of track reconstruction. The Acts
+propagation code is based on the ATLAS `RungeKuttaPropagator`, against which
+newer developments where validated. It has since been removed from the
+code base.
+
+## Steppers and Propagator
+
+The Acts propagator allows for different `Stepper` implementations provided as a
+class template. Following the general Acts design, each stepper has a nested
+cache `struct`, which is used for caching the field cell and the update the
+jacobian for covariance propagation.
+
+### AtlasStepper
+
+The `AtlasStepper` is a pure transcript from the ATLAS `RungeKuttaPropagator`
+and `RungeKuttaUtils`, and operators with an internal structure of `double[]`.
+This example shows a code snippet from the numerical integration.
+
+```cpp
+while (h != 0.) {
+  double S3 = (1. / 3.) * h, S4 = .25 * h, PS2 = Pi * h;
+
+  // First point
+  //
+  double H0[3] = {f0[0] * PS2, f0[1] * PS2, f0[2] * PS2};
+  double A0    = A[1] * H0[2] - A[2] * H0[1];
+  double B0    = A[2] * H0[0] - A[0] * H0[2];
+  double C0    = A[0] * H0[1] - A[1] * H0[0];
+  double A2    = A0 + A[0];
+  double B2    = B0 + A[1];
+  double C2    = C0 + A[2];
+  double A1    = A2 + A[0];
+  double B1    = B2 + A[1];
+  double C1    = C2 + A[2];
+
+  // Second point
+  //
+  if (!Helix) {
+    const Vector3D pos(R[0] + A1 * S4, R[1] + B1 * S4, R[2] + C1 * S4);
+    f = getField(cache, pos);
+  } else {
+    f = f0;
+  }
+
+  double H1[3] = {f[0] * PS2, f[1] * PS2, f[2] * PS2};
+  double A3    = (A[0] + B2 * H1[2]) - C2 * H1[1];
+  double B3    = (A[1] + C2 * H1[0]) - A2 * H1[2];
+  double C3    = (A[2] + A2 * H1[1]) - B2 * H1[0];
+  double A4    = (A[0] + B3 * H1[2]) - C3 * H1[1];
+  double B4    = (A[1] + C3 * H1[0]) - A3 * H1[2];
+  double C4    = (A[2] + A3 * H1[1]) - B3 * H1[0];
+  double A5    = 2. * A4 - A[0];
+  double B5    = 2. * B4 - A[1];
+  double C5    = 2. * C4 - A[2];
+
+  // Last point
+  //
+  if (!Helix) {
+    const Vector3D pos(R[0] + h * A4, R[1] + h * B4, R[2] + h * C4);
+    f = getField(cache, pos);
+  } else {
+    f = f0;
+  }
+
+  double H2[3] = {f[0] * PS2, f[1] * PS2, f[2] * PS2};
+  double A6    = B5 * H2[2] - C5 * H2[1];
+  double B6    = C5 * H2[0] - A5 * H2[2];
+  double C6    = A5 * H2[1] - B5 * H2[0];
+}
+```
+
+### EigenStepper
+
+The `EigenStepper` implements the same functionality as the ATLAS stepper,
+however, the stepping code is rewritten with using `Eigen` primitives. The
+following code snippet shows the Runge-Kutta stepping code.
+
+```cpp
+// The following functor starts to perform a Runge-Kutta step of a certain
+// size, going up to the point where it can return an estimate of the local
+// integration error. The results are stated in the local variables above,
+// allowing integration to continue once the error is deemed satisfactory
+const auto tryRungeKuttaStep = [&](const double h) -> bool {
+
+  // State the square and half of the step size
+  h2     = h * h;
+  half_h = h * 0.5;
+
+  // Second Runge-Kutta point
+  const Vector3D pos1 = state.stepping.pos + half_h * state.stepping.dir
+      + h2 * 0.125 * sd.k1;
+  sd.B_middle = getField(state.stepping, pos1);
+  if (!state.stepping.extension.k2(
+          state, sd.k2, sd.B_middle, half_h, sd.k1)) {
+    return false;
+  }
+
+  // Third Runge-Kutta point
+  if (!state.stepping.extension.k3(
+          state, sd.k3, sd.B_middle, half_h, sd.k2)) {
+    return false;
+  }
+
+  // Last Runge-Kutta point
+  const Vector3D pos2
+      = state.stepping.pos + h * state.stepping.dir + h2 * 0.5 * sd.k3;
+  sd.B_last = getField(state.stepping, pos2);
+  if (!state.stepping.extension.k4(state, sd.k4, sd.B_last, h, sd.k3)) {
+    return false;
+  }
+
+  // Return an estimate of the local integration error
+  error_estimate = std::max(
+      h2 * (sd.k1 - sd.k2 - sd.k3 + sd.k4).template lpNorm<1>(), 1e-20);
+  return true;
+};
+```
+
+The code includes the extension mechanism, which allows extending the numerical
+integration. This is implemented for the custom logic required to integrate
+through a volume with dense material.
diff --git a/doc/plugins/dd4hep.rst b/doc/plugins/dd4hep.rst
new file mode 100644
index 0000000000000000000000000000000000000000..0caf091b08402e1688a8bb33482971aae78e4c6e
--- /dev/null
+++ b/doc/plugins/dd4hep.rst
@@ -0,0 +1,183 @@
+DD4hep plugin
+=============
+
+The DD4hepPlugin allows building of a :class:`Acts::TrackingGeometry` from
+`DD4hep`_ input. DD4hep uses `ROOT`_ TGeo as the underlying geometry model.
+
+.. _DD4hep: https://dd4hep.web.cern.ch/dd4hep/
+.. _ROOT: https://root.cern.ch
+
+General
+-------
+
+The basic input for building the detector are a detector description in the
+XML file format and a corresponding detector constructor written in C++. These
+two components have to be changed accordingly. Detector constructors use these
+XML files as an input and construct a detector in the DD4hep geometry format.
+The whole detector is segmented into different detector parts, e.g. barrels
+and endcaps which describe different sub-detectors. Since these sub-detectors
+are built differently, they need different detector constructors. In this way
+one detector description in XML can use various detector constructors, needed
+for the different kinds of detector parts.
+
+In the detector description model of DD4hep any detector is a tree of instances
+of the so-called ``DetElement`` class. This ``DetElement`` class provides all
+needed detector information, e.g. readout segmentation, geometrical information,
+environmental conditions. This tree is parallel to the volume tree, which
+provides the ``TGeoVolumes`` and their placements. The relation between these
+two trees is one-directional, i.e. every volume can be accessed via its
+corresponding ``DetElement``, but not vice versa. Not every supporting material
+will be declared as a detector element, hence, the geometrical tree can have a
+deeper hierarchy structure. In order to access both, detector specific and
+geometrical information, the conversion to the tracking geometry navigates
+through the detector tree. The ``DetElement`` can also be extended, to add
+specific features or to access information. This extension mechanism is used
+during the translation process.
+
+Acts extension
+--------------
+
+DD4hep provides a special extension mechanism for the ``DetElement`` which
+allows to add custom features. In Acts this functionality is used for the
+conversion from ``DD4hep`` into Acts. The extensions are used to indicate
+certain volumes, e.g. if a ``DetElement`` is the beam pipe or if a
+``DetElement`` is a layer carrying the sensitive modules. In addition the
+extensions are used in order to distinguish if a sub detector is a barrel
+(described as a cylinder volume in Acts) or an endcap (which is described as a
+disc volume in Acts). Furthermore the extensions are used to hand over specific
+information needed for tracking, e.g. paramters for material mapping.
+
+DD4hepDetectorElement
+---------------------
+
+In Acts the surfaces describing the sensitive modules of a detector are directly
+linked to these of the initial geometry input. In the case of DD4hep the
+:class:`Acts::DD4hepDetectorElement` was introduced which is the direct link of
+Acts to DD4hep. In the case for tracking relevant parameters in the DD4hep
+geometry description are changed (e.g. alignment) it will be automatically
+changed in Acts.
+
+Build
+-----
+
+The DD4hepPlugin is only build on demand. The DD4hepPlugin depends on the
+TGeoPlugin therefore both plugins need to be installed. During the cmake
+configuration the flags ``ACTS_BUILD_DD4HEP_PLUGIN=on`` and
+``ACTS_BUILD_TGEO_PLUGIN=on`` need to be set. In addition ROOT and DD4hep
+installations need to be available to cmake.
+
+Prerequisites
+-------------
+
+To guarantee a working translation from DD4hep input to Acts geometry the
+following conditions need to be met:
+
+* The detector needs to have a barrel-endcap structure: Every hierarchy of
+  subdetectors (e.g. PixelDetector, StripDetector,...) needs to be decomposed
+  into
+  
+  #. {barrel}
+  #. {barrel + 2 endcaps}
+  #. {2 endcaps} - in case there is no barrel at this stage (e.g. forward end caps)
+
+* If a hierachy is not only a single barrel but is decomposed of a barrel
+  and its corresponding endcaps they need to be grouped together in an
+  assembly using the ``DD4hep_SubdetectorAssembly`` constructor which is
+  provided by DD4hep. Example of usage in xml file (where Barrel0, nEndCap0
+  and pEndCap0 are sub detectors defined in the file ``PixelTracker.xml``):
+  
+  .. code-block:: xml
+  
+      <include ref="PixelTracker.xml"/>
+      <detectors>
+       <detector id="1" name="PixelTracker"type="DD4hep_SubdetectorAssembly"vis="BlueVisTrans">
+         <shape name="PixelEnvelope" type="Tube" rmin="Env0_rmin"rmax="Env0_rmax"dz="Env0_dz" material="Air"/>
+           <composite name="Barrel0"/>
+           <composite name="nEndCap0"/>
+           <composite name="pEndCap0"/>
+       </detector>
+      </detectors>
+
+  If a user wants to create his/her own constructor to group these
+  volumes together the type needs to be set to "compound".
+
+* Since the translation walks trough the ``DetElement`` tree the following
+  objects need to be declared as a DD4hep ``DetElement``:
+ 
+  * The subvolumes e.g. barrel, endcap, beampipe (they are usually build with
+    different DD4hep constructors and are therefore DD4hep ``DetElement``'s
+    per default).
+  * Layers when containing sensitive material and/or the layer should
+    carry material (which will be mapped on the layer if indicated), or
+    the layer is sensitive itself.
+  
+    .. note::
+    
+        the layer does not need to be a direct child of the volume (barrel or
+        endcap),it an be nested in substructures
+
+  * Sensitive detector modules
+    
+    .. note::
+      
+        The sensitive detector modules need to be placed in a layer however
+        it can be nested in substructures (can be a component of a modules)
+        i.e. it does not need to be a direct child of the layer
+
+* The Tracking geometry needs to be built from bottom to top to ensure
+  navigation. Therefore the different hierarchies need to be sorted ascending.
+  Per default the sub detectors are sorted by the id of their ``DetElement``.
+  In case another sorting needs to be applied, the users can provide their own
+  function.
+
+* The :class:`Acts::ActsExtension`'s need to be used during the detector
+  construction indicating if a ``DetElement``
+  
+  * is a barrel
+  * is an endcap
+  * is the beampipe
+  * is a layer
+
+There are two modes building the layers around the sensitive detector modules:
+
+* The ``DetElement`` containing the sensitive modules have a geometrical
+  shape.
+  
+  The boundaries of the layers in Acts are taken directly from the given shape.
+
+* The ``DetElement`` containing the sensitive modules have no specific shape
+  (assembly).
+  
+  The boundaries of the layers are calculated automatically by adding a
+  tolerance to the geometric extension of the contained surfaces. The
+  tolerances in r and z need to be set for every ``DetElement`` representing
+  layer using envelopeR and envelopeZ in :class:`Acts::ActsExtension`.
+
+The volumes are automatically build around the layers:
+
+* The boundaries for the volumes are calculated automatically by adding a
+  tolerance to the geometric extension of the contained layers. The
+  tolerance parameters ``layerEnvelopeR`` and ``layerEnvelopeZ`` need to be
+  set in the :func:`Acts::convertDD4hepDetector()` function.
+
+Furthermore parameters can be handed over for material mapping or the axes
+orientation of modules.
+
+Summing up the ``DetElement`` tree in DD4hep should have the following
+structure:
+
+.. image:: /figures/DD4hepPlugin_DetElementStructure.jpg
+
+It is also possible to translate a very simple detector geometry, which just
+consists of cylindrical (for a barrel) or disc (for endcaps) layers which either
+have material, or, are declared sensitive in dd4hep themselves without
+containing any detector modules.
+
+Usage
+-----
+
+To receive the :class:`Acts::TrackingGeometry` the user should use the global
+function :func:`Acts::convertDD4hepDetector()`, where he/she needs to hand over
+the DD4hep world ``DetElement``. For a valid translation the user needs to make
+sure, that all prerequisites described above are met and that the right
+:class:`Acts::ActsExtension`'s are added during the DD4hep construction.
diff --git a/doc/plugins/digitization.rst b/doc/plugins/digitization.rst
new file mode 100644
index 0000000000000000000000000000000000000000..639d36f7993548be8c9d60907743775d3206b615
--- /dev/null
+++ b/doc/plugins/digitization.rst
@@ -0,0 +1,6 @@
+Digitization plugin
+===================
+
+.. warning::
+    
+    This is just a placeholder.
diff --git a/doc/plugins/identification.rst b/doc/plugins/identification.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a57f1638adc8ae2bcda3b831ff12de5e26abbce7
--- /dev/null
+++ b/doc/plugins/identification.rst
@@ -0,0 +1,6 @@
+Identification plugin
+=====================
+
+.. warning::
+    
+    This is just a placeholder.
diff --git a/doc/plugins/plugins.rst b/doc/plugins/plugins.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7fe4305865c48fb142d9d948e59ecfa7ae837298
--- /dev/null
+++ b/doc/plugins/plugins.rst
@@ -0,0 +1,14 @@
+Plugins
+=======
+
+Plugins are optional modules that provide additional functionality or
+compatibility with external packages. Plugins are disabled by default and
+can be selectively enabled during compilation.
+
+.. toctree::
+    :maxdepth: 1
+
+    dd4hep
+    digitization
+    identification
+    tgeo
diff --git a/doc/plugins/tgeo.rst b/doc/plugins/tgeo.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ce8ca6b106a10eaa7af9cc726979e0c3effd43e7
--- /dev/null
+++ b/doc/plugins/tgeo.rst
@@ -0,0 +1,6 @@
+TGeo plugin
+===========
+
+.. warning::
+    
+    This is just a placeholder.
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..61a676e520721ffa65ec8c2623505dfa0fdb03c0
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,6 @@
+sphinx>=2.0
+sphinx_bootstrap_theme>=0.7
+sphinx_markdown_tables
+recommonmark
+breathe>=4.13
+exhale
diff --git a/doc/Grid_Axis.md b/doc/utilities/grid_axis.md
similarity index 94%
rename from doc/Grid_Axis.md
rename to doc/utilities/grid_axis.md
index c09c6baedf632bc89da18a3730efa93ee6296ea7..86539b9795ef4def02f2d587e302403e0aa562e4 100644
--- a/doc/Grid_Axis.md
+++ b/doc/utilities/grid_axis.md
@@ -1,4 +1,4 @@
-# `Grid` and Axis
+# Grid and axis
 
 The `Grid` template class provides a generic binned `Grid` implementation in $N$ dimensions. `Grid` accepts a variadic list of `Axis` types, where the number of axes equals the number of desired dimensions of the `Grid`.
 
@@ -6,39 +6,42 @@ The `Grid` template class provides a generic binned `Grid` implementation in $N$
 `Axis` accepts two template parameters:
 
 ```cpp
-template <AxisType type, 
+template <AxisType type,
           AxisBoundaryType bdt = AxisBoundaryType::Open>
 class Axis;
 ```
 
-where 
+where
 ```cpp
 enum class AxisBoundaryType { Open, Bound, Closed };
 enum class AxisType { Equidistant, Variable };
 ```
 
 ### AxisType
-`AxisType` defines whether an axis is fully determined by $x_\text{min}$, $x_\text{max}$ and $N_\text{bins}$, or if there are variable bin boundaries $x_i = \{x_1, \ldots x_N\}$. 
+
+`AxisType` defines whether an axis is fully determined by $x_\text{min}$, $x_\text{max}$ and $N_\text{bins}$, or if there are variable bin boundaries $x_i = \{x_1, \ldots x_N\}$.
 The axis boundaries and, if necessary, the bin boundaries are provided in the constructor.
 
 
-If at all possible, `Equidistant` is preferrable, since bin $b$ can then be calculated in constant time for given $x$ as 
+If at all possible, `Equidistant` is preferrable, since bin $b$ can then be calculated in constant time for given $x$ as
 
 $$b = \frac{\mathrm{floor}(x - x_\text{min})}{w} + 1$$
 
 where $b \in \{0, 1, \ldots N_\text{bins}\}$. If the type is `Variable`, a search for the correct bin is performed over the bin boundaries.
 
 ### AxisBoundaryType
-`AxisBoundaryType` steers how out-of-bounds lookups are handled. 
+
+`AxisBoundaryType` steers how out-of-bounds lookups are handled.
 There are three options:
 
-![The three different axis boundary types](figures/AxisBoundaryTypes.svg)
+![The three different axis boundary types](/figures/AxisBoundaryTypes.svg)
 
 - **Bound**: out-of-bounds lookups resolve to the closest valid bin.
 - **Open**: out-of-bounds lookups resolve to dedicated underflow and overflow bins.
 - **Closed**: out-of-bounds lookups wrap-around to the other side of the axis.
 
 ## Grid creation
+
 The types of the axes have to be known at compile-time, since they are provided to the `Grid` as template parameters. Thus the number of dimensions $N$ of the `Grid` is also fixed at compile-time.
 The axes can be any combination of the aforementioned variations.
 
@@ -51,6 +54,7 @@ where `T` is the value type that is stored in each bin. Instances of each axis a
 The `Grid` performs a lookup by recursively visiting each axis and having it perform a lookup in the corresponding component of the input vector. The lookup methods are templated on the input vector type, which only has to support component access. Transforming in and out of the local `Grid` reference frame is not handled by the `Grid`.
 
 ## Local vs global bin indices
+
 The underlying data structure of the `Grid` is a one-dimensional `std::vector<T>`, where `T` is the template parameter determining the stored value type. The index of this vector is referred to as the **global bin index**.
 The logical index structure, where each global bin is addressed by an $N$-dimensional vector of integers is called **local bin indices**. The two can be converted into one another using
 
@@ -63,6 +67,7 @@ size_t getGlobalBinIndex(const index_t& localBins) const;
 The local bin indices are always defined from 1 to $N_\text{bins}$ for the respective axis. Bins 0 and $N_\text{bins} + 1$ address the underflow and overflow bins, **which are always present, even if `AxisBoundaryType != Open`**.
 
 ## Finding neighbors
+
 The `Grid` can determine the number of neighbors around a given bin. This done by first converting the global bin index to local bin indices, and then varying the local bin indices in each dimension. At this stage, each Axis gets to decide, which indices are considered neighbors, which differs depending on `AxisBinningType`. `Open` considers the underflow and overflow bins, while `Bound` does not. `Closed` considers bins on the other side of the axis.
 The resulting neighbor combination around bin *B* might look like
 
diff --git a/doc/utilities/logging.rst b/doc/utilities/logging.rst
new file mode 100644
index 0000000000000000000000000000000000000000..cd4ef3220dc0dccc50cd8154fc344f19d6daf3f3
--- /dev/null
+++ b/doc/utilities/logging.rst
@@ -0,0 +1,95 @@
+Logging
+=======
+
+The Acts logging facility supports several severity levels which allow you
+to control the amount of information displayed at run-time. Logger objects
+can easily be created using the :func:`Acts::getDefaultLogger` function which
+should be sufficient to get you started. In case you need more customized
+debug output, you can make use of the output decorators defined in
+:any:`Acts::Logging` or even write your own implementation of
+:class:`Acts::Logging::OutputDecorator`. In order to add debug messages to your program, you should use the provided macros for the different severity levels:
+
+.. code-block::
+
+    ACTS_VERBOSE(...);
+    ACTS_DEBUG(...);
+    ACTS_INFO(...);
+    ACTS_WARNING(...);
+    ACTS_ERROR(...);
+    ACTS_FATAL(...);
+
+All of these macros require that a function ``logger()`` returning a
+:class:`Acts::Logger` object is available in the scope in which the macros are
+used. Inside classes containing an :class:`Acts::Logger` object as member
+variable, this could be achieved by providing a private class method called
+``logger()`` (for an example see e.g.
+:func:`Acts::CylinderVolumeBuilder::logger`). Inside free functions or member
+methods with local logger objects, the same effect can be achieved by using the
+macro ``ACTS_LOCAL_LOGGER(...)`` which is provided for your convenience.
+
+Code example illustrating the usage:
+
+.. code-block::
+
+    #include <fstream>
+    #include <memory>
+    
+    #include "Acts/Utilities/Logger.hpp"
+    
+    void myFunction() {
+      // open the logfile
+      std::ofstream logfile("log.txt");
+      // setup a logger instance for >= INFO messages, streaming into the log file
+      // make sure you do NOT call the variable 'logger'
+      std::unique_ptr<const Acts::Logger> myLogger
+          = Acts::getDefaultLogger("MyLogger", Acts::Logging::INFO, &logfile);
+      // make sure the Acts debug macros can work with your logger
+      ACTS_LOCAL_LOGGER(myLogger);
+      ACTS_VERBOSE("This message will not appear in the logfile.");
+      ACTS_INFO("But this one will: Hello World!");
+      // do not forget to close the logfile
+      logfile.close();
+    }
+
+In case you are using Acts in another framework which comes with its own
+logging facility (e.g. Gaudi) you can pipe the logging output from Acts
+tools and algorithms to your framework's logging system by supplying different
+implementations of:
+
+*   :class:`Acts::Logging::OutputFilterPolicy` (for mapping logging levels)
+*   :class:`Acts::Logging::OutputPrintPolicy` (for passing the Acts output
+    to your internal logging system)
+
+Since Acts makes extensive use of :func:`Acts::getDefaultLogger()` to provide
+sufficient information for debugging, you would need to provide a modified
+implementation of this function (using your output filter and printing policies)
+to also pipe this output to your framework. Changing the implementation of an
+already defined function is a non-trivial task in C++. We recommend the
+following approach using the possibility to inject custom code by pre-loading
+shared libraries with ``LD_PRELOAD``. You need to provide an appropriate
+implementation for a function of the following signature into a separate source
+file and compile it in a shared library
+
+.. code-block::
+
+    namespace Acts {
+    std::unique_ptr<const Logger> getDefaultLogger(const std::string&,
+                                                   const Logging::Level&,
+                                                   std::ostream*);
+    }
+
+Then you can run your executable, which uses Acts tools and algorithms, in
+the following way (tested under Unix)
+
+.. code-block:: console
+
+    LD_PRELOAD=<YOUR_SHARED_LIBRARY> path/to/your/exectuable
+
+For an example have a look at CustomDefaultLogger.cpp which you can use as
+follows:
+
+.. code-block:: console
+
+    cd <ACTS/INSTALL/DIRECTORY>
+    source bin/setup.sh
+    LD_PRELOAD=lib/libActsCustomLogger.so bin/Examples/ActsGenericDetector
diff --git a/doc/utilities/units.rst b/doc/utilities/units.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1c20bf45e60b916351a386913d2a6d0289f9b024
--- /dev/null
+++ b/doc/utilities/units.rst
@@ -0,0 +1,117 @@
+Unit definitions and conversions
+================================
+
+All physical quantities have both a numerical value and a unit. For the
+computations we always choose a particular unit for a given physical quantity
+so we only need to consider the numerical values as such. The chosen base unit
+for a particular physical dimension, e.g. length, time, or energy, within this
+code base is called the native unit. The base units should be chosen such that
+they are internally consistent, require the least amount of explicit
+conversion factors (ideally none at all), and have typical numerical values
+close to unity to reduce numerical issues.
+
+Here, the following native units are used:
+
+*   Length is expressed in mm.
+*   Time is expressed in [speed-of-light * time] == mm. A consequence
+    of this choice is that the speed-of-light expressed in native units
+    is 1.
+*   Angles are expressed in radian.
+*   Energy, mass, and momentum are all expressed in GeV (consistent with
+    a speed-of-light == 1).
+*   Electric charge is expressed in e, i.e. units of the elementary charge.
+*   The magnetic field is expressed in GeV/(e*mm). The magnetic field
+    connects momentum to length, e.g. in SI units the radius of a charged
+    particle trajectory in a constant magnetic field is given by
+
+    .. math::
+        
+        radius = - (momentum / charge) / field
+
+    With the chosen magnetic field unit the expression above stays the
+    same and no additional conversion factors are necessary.
+
+Depending on the context a physical quantity might not be given in the native
+units. In this case we need to convert to the native unit first before the value
+can be used. The necessary conversion factors are defined in
+:ref:`namespace_Acts__UnitConstants`. Multiplying a value with the unit constant
+produces the equivalent value in the native unit, e.g.
+
+.. code-block:: cpp
+
+    double length = 1 * Acts::UnitConstants::m;       // length == 1000.0
+    double momentum = 100 * Acts::UnitConstants::MeV; // momentum == 0.1
+
+The conversion of a value in native units into the equivalent value in a
+specific other unit is computed by dividing with the relevant unit, e.g.
+
+.. code-block:: cpp
+
+    double length = 10.0;                               // native units mm
+    double lengthInM = length / Acts::UnitConstants::m; // == 0.01;
+
+To further simplify the usage, physical quantities can also be expressed via
+`C++ user literals <https://en.cppreference.com/w/cpp/language/user_literal>`_
+define in :ref:`namespace_Acts__UnitLiterals`. This allows us to
+express quantities in a concise way:
+
+.. code-block:: cpp
+
+    using namespace Acts::UnitLiterals;
+    
+    double length = 1_m;                     // == 1000.0
+    double momentum = 1.25_TeV;              // == 1250.0
+    double lengthInUm = length / 1_um;       // == 1000000.0
+    double momentumInMeV = momentum / 1_MeV; // == 1250000.0
+
+Since this requires a namespace import of :ref:`namespace_Acts__UnitLiterals` it
+should not be used in headers since it would (accidentally) modify the namespace
+wherever the header is included.
+
+To ensure consistent computations and results the following guidelines **must**
+be followed when handling physical quantities with units:
+
+*   All unqualified numerical values, i.e. without a unit, are assumed to
+    be expressed in the relevant native unit, e.g. mm for lengths or GeV
+    for energy/momentum.
+*   If a variable stores a physical quantity in a specific unit that is
+    not the native unit, clearly mark this in the variable, i.e.
+
+    .. code-block:: cpp
+    
+        double momentum = 100.0; // momentum is stored as native unit GeV
+        double momentumInMeV = 10.0; // would be 0.01 in native units
+
+*   All input values must be given as ``numerical_value * unit_constant`` or
+    equivalently using the unit literals as ``value_unit``. The resulting
+    unqualified numerical value will be automatically converted to the
+    native unit.
+*   To output an unqualified numerical value in the native units as a
+    numerical value in a specific unit divide by the unit constants as
+    ``numerical_value / unit_constant`` or using the unit literals as
+    ``value / 1_unit``.
+
+Examples:
+
+.. code-block:: cpp
+
+    #include <Acts/include/Utilities/Units.hpp>
+    using namespace Acts::UnitLiterals;
+    
+    // define input values w/ units (via unit constants)
+    double width    = 12 * Acts::UnitConstants::mm;
+    double mmuon    = 105.7 * Acts::UnitConstants::MeV;
+    // define input values w/ units (via unit user literals)
+    double length   = 23_cm;
+    double time     = 1214.2_ns;
+    double angle    = 123_degree;
+    double momentum = 2.5_TeV;
+    double mass     = 511_keV;
+    double velocity = 345_m / 1_s;
+    double bfield   = 3.9_T;
+    
+    // convert output values (via unit constants)
+    doube t_in_ns    = trackPars.time() / Acts::UnitConstants::ns;
+    // convert output values (via unit user literals)
+    double x_in_mm   = trackPars.position().x() / 1_mm;
+    double pt_in_TeV = trackPars.momentum().pT() / 1_TeV;
diff --git a/doc/utilities/utilities.rst b/doc/utilities/utilities.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ea22c304a3f5b104c610837713dd6c1b18c9fa16
--- /dev/null
+++ b/doc/utilities/utilities.rst
@@ -0,0 +1,9 @@
+Utilities
+=========
+
+.. toctree::
+    :maxdepth: 1
+
+    grid_axis
+    logging
+    units