diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f26a01e948cdc392cfffaa8447e4eeb8aac6ff48..fa11e075cc0fd8c54733fead8bc84daabc081f0b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,25 +1,20 @@
-# This build file is defined in two parts: 1) a generic set of instructions you
-# probably **don't** need to change and 2) a part you may have to tune to your
-# project. It heavily uses template features from YAML to help you in only
-# changing a minimal part of it and avoid code duplication to a maximum while
-# still providing a nice pipeline display on your package.
+# This build file heavily uses template features from YAML so it is generic
+# enough for any Bob project. Don't modify it unless you know what you're
+# doing.
 
 
-# 1) Generic instructions (only change if you know what you're doing)
-# -------------------------------------------------------------------
-
 # Definition of our build pipeline
 stages:
   - build
   - test
   - docs
   - wheels
+  - deploy
 
 
-# Global variables
-variables:
-  CONDA_PREFIX: env
-
+# ---------
+# Templates
+# ---------
 
 # Template for the build stage
 # Needs to run on all supported architectures, platforms and python versions
@@ -27,104 +22,98 @@ variables:
   stage: build
   before_script:
     - git clean -ffdx
-    - curl --silent https://gitlab.idiap.ch/bob/bob/snippets/7/raw | tr -d '\r' > bootstrap-conda.sh
-    - chmod 755 ./bootstrap-conda.sh
-    - ./bootstrap-conda.sh ${CONDA_FOLDER} ${PYTHON_VER} ${CONDA_PREFIX}
-  variables: &build_variables
-    BOB_DOCUMENTATION_SERVER: "http://www.idiap.ch/software/bob/docs/latest/bob/%s/master/"
+    - mkdir _ci
+    - curl --silent "https://gitlab.idiap.ch/bob/bob.admin/raw/master/gitlab/install.sh" > _ci/install.sh
+    - chmod 755 _ci/install.sh
+    - ./_ci/install.sh _ci #updates
+    - ./_ci/before_build.sh
   script:
-    - ./bin/buildout
-    - if [ -x ./bin/bob_dbmanage.py ]; then ./bin/bob_dbmanage.py all download --force; fi
-    - ./bin/sphinx-build doc sphinx
-    - ./bin/python setup.py bdist_wheel --python-tag ${WHEEL_TAG}
+    - ./_ci/build.sh
   after_script:
-    - rm -rf ${CONDA_PREFIX}
+    - ./_ci/after_build.sh
   artifacts:
-    expire_in: 1 day
+    expire_in: 1 week
     paths:
-      - bootstrap-conda.sh
+      - _ci/
       - dist/
       - sphinx/
 
 
-# Template for building on a Linux machine
-.build_linux_template: &linux_build_job
-  <<: *build_job
-  variables: &linux_build_variables
-    <<: *build_variables
-    CONDA_FOLDER: "/local/conda"
-    CFLAGS: "-D_GLIBCXX_USE_CXX11_ABI=0 -coverage"
-    CXXFLAGS: "-D_GLIBCXX_USE_CXX11_ABI=0 -coverage"
-
-
-# Template for building on a Mac OSX machine
-.build_mac_template: &macosx_build_job
-  <<: *build_job
-  variables: &macosx_build_variables
-    <<: *build_variables
-    CONDA_FOLDER: "/opt/conda"
-    MACOSX_DEPLOYMENT_TARGET: "10.9"
-    CFLAGS: "-pthread -coverage"
-    CXXFLAGS: "-pthread -coverage"
-    LDFLAGS: "-lpthread"
-
-
-# Template for the test stage - re-install from uploaded wheels
+# Template for the test stage - re-installs from uploaded wheels
 # Needs to run on all supported architectures, platforms and python versions
 .test_template: &test_job
   stage: test
   before_script:
