Static analysis and SonarQube web service

Table of Contents

This document presents an example of source code (C/C++, Python) analysis and publication of results to the Inria SonarQube web server.

Many concepts and tools that are used here are discussed in the Inria SonarQube documentation. Please refer to this documentation to get more information.

The toy project used here is Heat.

Summary of the hands-on session:

  1. install prerequisites
  2. test sonarqube scanner with a python "hello world"
  3. download the "Heat" source code from the public git repository
  4. build the project: generate a library, executables and a report containing the GCC compiler warnings, and generate clang static analyzer reports
  5. execute tests: necessary to produce the coverage (gcov) data
  6. perform analysis: gcov, cppcheck, valgrind, …
  7. create the file and call sonar-scanner to publish the results to SonarQube
  8. analyze results with the SonarQube web interface

1 Generalities

SonarQube is mainly a web server providing some dashboards that help assessing the quality of programs. Many things can be reported: size of source code, detection of duplication, issues based on static and dynamic analyzers, coverage data, etc.

There exists different versions released: one is opensource, free but with limited features and some others are charged, see Plans & Pricing. SonarCloud is a freely available instance of SonarQube for opensource projects. However it is charged for private projects.

After some experiments with the opensource Community Edition version we have concluded that it meets requirements for most Inria usage. We host an instance on a virtual machine managed by the DSI and the SED of Inria. The url of the service is : This is a Community Edition LTS. Here is the list of plugins installed: Installed Plugins. To get more plugins installed please contact the support team. Languages that can be analyzed are: C, C++, C#, CSS, Flex, Go, Groovy, Lua, Java, JavaScript, Kotlin, PHP, Python, Ruby, Scala, TypeScript, XML, see list of supported languages.

Without being logged only public projects are displayed. Any user is able to explore metrics and source code of public projects. This platform allows people with an Inria account to analyze their project. People with no Inria account will be able to join existing projects. Once logged users can:

  • create a new project (only Inria account), being automatically administrator, through a sonar-scanner analysis
  • join (browse metrics, see source code, administer issues, etc) existing project if proper permissions are given by one of the project's administrators

2 Initial setup

In the following we will perform analysis of source codes locally on a personal computer and then publish the results on the SonarQube@inria web server. This requires to have some tools installed and an internet access.

Considering the experiment environment we propose either to download a ready to use Docker image or to install the analysis tools in your own environment on your personal computer.

2.1 Use the ready to use Docker image

First if not already done, install Docker.

Then one can download the existing Docker image (~3.5 Go)

docker pull hpclib/sonarqube

Notice this image has been made with this Dockerfile.

Finally run interactively in the container with

docker run -it hpclib/sonarqube

In this environment all the analysis tools used in the following are available, sonar-scanner, coverity, cppcheck, clang, gcov, valgrind, etc. Thus you don't need to follow the "installation" recommandation given below. Still, the token creation is required, see next section.

2.2 Create a SonarQube token

To be able to publish results to SonarQube a token system is necessary for the authentication. Log in to with your Inria LDAP credential and create a personal token (save it in your home for example in $HOME/.sonarqubetoken)

2.3 Install sonar-scanner

If you don't use the Docker image you will need to install sonar-scanner to perform a static analysis, index source code files, and publish the results. Skip this stage if you use the Docker image.

Please install the sonar-scanner program.

We provide some installation scripts for some well known operating systems, please refer to one of the install-sonar-scanner-*.sh scripts. wget, unzip, sudo, ln commands are required.

2.3.1 Linux

sudo ln -s $PWD/sonar-scanner- /usr/local/bin/sonar-scanner

2.3.2 MacOSX

sudo ln -s $PWD/sonar-scanner- /usr/local/bin/sonar-scanner

2.3.3 Windows

On Windows, download the appropriate archive, extract the archive and add its sub-directory "/bin" in the PATH environment variable (Start Menu -> Right clic on Computer -> Properties -> Advanced system settings -> Environment Variables -> Path -> Edit).

2.4 Hello World SonarQube

Lets try sonar-scanner with an "Hello World" python script.

First create the "hello world" python script

# This program prints Hello, world!

print('Hello, world!')

you can execute it if you have python installed


Optionnaly save your token in a file, for example

