diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4c0dfccb4d8f29badb0c127624ff89de5a1888db..7f4bec564e23918cf912052af8e92081b96e3fa1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,6 +9,7 @@ variables:
 include:
   - local: '/.gitlab-ci/gcc8-seq-dbg.yml'
   - local: '/.gitlab-ci/gcc8-seq-release.yml'
+#  - local: '/.gitlab-ci/gcc8-seq-coverage.yml'
   - local: '/.gitlab-ci/clang8-seq-release.yml'
   - local: '/.gitlab-ci/clang8-mpi-release.yml'
   - local: '/.gitlab-ci/clang8-seq-coverage.yml'
diff --git a/.gitlab-ci/gcc8-seq-coverage.yml b/.gitlab-ci/gcc8-seq-coverage.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b1dde28e100add4c0aecccc07b7cb7c695cde92e
--- /dev/null
+++ b/.gitlab-ci/gcc8-seq-coverage.yml
@@ -0,0 +1,13 @@
+build:gcc8-seq-coverage:
+  image: localhost:5000/ubuntu_gcc8
+  stage: coverage
+  script:
+    - mkdir -p build/gcc8-seq-covrage
+    - cd build/gcc8-seq-covrage
+    - CXX=g++-8 CC=gcc-8 cmake ../.. -DCMAKE_BUILD_TYPE=Coverage
+    - make coverage
+  cache:
+    key: "${CI_COMMIT_REF_SLUG}-gcc8-seq-coverage"
+    paths:
+      - build/gcc8-seq-covrage
+    untracked: true
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0f2a3909fe1e7149dde87a3e8a12bd293f6ed24e..dc88cf603a01949662e34d92f5cf5606ed82372a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -226,54 +226,86 @@ add_custom_target(run_unit_tests
 # unit tests coverage
 
 if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
-  find_program(GCOVR gcovr)
-  if(NOT GCOVR)
-    message(FATAL_ERROR "gcovr not found, cannot perform coverage.")
+  find_program(LCOV lcov)
+  if(NOT LCOV)
+    message(FATAL_ERROR "lcov not found, cannot perform coverage.")
   endif()
 
-  if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-    string(REPLACE "clang++" "llvm-cov" LLVM_COV "${CMAKE_CXX_COMPILER}")
-    if(NOT EXISTS "${LLVM_COV}")
-      message(FATAL_ERROR "could not find ${LLVM_COV}, cannot perform coverage (using g++ for coverage is recommended).")
-    endif()
+  if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+    string(REGEX MATCH "^[0-9]+" GCC_VERSION
+      "${CMAKE_CXX_COMPILER_VERSION}")
+    find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov
+      HINTS ${COMPILER_PATH})
+  elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+    string(REGEX MATCH "^[0-9]+" LLVM_VERSION
+      "${CMAKE_CXX_COMPILER_VERSION}")
 
-    set(GCOVR_EXTRA "--gcov-executable=${LLVM_COV} gcov")
-  endif()
+    if(LLVM_VERSION VERSION_GREATER 7)
+      find_program(LLVM_COV_BIN NAMES "llvm-cov-${LLVM_VERSION}"
+        "llvm-cov" HINTS ${COMPILER_PATH})
+      mark_as_advanced(LLVM_COV_BIN)
 
-  set (GCOVR_EXCLUDE
-    -e "${PUGS_SOURCE_DIR}/src/main.cpp"
-    -e "${PUGS_SOURCE_DIR}/src/utils/BacktraceManager.cpp"
-    -e "${PUGS_SOURCE_DIR}/src/utils/BacktraceManager.hpp"
-    )
+      if (LLVM_COV_BIN)
+        file(MAKE_DIRECTORY "${PUGS_BINARY_DIR}/tools/tmp")
 
-  set(GCOVR_OPTIONS --object-directory="${PUGS_BINARY_DIR}" -r "${PUGS_SOURCE_DIR}/src" ${GCOVR_EXCLUDE} ${GCOVR_EXTRA})
+        file(WRITE "${PUGS_BINARY_DIR}/tools/tmp/llvm-cov.sh" "#! /bin/sh\n")
+        file(APPEND "${PUGS_BINARY_DIR}/tools/tmp/llvm-cov.sh" "'${LLVM_COV_BIN}' gcov \"\$@\"\n")
 
