diff --git a/.gitignore b/.gitignore
index b3e51ff22de13b38934435e60406c74287200c2c..247b01873778a0a9f9c0102a2c81ea95917f6dce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,9 +7,10 @@ parts
 .installed.cfg
 .mr.developer.cfg
 *.egg-info
-src
 develop-eggs
 sphinx
 dist
 build/
 record.txt
+.gitlab-ci-local*
+html/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 845b719f2378d396a8b75296a68d1e32c840e7c7..9a479703105d5241942420e9cfdf0867cc3183e5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1 +1,4 @@
-include: 'https://gitlab.idiap.ch/bob/bob.devtools/raw/master/bob/devtools/data/gitlab-ci/single-package.yaml'
+include:
+  - project: bob/dev-profile
+    ref: main
+    file: gitlab/python.yml
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 6352dfc534c96dd6ea1c8bc7c061f4745b199881..49337196592599a11942ecd8fc24a4230c5a196d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -2,20 +2,20 @@
 # See https://pre-commit.com/hooks.html for more hooks
 repos:
   - repo: https://github.com/timothycrosley/isort
-    rev: 5.10.1
+    rev: 5.12.0
     hooks:
       - id: isort
         args: [--settings-path, "pyproject.toml"]
   - repo: https://github.com/psf/black
-    rev: 22.3.0
+    rev: 23.1.0
     hooks:
       - id: black
-  - repo: https://gitlab.com/pycqa/flake8
-    rev: 3.9.2
+  - repo: https://github.com/pycqa/flake8
+    rev: 6.0.0
     hooks:
       - id: flake8
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.2.0
+    rev: v4.4.0
     hooks:
       - id: check-ast
       - id: check-case-conflict
diff --git a/MANIFEST.in b/MANIFEST.in
index 9434bd000526c48395849d6e3c8f92dd46245b41..c68f21a3fd823c7dc15f9ca623403c961b4831e4 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,3 @@
-include README.rst bootstrap-buildout.py buildout.cfg COPYING version.txt requirements.txt
+include README.rst bootstrap-buildout.py COPYING
 recursive-include doc *.py *.rst
 recursive-include bob/fusion/base/test/data scores-*
diff --git a/README.rst b/README.rst
index 3104908f46708ec06b7ddcf778cb3e6b3fb682cb..5b9fee362af9ab9538bbcd13781fc85fa330d13f 100644
--- a/README.rst
+++ b/README.rst
@@ -2,11 +2,11 @@
 .. Tue Jan 31 17:29:53 CET 2017
 
 .. image:: https://img.shields.io/badge/docs-latest-orange.svg
-   :target: https://www.idiap.ch/software/bob/docs/bob/bob.fusion.base/master/index.html
+   :target: https://www.idiap.ch/software/bob/docs/bob/bob.fusion.base/master/sphinx/index.html
 .. image:: https://gitlab.idiap.ch/bob/bob.fusion.base/badges/master/pipeline.svg
    :target: https://gitlab.idiap.ch/bob/bob.fusion.base/commits/master
 .. image:: https://gitlab.idiap.ch/bob/bob.fusion.base/badges/master/coverage.svg
-   :target: https://gitlab.idiap.ch/bob/bob.fusion.base/commits/master
+   :target: https://www.idiap.ch/software/bob/docs/bob/bob.fusion.base/master/coverage/
 .. image:: https://img.shields.io/badge/gitlab-project-0000c0.svg
    :target: https://gitlab.idiap.ch/bob/bob.fusion.base
 
diff --git a/buildout.cfg b/buildout.cfg
deleted file mode 100644
index 44d8d9994710473b419b074376ca3930d8de50d9..0000000000000000000000000000000000000000
--- a/buildout.cfg
+++ /dev/null
@@ -1,14 +0,0 @@
-; vim: set fileencoding=utf-8 :
-; Tue Jan 31 17:22:48 CET 2017
-
-[buildout]
-parts = scripts
-develop = .
-eggs = bob.fusion.base
-extensions = bob.buildout
-newest = false
-verbose = true
-
-[scripts]
-recipe = bob.buildout:scripts
-dependent-scripts = true
diff --git a/conda/meta.yaml b/conda/meta.yaml
index 6739adae253282464e411ac7d5f29b899cdd4d94..b6efea74d7b719d274d997eb492d2373f5ded88b 100644
--- a/conda/meta.yaml
+++ b/conda/meta.yaml
@@ -1,27 +1,27 @@
-{% set name = 'bob.fusion.base' %}
-{% set project_dir = environ.get('RECIPE_DIR') + '/..' %}
+{% set data = load_file_data(RECIPE_DIR + '/../pyproject.toml') %}
+{% set name = data['project']['name'] %}
 
 package:
   name: {{ name }}