echo "34539dd39d77f225f552676191a23ff725116702" > ~/.sonarqubetoken

Then lets use sonar-scanner to analyze this source code

sonar-scanner -D"" -D"sonar.login=$(cat ~/.sonarqubetoken)" -D"sonar.projectKey=sedbso:helloworld:test" -D"sonar.sources=./" -D"sonar.language=py"

Visit the sonarqube project page and look for your submitted project.

sonar-scanner is used in a shell through a CLI. One can pass the options directly in the command line or they can be stored in a file

Then you should be able to invoke sonar-scanner more simply


Note that one can set some options in the file and change their values at the level of the command line (take precedence).

2.5 Install some development and analysis tools for C/C++ and Python programs

Please skip this stage if you use the Docker image.

heat is a toy code written in C that will be used in this hands-on session to perform static and dynamic analysis.

We propose to install some dependencies of the heat program, git, C compiler (GCC), CMake, plus some useful analysis tools, Clang Static Analyzer, Cppcheck, GCOV, Valgrind, pytest, pylint …

We provide some scripts to do that depending on the OS, see install-dev-tools-*.sh scripts.

2.5.1 Debian (apt-get)

# Install Git, GCC, CMake, Clang, GCOV, LCOV, Cppcheck, Valgrind, Python (+pip+pylint+test and coverage modules+scan-build for Clang SA)
sudo apt-get update -y
sudo apt-get install -y git build-essential cmake clang clang-tidy gcovr lcov cppcheck valgrind python-pip pylint

pip install --upgrade pip
sudo python -m pip install pytest pytest-cov setuptools scan-build

# Install the script to convert lcov coverage report into xml file compatible with SonarQube
tar xvf 1.6.tar.gz
sudo ln -s $PWD/lcov-to-cobertura-xml-1.6/lcov_cobertura/ /usr/local/bin/


2.5.2 Centos (yum)

# Install Git, GCC, CMake, Clang, GCOV, LCOV, Cppcheck, Valgrind, Python (+pip+pylint+test and coverage modules+scan-build for Clang SA)
sudo yum install -y epel-release
sudo yum update -y
sudo yum install -y git gcc gcc-gfortran gcc-c++ cmake clang llvm-toolset-7-clang-tools-extra.x86_64 lcov cppcheck valgrind python python-pip pylint

sudo pip install --upgrade pip
sudo python -m pip install pytest pytest-cov setuptools scan-build


2.5.3 Fedora (dnf)

# Install Git, GCC, CMake, Clang, GCOV, LCOV, Cppcheck, Valgrind, Python (+pip+pylint+test and coverage modules+scan-build for Clang SA)
sudo dnf upgrade -y
sudo dnf install -y git gcc gcc-gfortran gcc-c++ cmake clang clang-tools-extra gcovr lcov cppcheck valgrind python python-pip pylint

sudo pip install --upgrade pip
sudo python -m pip install pytest pytest-cov setuptools scan-build


2.5.4 MacOSX

# install Homebrew
/usr/bin/ruby -e "$(curl -fsSL"

# Install Git, GCC, CMake, Clang, GCOV, LCOV, Cppcheck, Valgrind, Python (+pip+pylint+test and coverage modules+scan-build for Clang SA)

# install packages with homebrew
brew update
brew install git gcc lcov cppcheck valgrind python llvm --with-toolchain

# install some additional python modules for python analysis
pip3 install --upgrade pip
pip3 install pytest pytest-cov pylint

# get scan-build for clang static analysis
tar xf checker-279.tar.bz2
sudo ln -s $PWD/checker-279/bin/scan-build /usr/local/bin/scan-build


2.5.5 Windows

3 Scan a program

Let's experiment static and dynamic analysis on a toy code, "Heat" written in C and providing a basic implementation for solving the heat equation.

Static analysis intends to find issues in the source code just based on the raw files and points out possible syntaxical errors, use of uninitialized variables, dereference pointer problem, memory leak, duplications, scope reduction, non respect of conventions, etc.

Dynamic analysis allows to check a program by executing the binary executables. Unit tests and integration tests are part of dynamic analysis, just as coverage measurements, memory checking, thread checking, etc

3.1 Download Heat with git

In a shell, git clone the Heat source code, this is a public git repository

# git command is required
git clone
cd heat/