-  add_custom_target(coverage-clean-up
-    ALL
-    COMMAND ${CMAKE_COMMAND}
-    -DPUGS_BINARY_DIR="${PUGS_BINARY_DIR}"
-    -P ${PUGS_SOURCE_DIR}/cmake/CoverageRemoveObsoleteFiles.cmake
-    COMMENT "Removing obsolete gcda to perform a net coverage."
-    )
+        file(COPY "${PUGS_BINARY_DIR}/tools/tmp/llvm-cov.sh"
+             DESTINATION "${PUGS_BINARY_DIR}/tools"
+             FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
 
-  add_custom_target(coverage
-    ALL
-    COMMAND ${GCOVR} ${GCOVR_OPTIONS} --exclude-unreachable-branches --sort-percentage
-    DEPENDS coverage-clean-up
-    DEPENDS run_unit_tests pugs
-    COMMENT "Running gcovr to build coverage report."
-    )
+        set(GCOV_BIN "${PUGS_BINARY_DIR}/tools/llvm-cov.sh")
+      endif()
+    endif()
+  endif()
 
-  add_custom_target(coverage-report
-    ALL
-    COMMAND ${CMAKE_COMMAND} -E remove_directory "${PUGS_BINARY_DIR}/coverage"
-    COMMAND ${CMAKE_COMMAND} -E make_directory "${PUGS_BINARY_DIR}/coverage"
-    COMMAND ${GCOVR} ${GCOVR_OPTIONS} --delete --html --html-details -o "${PUGS_BINARY_DIR}/coverage/index.html"
-    DEPENDS coverage
-    COMMENT "Building coverage html report."
+  if(NOT GCOV_BIN)
+     message(FATAL_ERROR "Cannot find a proper gcov tool, cannot perform coverage.")
+  endif()
+
+  add_custom_target(coverage
+    ALL # in coverage mode we do coverage!
+    # Cleanup previously generated profiling data
+    COMMAND ${LCOV} -q --gcov "${GCOV_BIN}" --base-directory "${PUGS_SOURCE_DIR}/src" --directory "${PUGS_BINARY_DIR}" --zerocounters
+    # Initialize profiling data with zero coverage for every instrumented line of the project
+    # This way the percentage of total lines covered will always be correct, even when not all source code files were loaded during the test(s)
+    COMMAND ${LCOV} -q --gcov "${GCOV_BIN}" --base-directory "${PUGS_SOURCE_DIR}/src" --directory "${PUGS_BINARY_DIR}" --capture --initial --output-file coverage_base.info
+    # Run tests
+    COMMAND ${CMAKE_CTEST_COMMAND} -j ${PROCESSOR_COUNT}
+    # Collect data from executions
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" --base-directory "${PUGS_SOURCE_DIR}/src" --directory "${PUGS_BINARY_DIR}" --capture --output-file coverage_ctest.info
+    # Combine base and ctest results
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" -q --add-tracefile coverage_base.info --add-tracefile coverage_ctest.info --output-file coverage_full.info
+    # Extract only project data (--no-capture or --remove options may be used to select collected data)
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" -q --extract coverage_full.info "'${PUGS_SOURCE_DIR}/src/*'" --output-file coverage_extract.info
+
+    # Remove unwanted stuff
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" --remove coverage_extract.info  --output-file coverage.info
+                                              '${PUGS_SOURCE_DIR}/src/main.cpp'
+                                              '${PUGS_SOURCE_DIR}/utils/BacktraceManager.*'
+
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" --list coverage.info
+
+    DEPENDS unit_tests mpi_unit_tests
+    COMMENT "Running test coverage."
     WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
     )
 
+  find_program(GENHTML genhtml)
+  if(NOT GENHTML)
+    message(WARNING "genhtml not found, cannot perform report-coverage.")
+  else()
+    add_custom_target(coverage-report
+      ALL
+      COMMAND ${CMAKE_COMMAND} -E remove_directory "${PUGS_BINARY_DIR}/coverage"
+      COMMAND ${CMAKE_COMMAND} -E make_directory "${PUGS_BINARY_DIR}/coverage"
+      COMMAND ${GENHTML} -q -o coverage -t "${CMAKE_PROJECT_NAME} test coverage" --ignore-errors source --legend --num-spaces 4 coverage.info
+      DEPENDS coverage
+      COMMENT "Building coverage html report."
+      WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
+      )
+  endif()
 endif()
 
 #------------------------------------------------------