-  version: {{ environ.get('BOB_PACKAGE_VERSION', '0.0.1') }}
+  version: {{ data['project']['version'] }}
+
+source:
+  path: ..
 
 build:
+  noarch: python
   number: {{ environ.get('BOB_BUILD_NUMBER', 0) }}
   run_exports:
     - {{ pin_subpackage(name) }}
   script:
-    - cd {{ project_dir }}
-    {% if environ.get('BUILD_EGG') %}
-    - "{{ PYTHON }} setup.py sdist --formats=zip"
-    {% endif %}
-    - "{{ PYTHON }} -m pip install . -vv"
+    - "{{ PYTHON }} -m pip install {{ SRC_DIR }} -vv"
 
 requirements:
   host:
     - python {{ python }}
     - setuptools {{ setuptools }}
     - pip {{ pip }}
-    - bob.extension
+    - clapp
     - bob.measure
     - bob.learn.em
     - bob.bio.base
@@ -31,6 +31,10 @@ requirements:
   run:
     - python
     - setuptools
+    - clapp
+    - bob.measure
+    - bob.learn.em
+    - bob.bio.base
     - {{ pin_compatible('matplotlib') }}
     - {{ pin_compatible('numpy') }}
     - {{ pin_compatible('scikit-learn') }}
@@ -39,24 +43,11 @@ test:
   imports:
     - {{ name }}
   commands:
-    - bob fusion fuse --help
-    - bob fusion resource --help
-    - bob fusion resource
-    - bob fusion boundary --help
-    - pytest --verbose --cov {{ name }} --cov-report term-missing --cov-report html:{{ project_dir }}/sphinx/coverage --cov-report xml:{{ project_dir }}/coverage.xml --pyargs {{ name }}
-    - sphinx-build -aEW {{ project_dir }}/doc {{ project_dir }}/sphinx
-    - sphinx-build -aEb doctest {{ project_dir }}/doc sphinx
     - conda inspect linkages -p $PREFIX {{ name }}  # [not win]
     - conda inspect objects -p $PREFIX {{ name }}  # [osx]
-  requires:
-    - pytest {{ pytest }}
-    - pytest-cov {{ pytest_cov }}
-    - coverage {{ coverage }}
-    - sphinx {{ sphinx }}
-    - sphinx_rtd_theme {{ sphinx_rtd_theme }}
 
 about:
-  home: https://www.idiap.ch/software/bob/
-  license: GPL-3.0
-  summary: Score fusion in biometric and pad experiments
+  home: {{ data['project']['urls']['homepage'] }}
+  summary: {{ data['project']['description'] }}
+  license: {{ data['project']['license']['text'] }}
   license_family: GPL
diff --git a/doc/conf.py b/doc/conf.py
index eb13ae8540c4499b18d2a487529d42a365e69e68..1f6eebd30c904edcae5069d696875c6a97362270 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -24,7 +24,7 @@ extensions = [
     "sphinx.ext.napoleon",
     "sphinx.ext.viewcode",
     "sphinx.ext.mathjax",
-    # 'matplotlib.sphinxext.plot_directive'
+    "auto_intersphinx",
 ]
 
 # Be picky about warnings
@@ -232,14 +232,11 @@ autodoc_default_options = {
     "show-inheritance": True,
 }
 
-# For inter-documentation mapping:
-from bob.extension.utils import link_documentation, load_requirements
-
-sphinx_requirements = "extra-intersphinx.txt"
-if os.path.exists(sphinx_requirements):
-    intersphinx_mapping = link_documentation(
-        additional_packages=["python", "numpy"]
-        + load_requirements(sphinx_requirements)
-    )
-else:
-    intersphinx_mapping = link_documentation()
+auto_intersphinx_packages = [
+    ("python", "3"),
+    "numpy",
+    "scikit-learn",
+    "bob.pad.base",
+    "bob.bio.base",
+]
+auto_intersphinx_catalog = "catalog.json"
diff --git a/pyproject.toml b/pyproject.toml
index b738dc847ff9705c5769673db7415f2eb9a75f4d..f852bb999c6656c486d127b9003dfe05081b3783 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,7 +1,91 @@
 [build-system]