3.2 Build

Configure and build Heat so that:

  • we enable and save some chosen GCC warnings
  • we enable GCOV coverage
  • we perform a static analysis with Clang Static Analyzer
mkdir -p build
cd build
# make clean
CFLAGS="--coverage -fPIC -fdiagnostics-show-option -Wall -Wunused-parameter -Wundef -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wstrict-prototypes -Wcomment -pedantic -g"
scan-build -v -plist --intercept-first --analyze-headers -o analyzer_reports cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_FLAGS="$CFLAGS" -DCMAKE_EXE_LINKER_FLAGS="$LDFLAGS"
scan-build -v -plist --intercept-first --analyze-headers -o analyzer_reports make 2>&1 | tee heat-build.log


  • CMAKE_VERBOSE_MAKEFILE is set to ON to get detailed compilation lines
  • CMAKE_EXPORT_COMPILE_COMMANDS is set to ON to get compile commands used during the make process. It will be used later for the clang-tidy analysis and cppcheck
  • "–coverage" is used for coverage analysis with gcov, see Instrumentation Options
  • "-fPIC" should be used if a shared library is built
  • "-fdiagnostics-show-option" is used to feed GCC warnings into SonarQube, see sonar-cxx wiki
  • "-Wall -Wunused-parameter -Wundef -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wstrict-prototypes -Wcomment -pedantic" are used to enable some GCC warnings (arbitrarily)
  • scan-build program is used to perform a clang static analyzer scan, see scan-build
  • we build with debug information "-g" to help scan-build (clang analyzer) to be more effective (avoid false positive), see scan-build recommended debug
  • scan-build results are stored in analyzer_reports
  • "-plist" option is used for getting some report files compatible with SonarQube

3.3 Test

We perform unitary tests and this generates gcov coverage files thanks to the "–coverage" flags used just before, see resulting *.gcda and *.gcno files

ctest -V
find . -regex '.*\.\(gcda\|gcno\)'

3.4 Perform static and dynamic analysis

SonarQube performs a static analysis when we invoke sonar-scanner (see the next section "SonarQube scan"). The issues that are considered by the SonarQube analysis depends on the language and for C/C++ it relies on the sonar-cxx plugin. In addition to its own analysis the plugin allows to import issues addressed by external analysis tools.

In this section we run some of the external tools that are compatible to perform static (clang-tidy, cppcheck) and dynamic analysis (coverage with gcov, valgrind, drmemory).

Notice we already have performed the clang static analysis during the build step. There is no need to do something else, the clang reports generated with the "-plist" parameter are compatible with SonarQube.

3.4.1 clang

The Clang project provides two tools for static analysis, clang-sa and clang-tidy. clang-sa covers a variety of checks targeted at finding security and API usage bugs, dead code, and other logic errors, see available checkers. clang-tidy is more a "linter" tool for diagnosing and fixing typical programming errors, like style violations, interface misuse, etc.

clang-sa has been used during the build process, please see the previous section about the build. Report files should have been generated in the build/analyzer_reports/ directory and are ready to be imported in SonarQube.

clang-tidy can be invoked to add code smells reports.