-    - ./bootstrap-conda.sh ${CONDA_FOLDER} ${PYTHON_VER} ${CONDA_PREFIX}
-    - source ${CONDA_FOLDER}/bin/activate ${CONDA_PREFIX}
-    - pip install --use-wheel --no-index --pre dist/*.whl
+    - ./_ci/install.sh _ci #updates
+    - ./_ci/before_test.sh
   script:
-    - cd ${CONDA_PREFIX}
-    - python -c "from ${CI_PROJECT_NAME} import get_config; print(get_config())"
-    - coverage run --source=${CI_PROJECT_NAME} ./bin/nosetests -sv ${CI_PROJECT_NAME}
-    - coverage report
-    - sphinx-build -b doctest ../doc ../sphinx
+    - ./_ci/test.sh
   after_script:
-    - rm -rf ${CONDA_PREFIX}
+    - ./_ci/after_test.sh
 
 
 # Template for the wheel uploading stage
-# Needs to run against one combination of python 2.x and 3.x if it is a python
-# only package, otherwise, needs to run in both pythons to all supported
-# architectures (Linux and Mac OSX 64-bit)
+# Needs to run against one supported architecture, platform and python version
 .wheels_template: &wheels_job
   stage: wheels
+  environment: intranet
   only:
     - master
-    - tags
+    - /^v\d+\.\d+\.\d+([abc]\d*)?$/  # PEP-440 compliant version (tags)
   before_script:
-    - curl --silent https://gitlab.idiap.ch/bob/bob/snippets/8/raw | tr -d '\r' > upload-wheel.sh
-    - chmod 755 upload-wheel.sh
+    - ./_ci/install.sh _ci #updates
+    - ./_ci/before_wheels.sh
   script:
-    - ./upload-wheel.sh
+    - ./_ci/wheels.sh
+  after_script:
+    - ./_ci/after_wheels.sh
 
 
 # Template for (latest) documentation upload stage
 # Only one real job needs to do this
 .docs_template: &docs_job
   stage: docs
+  environment: intranet
   only:
     - master
   before_script:
-    - curl --silent https://gitlab.idiap.ch/bob/bob/snippets/9/raw | tr -d '\r' > upload-sphinx.sh
-    - chmod 755 upload-sphinx.sh
+    - ./_ci/install.sh _ci #updates
+    - ./_ci/before_docs.sh
+  script:
+    - ./_ci/docs.sh
+  after_script:
+    - ./_ci/after_docs.sh
+
+
+# Template for the deployment stage - re-installs from uploaded wheels
+# Needs to run on a single architecture only
+# Will deploy your package to PyPI and other required services
+# Only runs for tags
+.deploy_template: &deploy_job
+  stage: deploy
+  environment: internet
+  only:
+    - /^v\d+\.\d+\.\d+([abc]\d*)?$/  # PEP-440 compliant version (tags)
+  except:
+    - branches
+  before_script:
+    - ./_ci/install.sh _ci #updates
+    - ./_ci/before_deploy.sh
   script:
-    - ./upload-sphinx.sh
+    - ./_ci/deploy.sh
+  after_script:
+    - ./_ci/after_deploy.sh
 
 
-# 2) Package specific instructions (you may tune this if needed)
-# --------------------------------------------------------------
+# -------------
+# Build Targets
+# -------------
 
-# Linux + Python 2.7: Builds, tests, uploads wheel
+# Linux + Python 2.7: Builds, tests, uploads wheel and deploys (if needed)
 build_linux_27:
-  <<: *linux_build_job
+  <<: *build_job
   variables: &linux_27_build_variables
-    <<: *linux_build_variables
-    PYTHON_VER: "2.7"
+    PYTHON_VERSION: "2.7"
     WHEEL_TAG: "py27"
   tags:
     - conda-linux
@@ -139,6 +128,15 @@ test_linux_27:
 
 wheels_linux_27:
   <<: *wheels_job
+  variables: *linux_27_build_variables
+  dependencies:
+    - build_linux_27
+  tags:
+    - conda-linux
+
+deploy_linux_27:
+  <<: *deploy_job
+  variables: *linux_27_build_variables
   dependencies:
     - build_linux_27
   tags:
@@ -147,10 +145,9 @@ wheels_linux_27:
 
 # Linux + Python 3.4: Builds and tests
 build_linux_34:
-  <<: *linux_build_job
+  <<: *build_job
   variables: &linux_34_build_variables
-    <<: *linux_build_variables
-    PYTHON_VER: "3.4"
+    PYTHON_VERSION: "3.4"
     WHEEL_TAG: "py3"
   tags:
     - conda-linux
@@ -164,12 +161,11 @@ test_linux_34:
     - conda-linux
 
 
-# Linux + Python 3.5: Builds, tests, uploads wheel
+# Linux + Python 3.5: Builds, tests and uploads wheel
 build_linux_35:
-  <<: *linux_build_job
+  <<: *build_job
   variables: &linux_35_build_variables
-    <<: *linux_build_variables
-    PYTHON_VER: "3.5"
+    PYTHON_VERSION: "3.5"
     WHEEL_TAG: "py3"
   tags:
     - conda-linux
@@ -184,6 +180,7 @@ test_linux_35:
 
 wheels_linux_35:
   <<: *wheels_job
+  variables: *linux_35_build_variables
   dependencies:
     - build_linux_35
   tags:
@@ -191,6 +188,7 @@ wheels_linux_35:
 
 docs_linux_35:
   <<: *docs_job
+  variables: *linux_35_build_variables
   dependencies:
     - build_linux_35
   tags:
@@ -199,10 +197,9 @@ docs_linux_35:
 
 # Mac OSX + Python 2.7: Builds and tests
 build_macosx_27:
-  <<: *macosx_build_job
+  <<: *build_job
   variables: &macosx_27_build_variables
-    <<: *macosx_build_variables
-    PYTHON_VER: "2.7"
+    PYTHON_VERSION: "2.7"
     WHEEL_TAG: "py27"
   tags:
     - conda-macosx
@@ -218,10 +215,9 @@ test_macosx_27:
 
 # Mac OSX + Python 3.4: Builds and tests
 build_macosx_34:
-  <<: *macosx_build_job
+  <<: *build_job
   variables: &macosx_34_build_variables
-    <<: *macosx_build_variables
-    PYTHON_VER: "3.4"
+    PYTHON_VERSION: "3.4"
     WHEEL_TAG: "py3"
   tags:
     - conda-macosx
@@ -237,10 +233,9 @@ test_macosx_34:
 
 # Mac OSX + Python 3.5: Builds and tests
 build_macosx_35:
-  <<: *macosx_build_job
+  <<: *build_job
   variables: &macosx_35_build_variables
-    <<: *macosx_build_variables
-    PYTHON_VER: "3.5"
+    PYTHON_VERSION: "3.5"
     WHEEL_TAG: "py3"
   tags:
     - conda-macosx
@@ -251,4 +246,4 @@ test_macosx_35:
   dependencies:
     - build_macosx_35
   tags:
-    - conda-macosx
\ No newline at end of file
+    - conda-macosx
diff --git a/develop.cfg b/develop.cfg
index c770b14bfc764187a439bc11119d845ea23639a4..497ac8e077aff0cfc389d708c27da2d1b1d79b04 100644
--- a/develop.cfg
+++ b/develop.cfg
@@ -21,7 +21,6 @@ develop = src/bob.extension
           src/bob.learn.em
           src/bob.measure
           src/bob.db.base
-          src/bob.bio.db
           src/bob.db.atnt
           src/bob.io.image
           src/bob.bio.base
@@ -44,7 +43,6 @@ bob.learn.linear = git https://gitlab.idiap.ch/bob/bob.learn.linear
 bob.learn.em = git https://gitlab.idiap.ch/bob/bob.learn.em
 bob.measure = git https://gitlab.idiap.ch/bob/bob.measure
 bob.db.base = git https://gitlab.idiap.ch/bob/bob.db.base
-bob.bio.db = git https://gitlab.idiap.ch/bob/bob.bio.db
 bob.db.atnt = git https://gitlab.idiap.ch/bob/bob.db.atnt
 bob.io.image = git https://gitlab.idiap.ch/bob/bob.io.image
 bob.bio.base = git https://gitlab.idiap.ch/bob/bob.bio.base
diff --git a/doc/conf.py b/doc/conf.py
index 7cd8b53d0407b23306e22117fad62e0c092c8e76..844307fb346a7e1599de6858ca6702f4bb59b076 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -111,7 +111,7 @@ pygments_style = 'sphinx'
 
 # Some variables which are useful for generated material
 project_variable = project.replace('.', '_')
-short_description = u'Run Gaussian mixture model based algorithms'
+short_description = u'Tools for running biometric recognition experiments'
 owner = [u'Idiap Research Institute']
 
 
@@ -216,8 +216,13 @@ autodoc_default_flags = [
   ]
 
 # For inter-documentation mapping:
-from bob.extension.utils import link_documentation
-intersphinx_mapping = link_documentation()
+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=load_requirements(sphinx_requirements))
+else:
+    intersphinx_mapping = link_documentation()
+
 
 # We want to remove all private (i.e. _. or __.__) members
 # that are not in the list of accepted functions
diff --git a/requirements.txt b/requirements.txt
index fd14f2fda23edc0f0f457da9805f075f9bb03e67..1feea38a47ba8ce0b1a3514e48c31219cd136d09 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -10,7 +10,5 @@ bob.sp
 bob.learn.em
 bob.measure
 bob.db.base
-bob.db.atnt  # for test purposes
-bob.io.image # for test purposes
 bob.bio.base
 matplotlib   # for plotting
diff --git a/test-requirements.txt b/test-requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b43739e4acef80d6cc73773077529240de759eef
--- /dev/null
+++ b/test-requirements.txt
@@ -0,0 +1,2 @@
+bob.db.atnt  # for test purposes
+bob.io.image # for test purposes
\ No newline at end of file