-    requires = ["setuptools", "wheel", "bob.extension"]
+    requires = ["setuptools>=61.0.0", "wheel"]
     build-backend = "setuptools.build_meta"
 
+[project]
+    name = "bob.fusion.base"
+    version = "0.1.5b0"
+    requires-python = ">=3.9"
+    description = "Score fusion in biometric and pad experiments"
+    dynamic = ["readme"]
+    license = {text = "GPLv3 License"}
+    authors = [
+    {name = "Amir Mohammadi", email = "amir.mohammadi@idiap.ch"},
+    ]
+    keywords = ["bob", "score fusion", "evaluation", "biometric"]
+
+    classifiers=[
+        "Framework :: Bob",
+        "Development Status :: 3 - Alpha",
+        "Intended Audience :: Developers",
+        "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
+        "Natural Language :: English",
+        "Programming Language :: Python",
+        "Topic :: Scientific/Engineering :: Artificial Intelligence",
+    ]
+    dependencies = [
+        "setuptools",
+        "numpy",
+        "clapp",
+        "bob.measure",
+        "bob.learn.em",
+        "bob.bio.base",
+        "scikit-learn",
+        "matplotlib",
+    ]
+
+[project.urls]
+    documentation = "https://www.idiap.ch/software/bob/docs/bob/bob.fusion.base/stable/"
+    homepage      = "https://pypi.org/project/bob.fusion.base/"
+    repository    = "https://gitlab.idiap.ch/bob/bob.fusion.base"
+    changelog     = "https://gitlab.idiap.ch/bob/bob.fusion.base/-/releases"
+
+[project.optional-dependencies]
+    qa = ["pre-commit"]
+    doc = [
+        "sphinx",
+        "sphinx_rtd_theme",
+        "sphinx-autodoc-typehints",
+        "auto-intersphinx",
+        "sphinxcontrib-programoutput",
+        "bob.pad.base",
+        ]
+    test = [
+        "pytest",
+        "pytest-cov",
+        "coverage",
+        ]
+
+[tool.setuptools]
+    zip-safe = false
+    package-dir = {"" = "src"}
+
+[tool.setuptools.dynamic]
+    readme = {file = "README.rst"}
+
+[project.entry-points."bob.cli"]
+    fusion = "bob.fusion.base.script.fusion:fusion"
+
+[project.entry-points."bob.fusion.cli"]
+    fuse     = "bob.fusion.base.script.fuse:fuse"
+    resource = "bob.fusion.base.script.resource:resource"
+    boundary = "bob.fusion.base.script.boundary:boundary"
+
+[project.entry-points."bob.fusion.algorithm"]
+    mean       = "bob.fusion.base.config.algorithm.mean:algorithm"
+    mean-tanh  = "bob.fusion.base.config.algorithm.mean:algorithm_tanh"
+    llr        = "bob.fusion.base.config.algorithm.llr_skl:algorithm"
+    llr-tanh   = "bob.fusion.base.config.algorithm.llr_skl:algorithm_tanh"
+    plr-2      = "bob.fusion.base.config.algorithm.plr_2:algorithm"
+    plr-2-tanh = "bob.fusion.base.config.algorithm.plr_2:algorithm_tanh"
+    plr-3      = "bob.fusion.base.config.algorithm.plr_3:algorithm"
+    plr-3-tanh = "bob.fusion.base.config.algorithm.plr_3:algorithm_tanh"
+    gmm        = "bob.fusion.base.config.algorithm.gmm:algorithm"
+    gmm-tanh   = "bob.fusion.base.config.algorithm.gmm:algorithm_tanh"
+
+[tool.distutils.bdist_wheel]
+    universal = true
+
 [tool.isort]
     profile = "black"
     line_length = 80
@@ -10,3 +94,15 @@
 
 [tool.black]
     line-length = 80
+
+[tool.coverage.run]
+    relative_files = true
+
+[tool.pytest.ini_options]
+    addopts = [
+        "--import-mode=append",
+        "--cov-report=term-missing",
+        "--cov=bob.fusion.base",
+    ]
+    junit_logging = "all"
+    junit_log_passing_tests = false
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index dca2c71dd8d1c13157dcdb5440e8339f32699dc7..0000000000000000000000000000000000000000
--- a/requirements.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-setuptools
-numpy
-bob.extension
-bob.measure
-bob.learn.em
-bob.bio.base
-scikit-learn # Used for classifiers and pre-processors.
-matplotlib   # for plotting
diff --git a/setup.py b/setup.py
index ffa14e5f7961f589e5f8383ac8aa3566b43e486b..3a3aaadbd1b7a7371f5208fe978855323b3c5291 100644
--- a/setup.py
+++ b/setup.py
@@ -1,59 +1,6 @@
 #!/usr/bin/env python
 # vim: set fileencoding=utf-8 :
 