# in the build directory
clang-tidy -checks='*' -header-filter=.. -p . ../*.c > clang-tidy-report
# or even better using the compilation database and 5 threads
/usr/lib/llvm-9/share/clang/ -checks='*' -header-filter=.. -p . -j5 > clang-tidy-report

See also

SonarQube list of Clang issues for C code :

3.4.2 cppcheck


cd ..
cppcheck -v -f --language=c --platform=unix64 --enable=all --xml --xml-version=2 --suppress=missingIncludeSystem ${DEFINITIONS} ${CPPCHECK_INCLUDES} ${SOURCES_TO_EXCLUDE} ${SOURCES_TO_ANALYZE} 2> heat-cppcheck.xml
# windows "C:\Program Files\Cppcheck\cppcheck.exe" -v -f --language=c --platform=win64 --enable=all --xml --xml-version=2 -I. -ibuild\CMakeFiles . 2> heat-cppcheck.xml


  • "-f" to force maximum number of configurations (combination of all macros states), see "–max-configs" option to limit the number of configurations because it can be very long or "-D" and "-U" to define/undefine macros
  • "–enable=all" enables all error types checking
  • "–xml" allows to generate a report compatible with SonarQube

SonarQube list of Cppcheck issues for C code : cppcheck

3.4.3 valgrind

See Valgrind is used to detect memory management and threading bugs.

valgrind --xml=yes --xml-file=heat-valgrind.xml --memcheck:leak-check=full --show-reachable=yes "./build/heat_seq" "10" "10" "200" "0" "0"

SonarQube list of Valgrind issues for C code : valgrind

3.4.4 drmemory


mkdir drmemory
$DRMEMORY/drmemory -logdir drmemory -- build/heat_seq "10" "10" "200" "0" "0"
# windows "C:\Program Files (x86)\Dr. Memory\bin64\drmemory.exe" -logdir C:\Users\ci\heat\drmemory -- build\heat_seq.exe "10" "10" "200" "0" "0"

SonarQube list of DrMemory issues for C code : drmemory

3.4.5 coverage with GCOV and LCOV

After the tests execution you can generate the coverage report. You can already generate an HTML file using lcov and genhtml. script is necessary to produce the xml report necessary to publish coverage on SonarQube (the .lcov report cannot be imported as it is).

lcov --directory . --capture --output-file heat.lcov
genhtml -o coverage heat.lcov
# see the result, for example: firefox coverage/index.html heat.lcov --output heat-coverage.xml

See for more information.

Actually it could also be possible to import the unitary tests if the test framework supports "JUnitReport-like" such as Googletest and Boost Test, see

3.4.6 And more

Other reports can be imported such as :

3.5 SonarQube scan from the command line

SonarQube performs a static analysis when we invoke sonar-scanner. The issues that are considered by the SonarQube analysis depends on the language and for C/C++ it relies on the sonar-cxx plugin.

The sonar-scanner program is used for executing the SonarQube scan and put the results online i.e. upload to the server. The program takes some arguments such as the url of the server, credentials, the name we want to assign to our project analysis, paths to external analysis reports, etc.

See how to use it. Parameters can be given either with the -D argument of the program and/or defining them in a configuration file which must be located in the current path where sonar-scanner is invoked.

3.5.1 config scanner

For our use case we define project's specific parameters in the local configuration file, please adapt the projectkey parameter and replace with your name e.g. fpruvost -> hmathieu

sonar.projectDescription=Solve the heat propagation equation
sonar.c.includeDirectories=/usr/lib/gcc/x86_64-linux-gnu/9/include, /usr/local/include, /usr/lib/gcc/x86_64-linux-gnu/9/include-fixed, /usr/include/x86_64-linux-gnu, /usr/include, ., include
sonar.c.compiler.regex=^(.*):(\\\d+):\\\d+: warning: (.*)\\\[(.*)\\\]$


  • for explanation about the main sonar-scanner parameters please read
  • please follow the convention we described here about the sonar.projectKey (e.g. team:project:git:branch) parameter, and please do not provide the sonar.projectName (projectKey will be used as name), it helps to keep projects organized in SonarQube
  • the sonar.c parameters are related to the sonar-cxx plugin and allows to complete the analysis with reports coming from other tools. In this example we import issues coming from
    • GCC warnings: compiler.reportPath
    • Clang-SA: clangsa.reportPath
    • Clang-tidy: clangtidy.reportPath
    • GCOV: coverage.reportPath
    • Cppcheck: cppcheck.reportPath
    • Valgrind: valgrind.reportPath
    • DrMemory: drmemory.reportPath
  • sonar-scanner is not able to find paths to header files on his own, one has to help it to properly set the sonar.c.includeDirectories parameter, e.g.
    • compiler header files directories:
    echo | gcc -xc -E -Wp,-v - 2>&1 | grep "^ " | xargs | sed -e "s# #, #g"
    • internal header files directories
    find . -name "*.h" -printf '%h, '

3.5.2 sonar-scanner

We invoke sonar-scanner with -X (debug), the address of the sonarqube server, the personal token for identification, and we save the output in a file

sonar-scanner -X -Dsonar.login=`cat ~/.sonarqubetoken` >sonar.log 2>&1

The .sonarqubetoken file must contain your personal token in this example. You need to give your personal token here to be able to upload some data, see the first section "Initial setup".

See the results in SonarQube. In the "Projects" tab search for your project in the research bar (the projectKey parameter).

Note that SonarQube analysis can be performed differently than using the sonar-scanner program in a shell for project building with MSBuild, Maven, Gradle, Ant, Jenkins, see here.

3.6 Scan a C++ program

The same tools as for C program can be used. The only things to change are some parameters in the file

  • sonar.c properties should be replaced by sonar.cxx
  • sonar.language should be set to "c++".
  • to find compiler header files directories
echo | gcc -xc++ -E -Wp,-v - 2>&1 | grep "^ " | xargs | sed -e "s# #, #g"

3.7 Scan a Python program

Example with the Explauto library.


git clone
cd explauto
python3 -m pip install codecov pytest-cov setuptools
python3 -m pip install -r requirements.txt
python3 build
sudo python3 develop

Test + Coverage

pytest --cov=./ --junit-xml=test.xml --cov-report xml

Setup the SonarQube configuration

sonar.projectDescription=An autonomous exploration library

Perform sonarqube analysis and publish the results

sonar-scanner -X -Dsonar.login=`cat ~/.sonarqubetoken` >sonar.log 2>&1

Notice SonarQube perfoms also a pylint analysis if it is installed on the system. In addition unitary tests and coverage are imported thanks to the xml files generated before with pytest.

See the results in SonarQube.

3.8 SonarQube public server for opensource softwares

The C/C++ analyzer from SonarQube is a paid service, see SonarCFamily plugin. This plugin cannot be used in the community version we have instanciated at Inria. For C/C++ we use the community plugin sonar-cxx. With this plugin we get access to a few SonarQube issues (during the sonar-scanner analysis) and we can import many other reports coming from external analyzers. This is fine but we don't have access to the "official" SonarQube C/C++ analyzer which is surely interesting too.

The good news ? There exists a public SonarQube server, sonarcloud for opensource projects which gives access to the SonarCFamily plugin.

If you have an opensource project to analyze and you want to see what gives the sonar-scanner analysis with the SonarCFamily plugin please visit the sonarsource documentation.

See for example the SimGrid project.

3.9 The Coverity alternative

Coverity is another analyzer that is normally a paid service but which gives access to a public server for opensource projects, see :

Download the cov-build program here.

wget --no-check-certificate --post-data "token=$COVERITY_TOKEN&project=Heat" -O coverity_tool.tgz
tar xvf coverity_tool.tgz
sudo ln -s -f $PWD/cov-analysis-linux64-*/bin/cov-build /usr/local/bin/cov-build