-from setuptools import dist, setup
+from setuptools import setup
 
-dist.Distribution(dict(setup_requires=["bob.extension"]))
-
-from bob.extension.utils import find_packages, load_requirements
-
-install_requires = load_requirements()
-
-setup(
-    name="bob.fusion.base",
-    version=open("version.txt").read().rstrip(),
-    description="Score fusion in biometric and pad experiments",
-    url="https://gitlab.idiap.ch/bob/bob.fusion.base",
-    license="GPLv3",
-    author="Amir Mohammadi",
-    author_email="amir.mohammadi@idiap.ch",
-    keywords="bob, score fusion, evaluation, biometric",
-    long_description=open("README.rst").read(),
-    packages=find_packages(),
-    include_package_data=True,
-    zip_safe=False,
-    install_requires=install_requires,
-    entry_points={
-        # main entry for bob fusion cli
-        "bob.cli": [
-            "fusion = bob.fusion.base.script.fusion:fusion",
-        ],
-        # bob fusion scripts
-        "bob.fusion.cli": [
-            "fuse = bob.fusion.base.script.fuse:fuse",
-            "resource = bob.fusion.base.script.resource:resource",
-            "boundary = bob.fusion.base.script.boundary:boundary",
-        ],
-        "bob.fusion.algorithm": [
-            "mean         = bob.fusion.base.config.algorithm.mean:algorithm",
-            "mean-tanh    = bob.fusion.base.config.algorithm.mean:algorithm_tanh",
-            "llr          = bob.fusion.base.config.algorithm.llr_skl:algorithm",
-            "llr-tanh     = bob.fusion.base.config.algorithm.llr_skl:algorithm_tanh",
-            "plr-2        = bob.fusion.base.config.algorithm.plr_2:algorithm",
-            "plr-2-tanh   = bob.fusion.base.config.algorithm.plr_2:algorithm_tanh",
-            "plr-3        = bob.fusion.base.config.algorithm.plr_3:algorithm",
-            "plr-3-tanh   = bob.fusion.base.config.algorithm.plr_3:algorithm_tanh",
-            "gmm          = bob.fusion.base.config.algorithm.gmm:algorithm",
-            "gmm-tanh     = bob.fusion.base.config.algorithm.gmm:algorithm_tanh",
-        ],
-    },
-    classifiers=[
-        "Framework :: Bob",
-        "Development Status :: 3 - Alpha",
-        "Intended Audience :: Developers",
-        "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
-        "Natural Language :: English",
-        "Programming Language :: Python",
-        "Topic :: Scientific/Engineering :: Artificial Intelligence",
-    ],
-)
+setup()
diff --git a/bob/__init__.py b/src/bob/__init__.py
similarity index 100%
rename from bob/__init__.py
rename to src/bob/__init__.py
diff --git a/bob/fusion/__init__.py b/src/bob/fusion/__init__.py
similarity index 100%
rename from bob/fusion/__init__.py
rename to src/bob/fusion/__init__.py
diff --git a/bob/fusion/base/__init__.py b/src/bob/fusion/base/__init__.py
similarity index 52%
rename from bob/fusion/base/__init__.py
rename to src/bob/fusion/base/__init__.py
index 0a5e9125e0383d12ac32260a7be39ebd799f2ce0..63f8744e1f789c0a5cbdb588448e57d5854e4386 100644
--- a/bob/fusion/base/__init__.py
+++ b/src/bob/fusion/base/__init__.py
@@ -1,12 +1,4 @@
 from . import algorithm, config, preprocessor, script, tools  # noqa: F401
 
-
-def get_config():
-    """Returns a string containing the configuration information."""
-    import bob.extension
-
-    return bob.extension.get_config(__name__)
-
-
 # gets sphinx autodoc done right - don't remove it
 __all__ = [_ for _ in dir() if not _.startswith("_")]