Build and analyze with the 'cov-build' command

git clone
cd heat/
mkdir -p build
cd build
cmake ..
make clean
cov-build --dir cov-int make -j 4

Create a compress tar archive of the results

tar czvf heat.tgz cov-int

Submit compressed file created in previous step for analysis

curl --form token=$COVERITY_TOKEN --form --form file=@heat.tgz --form version="`git rev-parse --short HEAD`" --form description=""

See the results in the Coverity dashboard, follow the "View Defects" link.


  • Paid service if not opensource
  • Languages: C/C++, C#, Java, Javascript, PHP, Python, .NET Core, ASP.NET, Objective-C, Go, JSP, Ruby, Swift, Fortran, Scala, VB.NET, iOS, TypeScript
  • Well integrated in IDEs, supports most of compilers
  • Fine detection of bugs (static analysis)
  • Concurrency issues (concurrent data access, deadlocks, race conditions)
  • Security issues, …

4 SonarQube web interface

4.1 Overview

Please look at the Overview tab of your project.

One first thing you should think of is the question of the project visibility. Is your program free, opensource ? Do you want to share the SonarQube measures with your community ? If yes then go to the Administration -> Permissions tab and turn the project "Public". Hence the project will be examinable by anyone.

The main metrics are displayed such as the number of Bugs (reliability), Vulnerabilities (security aspects), Code Smells (encourage to follow standards), Unitary tests and Coverage, Duplications. Each measure is clickable, one can explore

  • graphs of measures to get nice views of the least/most impacted files
    • circles at top-left : this is not good you should do something
    • circles at bottom-right : good job
  • activity: historical trends in the course of several analysis
  • lists of issues