diff --git a/bob/fusion/base/algorithm/AND.py b/src/bob/fusion/base/algorithm/AND.py
similarity index 100%
rename from bob/fusion/base/algorithm/AND.py
rename to src/bob/fusion/base/algorithm/AND.py
diff --git a/bob/fusion/base/algorithm/Algorithm.py b/src/bob/fusion/base/algorithm/Algorithm.py
similarity index 100%
rename from bob/fusion/base/algorithm/Algorithm.py
rename to src/bob/fusion/base/algorithm/Algorithm.py
diff --git a/bob/fusion/base/algorithm/AlgorithmBob.py b/src/bob/fusion/base/algorithm/AlgorithmBob.py
similarity index 100%
rename from bob/fusion/base/algorithm/AlgorithmBob.py
rename to src/bob/fusion/base/algorithm/AlgorithmBob.py
diff --git a/bob/fusion/base/algorithm/Empty.py b/src/bob/fusion/base/algorithm/Empty.py
similarity index 100%
rename from bob/fusion/base/algorithm/Empty.py
rename to src/bob/fusion/base/algorithm/Empty.py
diff --git a/bob/fusion/base/algorithm/GMM.py b/src/bob/fusion/base/algorithm/GMM.py
similarity index 98%
rename from bob/fusion/base/algorithm/GMM.py
rename to src/bob/fusion/base/algorithm/GMM.py
index 0c11abf90126eecce975538bffd090474c731e18..b4b6d6109ff2a13b76341b686bc74624cbc0577b 100644
--- a/bob/fusion/base/algorithm/GMM.py
+++ b/src/bob/fusion/base/algorithm/GMM.py
@@ -10,7 +10,7 @@ from bob.learn.em import GMMMachine
 
 from .AlgorithmBob import AlgorithmBob
 
-logger = logging.getLogger("bob.fusion.base")
+logger = logging.getLogger(__name__)
 
 
 class GMM(AlgorithmBob):
diff --git a/bob/fusion/base/algorithm/Weighted_Sum.py b/src/bob/fusion/base/algorithm/Weighted_Sum.py
similarity index 100%
rename from bob/fusion/base/algorithm/Weighted_Sum.py
rename to src/bob/fusion/base/algorithm/Weighted_Sum.py
diff --git a/bob/fusion/base/algorithm/__init__.py b/src/bob/fusion/base/algorithm/__init__.py
similarity index 100%
rename from bob/fusion/base/algorithm/__init__.py
rename to src/bob/fusion/base/algorithm/__init__.py
diff --git a/bob/fusion/base/config/__init__.py b/src/bob/fusion/base/config/__init__.py
similarity index 100%
rename from bob/fusion/base/config/__init__.py
rename to src/bob/fusion/base/config/__init__.py
diff --git a/bob/fusion/base/config/algorithm/__init__.py b/src/bob/fusion/base/config/algorithm/__init__.py
similarity index 100%
rename from bob/fusion/base/config/algorithm/__init__.py
rename to src/bob/fusion/base/config/algorithm/__init__.py
diff --git a/bob/fusion/base/config/algorithm/gmm.py b/src/bob/fusion/base/config/algorithm/gmm.py
similarity index 100%
rename from bob/fusion/base/config/algorithm/gmm.py
rename to src/bob/fusion/base/config/algorithm/gmm.py
diff --git a/bob/fusion/base/config/algorithm/llr_skl.py b/src/bob/fusion/base/config/algorithm/llr_skl.py
similarity index 100%
rename from bob/fusion/base/config/algorithm/llr_skl.py
rename to src/bob/fusion/base/config/algorithm/llr_skl.py
diff --git a/bob/fusion/base/config/algorithm/mean.py b/src/bob/fusion/base/config/algorithm/mean.py
similarity index 100%
rename from bob/fusion/base/config/algorithm/mean.py
rename to src/bob/fusion/base/config/algorithm/mean.py
diff --git a/bob/fusion/base/config/algorithm/plr_2.py b/src/bob/fusion/base/config/algorithm/plr_2.py
similarity index 100%
rename from bob/fusion/base/config/algorithm/plr_2.py
rename to src/bob/fusion/base/config/algorithm/plr_2.py
diff --git a/bob/fusion/base/config/algorithm/plr_3.py b/src/bob/fusion/base/config/algorithm/plr_3.py
similarity index 100%
rename from bob/fusion/base/config/algorithm/plr_3.py
rename to src/bob/fusion/base/config/algorithm/plr_3.py
diff --git a/bob/fusion/base/preprocessor/Tanh.py b/src/bob/fusion/base/preprocessor/Tanh.py
similarity index 100%
rename from bob/fusion/base/preprocessor/Tanh.py
rename to src/bob/fusion/base/preprocessor/Tanh.py
diff --git a/bob/fusion/base/preprocessor/ZNorm.py b/src/bob/fusion/base/preprocessor/ZNorm.py
similarity index 100%
rename from bob/fusion/base/preprocessor/ZNorm.py
rename to src/bob/fusion/base/preprocessor/ZNorm.py
diff --git a/bob/fusion/base/preprocessor/__init__.py b/src/bob/fusion/base/preprocessor/__init__.py
similarity index 100%
rename from bob/fusion/base/preprocessor/__init__.py
rename to src/bob/fusion/base/preprocessor/__init__.py
diff --git a/bob/fusion/base/script/__init__.py b/src/bob/fusion/base/script/__init__.py
similarity index 100%
rename from bob/fusion/base/script/__init__.py
rename to src/bob/fusion/base/script/__init__.py
diff --git a/bob/fusion/base/script/boundary.py b/src/bob/fusion/base/script/boundary.py
similarity index 98%
rename from bob/fusion/base/script/boundary.py
rename to src/bob/fusion/base/script/boundary.py
index 55caad6a338c0c9c1b5cce2bd175569b9c72e36e..728ff9c1a19d21bd130ef31a78f406d0fa1214fb 100644
--- a/bob/fusion/base/script/boundary.py
+++ b/src/bob/fusion/base/script/boundary.py
@@ -5,8 +5,9 @@ import logging
 import click
 import numpy as np
 
+from clapp.click import verbosity_option
+
 from bob.bio.base.score import load_score
-from bob.extension.scripts.click_helper import verbosity_option
 
 from ..algorithm import Algorithm
 from ..tools import (
@@ -185,7 +186,7 @@ $ bob fusion boundary -vvv {sys1,sys2}/scores-eval -m /path/to/Model.pkl
     help="If True, it will skip checking for the consistency "
     "between scores.",
 )
-@verbosity_option()
+@verbosity_option(logger)
 def boundary(
     scores,
     model_file,
diff --git a/bob/fusion/base/script/fuse.py b/src/bob/fusion/base/script/fuse.py
similarity index 98%
rename from bob/fusion/base/script/fuse.py
rename to src/bob/fusion/base/script/fuse.py
index 76131141b8e12fbc693f682591850b1e3cdd34a3..c97fe1c8c5de723416671aadbc29ce4a2788aa62 100644
--- a/bob/fusion/base/script/fuse.py
+++ b/src/bob/fusion/base/script/fuse.py
@@ -9,9 +9,10 @@ import sys
 import click
 import numpy as np
 
+from clapp.click import ResourceOption, verbosity_option
+
 from bob.bio.base import utils
 from bob.bio.base.score import dump_score, load_score
-from bob.extension.scripts.click_helper import ResourceOption, verbosity_option
 
 from ..tools import (
     check_consistency,
@@ -33,7 +34,7 @@ def write_info(
     model_file,
     skip_check,
     force,
-    **kwargs
+    **kwargs,
 ):
     info = """
 scores: %s
@@ -95,7 +96,6 @@ def routine_fusion(
     min_file_size=1000,
     do_training=True,
 ):
-
     # load the model if model_file exists and no training data was provided
     if os.path.exists(model_file) and not do_training:
         logger.info("Loading the algorithm from %s", model_file)
@@ -231,7 +231,7 @@ $ bob fusion fuse -vvv sys_bio/scores-{world,dev,eval} sys_pad/scores-{train,dev
     show_default=True,
     help="Whether to overwrite existing files.",
 )
-@verbosity_option()
+@verbosity_option(logger)
 def fuse(
     scores,
     algorithm,
@@ -240,7 +240,7 @@ def fuse(
     model_file,
     skip_check,
     force,
-    **kwargs
+    **kwargs,
 ):
     """Score fusion
 
@@ -288,7 +288,7 @@ def fuse(
         model_file,
         skip_check,
         force,
-        **kwargs
+        **kwargs,
     )
 
     """Do the actual fusion."""
diff --git a/bob/fusion/base/script/fusion.py b/src/bob/fusion/base/script/fusion.py
similarity index 82%
rename from bob/fusion/base/script/fusion.py
rename to src/bob/fusion/base/script/fusion.py
index f30807b4eb109c2a53d4572bd2e8b3ea4a2e5345..456f8057a3d8def720d254614172d5e5ed3181b2 100644
--- a/bob/fusion/base/script/fusion.py
+++ b/src/bob/fusion/base/script/fusion.py
@@ -3,10 +3,9 @@
 import click
 import pkg_resources
 
+from clapp.click import AliasedGroup
 from click_plugins import with_plugins
 
-from bob.extension.scripts.click_helper import AliasedGroup
-
 
 @with_plugins(pkg_resources.iter_entry_points("bob.fusion.cli"))
 @click.group(cls=AliasedGroup)
diff --git a/bob/fusion/base/script/resource.py b/src/bob/fusion/base/script/resource.py
similarity index 90%
rename from bob/fusion/base/script/resource.py
rename to src/bob/fusion/base/script/resource.py
index 7ed23e9e78672113f287187a3ac45e5aaa0e7ac0..bef0aac4d7b84d2ea0cf551b0d474644d1981e32 100644
--- a/bob/fusion/base/script/resource.py
+++ b/src/bob/fusion/base/script/resource.py
@@ -6,9 +6,9 @@ import logging
 
 import click
 
-import bob.bio.base
+from clapp.click import verbosity_option
 
-from bob.extension.scripts.click_helper import verbosity_option
+import bob.bio.base
 
 logger = logging.getLogger(__name__)
 
@@ -26,7 +26,7 @@ $ bob fusion resource -v
     multiple=True,
     help="List only the resources from these packages.",
 )
-@verbosity_option()
+@verbosity_option(logger)
 @click.pass_context
 def resource(ctx, packages, **kwargs):
     """Lists fusion algorithm resources."""
diff --git a/bob/fusion/base/tools/__init__.py b/src/bob/fusion/base/tools/__init__.py
similarity index 100%
rename from bob/fusion/base/tools/__init__.py
rename to src/bob/fusion/base/tools/__init__.py
diff --git a/bob/fusion/base/tools/common.py b/src/bob/fusion/base/tools/common.py
similarity index 100%
rename from bob/fusion/base/tools/common.py
rename to src/bob/fusion/base/tools/common.py
diff --git a/bob/fusion/base/tools/plotting.py b/src/bob/fusion/base/tools/plotting.py
similarity index 99%
rename from bob/fusion/base/tools/plotting.py
rename to src/bob/fusion/base/tools/plotting.py
index c61c59ad1858a06d99835218d87c5e10530df17c..3294c05018f9ad1d9e330c578a6d87bddecd1d12 100644
--- a/bob/fusion/base/tools/plotting.py
+++ b/src/bob/fusion/base/tools/plotting.py
@@ -8,7 +8,6 @@ from bob.learn.em import KMeansMachine
 
 
 def grouping(scores, gformat="random", npoints=500, seed=None, **kwargs):
-
     scores = np.asarray(scores)
     if scores.size == 0:
         return scores
diff --git a/bob/fusion/base/test/__init__.py b/tests/__init__.py
similarity index 100%
rename from bob/fusion/base/test/__init__.py
rename to tests/__init__.py
diff --git a/bob/fusion/base/test/data/scores-eval-1 b/tests/data/scores-eval-1
similarity index 100%
rename from bob/fusion/base/test/data/scores-eval-1
rename to tests/data/scores-eval-1
diff --git a/bob/fusion/base/test/data/scores-eval-2 b/tests/data/scores-eval-2
similarity index 100%
rename from bob/fusion/base/test/data/scores-eval-2
rename to tests/data/scores-eval-2
diff --git a/bob/fusion/base/test/data/scores-fused-eval b/tests/data/scores-fused-eval
similarity index 100%
rename from bob/fusion/base/test/data/scores-fused-eval
rename to tests/data/scores-fused-eval
diff --git a/bob/fusion/base/test/data/scores-fused-eval-licit b/tests/data/scores-fused-eval-licit
similarity index 100%
rename from bob/fusion/base/test/data/scores-fused-eval-licit
rename to tests/data/scores-fused-eval-licit
diff --git a/bob/fusion/base/test/data/scores-fused-eval-spoof b/tests/data/scores-fused-eval-spoof
similarity index 100%
rename from bob/fusion/base/test/data/scores-fused-eval-spoof
rename to tests/data/scores-fused-eval-spoof
diff --git a/bob/fusion/base/test/data/scores-fused-train b/tests/data/scores-fused-train
similarity index 100%
rename from bob/fusion/base/test/data/scores-fused-train
rename to tests/data/scores-fused-train
diff --git a/bob/fusion/base/test/data/scores-fused-train-licit b/tests/data/scores-fused-train-licit
similarity index 100%
rename from bob/fusion/base/test/data/scores-fused-train-licit
rename to tests/data/scores-fused-train-licit
diff --git a/bob/fusion/base/test/data/scores-fused-train-spoof b/tests/data/scores-fused-train-spoof
similarity index 100%
rename from bob/fusion/base/test/data/scores-fused-train-spoof
rename to tests/data/scores-fused-train-spoof
diff --git a/bob/fusion/base/test/data/scores-train-1 b/tests/data/scores-train-1
similarity index 100%
rename from bob/fusion/base/test/data/scores-train-1
rename to tests/data/scores-train-1
diff --git a/bob/fusion/base/test/data/scores-train-2 b/tests/data/scores-train-2
similarity index 100%
rename from bob/fusion/base/test/data/scores-train-2
rename to tests/data/scores-train-2
diff --git a/bob/fusion/base/test/test_algorithm.py b/tests/test_algorithm.py
similarity index 99%
rename from bob/fusion/base/test/test_algorithm.py
rename to tests/test_algorithm.py
index 7a9f29165ed049c45880ff9c6e38fd4060ed27aa..0b1601e035074d3e0ade722290d5325977153380 100644
--- a/bob/fusion/base/test/test_algorithm.py
+++ b/tests/test_algorithm.py
@@ -11,7 +11,7 @@ from sklearn.preprocessing import StandardScaler
 
 import bob.fusion.base
 
-logger = logging.getLogger("bob.fusion.base")
+logger = logging.getLogger(__name__)
 
 
 NEG = array(
diff --git a/bob/fusion/base/test/test_preprocessor.py b/tests/test_preprocessor.py
similarity index 100%
rename from bob/fusion/base/test/test_preprocessor.py
rename to tests/test_preprocessor.py
diff --git a/bob/fusion/base/test/test_scripts.py b/tests/test_scripts.py
similarity index 87%
rename from bob/fusion/base/test/test_scripts.py
rename to tests/test_scripts.py
index cda42c3749e80bfe71784a0da2fb14edf90e3679..c8189d4b1ffc06956b66fe42a352c3059d46fb6a 100644
--- a/bob/fusion/base/test/test_scripts.py
+++ b/tests/test_scripts.py
@@ -7,29 +7,27 @@ import numpy
 from click.testing import CliRunner
 
 from bob.bio.base.score import load_score
-from bob.extension.scripts.click_helper import assert_click_runner_result
-from bob.io.base.test_utils import datafile
-
-from ..script.boundary import boundary
-from ..script.fuse import fuse
+from bob.fusion.base.script.boundary import boundary
+from bob.fusion.base.script.fuse import fuse
+from bob.io.base.testing_utils import assert_click_runner_result, datafile
 
 train_files = [
-    datafile("scores-train-1", "bob.fusion.base", "test/data"),
-    datafile("scores-train-2", "bob.fusion.base", "test/data"),
+    datafile("scores-train-1", __name__, "data/"),
+    datafile("scores-train-2", __name__, "data/"),
 ]
 eval_files = [
-    datafile("scores-eval-1", "bob.fusion.base", "test/data"),
-    datafile("scores-eval-2", "bob.fusion.base", "test/data"),
+    datafile("scores-eval-1", __name__, "data/"),
+    datafile("scores-eval-2", __name__, "data/"),
 ]
 fused_train_files = [
-    datafile("scores-fused-train", "bob.fusion.base", "test/data"),
-    datafile("scores-fused-train-licit", "bob.fusion.base", "test/data"),
-    datafile("scores-fused-train-spoof", "bob.fusion.base", "test/data"),
+    datafile("scores-fused-train", __name__, "data/"),
+    datafile("scores-fused-train-licit", __name__, "data/"),
+    datafile("scores-fused-train-spoof", __name__, "data/"),
 ]
 fused_eval_files = [
-    datafile("scores-fused-eval", "bob.fusion.base", "test/data"),
-    datafile("scores-fused-eval-licit", "bob.fusion.base", "test/data"),
-    datafile("scores-fused-eval-spoof", "bob.fusion.base", "test/data"),
+    datafile("scores-fused-eval", __name__, "data/"),
+    datafile("scores-fused-eval-licit", __name__, "data/"),
+    datafile("scores-fused-eval-spoof", __name__, "data/"),
 ]
 
 REGENERATE_TEST_FILES = False
diff --git a/version.txt b/version.txt
deleted file mode 100644
index ccf6dfd37dbdaca02c998d60c539dff63b9d9dfb..0000000000000000000000000000000000000000
--- a/version.txt
+++ /dev/null
@@ -1 +0,0 @@
-0.1.5b0