The Quality Gate (QG), is always in a "Passed" (green) status because we have decided not to use it by default. One can use it to define a state change of the code quality. For example if we get new bugs between two analysis then the QG becomes red and developers should be notified and fix the bugs to turn the QG green.

There is also the notion of "New Bugs", code smells etc, since previous version. What does this mean ? It simply reports how things get worse since the previous version number, the number used for the sonar.projectVersion parameter. If you change the version from 1.0 to 2.0 subsequent analysis will report new issues since the last analysis of version 1 in the "Leak Period: since 1.0" yellow part.

4.1.1 Exercices

  1. Could you figure out the technical debt trend of the hwloc library ?
  2. What Quality Profile is used by starpu v1.2 ?
  3. What is the programming language of ViSP, how many lines of code ?

4.2 Issues

By clicking on Issues you've got the list of all issues (bugs, vulnerabilities, code smells). The left part of the interface allows to filter the issues to improve the navigation and understanding.

This Issues tab is convenient to explore the results of static and dynamic analysis coming from the different tools (sonar-scanner, warning gcc, clang-sa, clang-tidy, cppcheck, valgrind, drmemory, etc) and to manage them. By manage we mean to decide whether or not the issues should be fixed or not. By default new issues have an Open status. The goal is to decrease the number of open issues. The first thing to do in the interface is to choose which issues should be fixed in a near future or not.

  1. Issues to be fixed are tagged Confirmed. If in the next analysis issues are not in the reports anymore then SonarQube will turn them as Fixed and Closed.
  2. Issues that are not fixed should be classified. Why not fixing these issues ? Is it because A. this is a false positive, and the issue should be tagged false positive B. the issue is known and we accept to keep it as it is for good reasons, the issue should be tagged won't fix

Remark: closed issues are kept for 30 days in the database.

There are many way to filter issues, see on the left side of the tab

  • Type : bug, vulnerabilities, code smells
  • Resolution and Status : Unresolved, fixed , Open, Closed, …
  • Rule : the issue name
  • Directory, File
  • Assignee, Author
  • Language

4.2.1 Exercices

  1. Fix the issues of type "Bug" in heat and submit another analysis
  2. How to deal with the code smell "Unable to find the source for '#include <mpi.h>'" ?
  3. Try to filter the issues dealing with memory problems
  4. Assign several issues to yourself with the Bulk Change button
  5. Change the Quality Profile of heat to sedbso:heat and submit a new analysis, what is happening with the code smells ? Can you figure out why ?

4.3 Measures

The Measures tab allows to get synthetic views with graphs, treemap, directory tree, about the bugs, vulnerabilities, code smells, coverage, unitary tests, duplications, size, complexity, issue kinds.

4.3.1 Exercices

  1. What is the signification of bubbles size and color in the project overview of the Measures tab ?
  2. For mmg develop branch, which files should be considered first to improve the maintainability ?
  3. How many classes are written in ViSP ?
  4. Can you explain why there is so many duplicated blocks in chameleon ?

4.4 Code

The Code tab allows to navigate in the code structure directory by directory and get the size (lines of code), the number of issues, the coverage percentage and the duplications.

4.4.1 Exercices

  1. In hwloc master branch which directory is mainly made of duplicate content ?

4.5 Activity

The Activity tab informs about the history of analysis. One can find the dates and some graphs to follow the trend of some measures.

4.5.1 Exercice

  1. What is the trend in term of Bugs and Code Smells in, hwloc, in mmg ?

4.6 Administration

4.6.1 Quality Profiles

4.6.2 Permissions

You can update permissions to make the project public or private (to hide or not the source code), add and remove users to be able to administrate the project and its issues. See also

4.7 Bonus

4.7.1 Email notifications

You can register to email notifications that inform about new analysis results and give a link to the project new issues.

Go to "My Account" (top right corner) -> "Notifications", in "Notifications per project", write the name of your project in the search bar, select it then check the boxes.

4.7.2 Bagdes

SVG badges can be added in some web pages in order to show the code quality measures.

4.7.3 3D view

See the tab More -> SoftVis3D Viewer.

Author: Florent Pruvost, Service Expérimentation et Dévelopement, Inria Bordeaux Sud-Ouest

Created: 2020-01-30 jeu. 23:01

Emacs 24.5.1 (Org mode 8.2.10)