Просмотр исходного кода

ignorera alla filer under .sonarqube

Axel Nordh 3 лет назад
Родитель
Сommit
d307094c1a

+ 1 - 1
.gitignore

@@ -51,4 +51,4 @@ sysinfo.txt
 crashlytics-build.properties
 
 # sonarqube files
-.sonarqube
+.sonarqube/*

BIN
.sonarqube/bin/SonarScanner.MSBuild.Common.dll


BIN
.sonarqube/bin/SonarScanner.MSBuild.Tasks.dll


+ 618 - 618
.sonarqube/bin/targets/SonarQube.Integration.targets

@@ -1,618 +1,618 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-
-  <!--
-    This file contains targets to integrate SonarQube and MSBuild.
-
-    The targets will produce an output folder structure containing information required by the sonar-scanner.
-
-    A subdirectory will be created for each MSBuild project. Information about the project
-    will be written to a file called "ProjectInfo.xml". Additional files may also be written
-    containing information required by different analyzers. In particular, a file will be written
-    containing the list of files in the project that should be analyzed by the sonar-scanner.
-
-    The output will only be produced if the property $(SonarQubeTempPath) and is specified.
-    $(SonarQubeTempPath) is the root folder under which per-analysis output should be written.
-
-    Excluding projects and files from SonarQube analysis
-    ****************************************************
-    Individual projects can excluded from SonarQube analysis by setting the property $(SonarQubeExclude) e.g.
-
-      <SonarQubeExclude>true</SonarQubeExclude>
-
-    Individual files can be excluded from analysis by setting the <SonarQubeExclude> metadata item e.g.
-
-      <Compile Include="Logger.cs">
-        <SonarQubeExclude>true</SonarQubeExclude>
-      </Compile>
-
-    Project is also excluded if it's recognized as a Fakes or a Temp project. These projects are auto-generated.
-
-    Test projects
-    *************
-    The analysis performed by SonarQube varies depending on whether a project is a test project or not.
-
-    A project can be explicitly marked as being a test or product project by setting the property $(SonarQubeTestProject) e.g.
-
-      <SonarQubeTestProject>true</SonarQubeTestProject>
-
-    If $(SonarQubeTestProject) is not set explicitly then the project is categorized as a Test project if:
-    * Is a Fakes or a Temp project explicitly marked as SonarQubeExclude=false
-    * Has one of the expected test project GUIDs ("3AC096D0-A1C2-E12C-1390-A8335801FDAB" or legacy "82A7F48D-3B50-4B1E-B82E-3ADA8210C358").
-    * Has a TestContainer project capability.
-    * References a known unit test related assembly.
-    * Deprecated: Project name matches "sonar.msbuild.testProjectPattern" parameter. Use SonarQubeTestProject=true instead.
-
-    Otherwise it is a Product project.
-
-    Supplying analysis setting in a project file
-    ********************************************
-    Project-level analysis settings can be specified in a project file using following
-    syntax:
-
-    <ItemGroup>
-      <SonarQubeSetting Include="sonar.my.analysis.setting">
-        <Value>42</Value>
-      </SonarQubeSetting>
-    </ItemGroup>
-
-    Settings specified in the project file will override those specified on the SonarQube server.
-
-    Specifying additional types of file to be analysed
-    **************************************************
-
-    The Scanner for MSBuild will automatically collect all of the common
-    file types that can be analysed by the various Sonar language plugins
-    (e.g. C# files, TypeScript, TSQL, C++ include and source files etc).
-    The full list of item types that will be included for analysis is
-    specified in $(SQAnalysisFileItemTypes) property below.
-
-    If you have any additional item types that you want to have analyzed,
-    you can specify them setting the property $(SQAdditionalAnalysisFileItemTypes)
-    in the project being analysed e.g.
-
-    <SQAdditionalAnalysisFileItemTypes>MyCustomFileType1;MyCustomFileType</SQAdditionalAnalysisFileItemTypes>
-
-    Specific handling of Razor builds
-    **************************************************
-    During the compilation of an SDK-style MSBuild project with Razor, MSBuild executes 2 build targets:
-    CoreCompile to compile the main code and RazorCoreCompile to compile ".cshtml" view files.
-    Since it is not possible to execute one target more than once, there's a logic that prevents RazorCoreCompile
-    from overriding output files from CoreCompile step:
-      * CoreCompile produces output files in directory "X", where X represents project specific unique number.
-      * Directory "X" with CoreCompile results is renamed to "X.tmp" before RazorCoreCompile and new empty directory "X" is prepared.
-      * RazorCoreCompile produces its output to the current directory "X".
-      * Directory "X" with Razor output is renamed to "X.Razor".
-      * Directory "X.tmp" with original output is renamed back to "X".
--->
-
-  <!-- **************************************************************************** -->
-  <!-- SonarQube MSBuild Integration implementation logic -->
-  <!-- **************************************************************************** -->
-  <!-- Note: where possible, these targets avoid taking dependencies on specific
-        managed or C++- targets e.g. they use
-           "AfterTargets='Build'" which is general rather than
-           "AfterTargets='CoreCompile'" which is specific to managed projects.
-  -->
-
-  <!-- Safeguard against importing this .targets file multiple times -->
-  <PropertyGroup>
-    <SonarQubeTargetsImported>true</SonarQubeTargetsImported>
-  </PropertyGroup>
-
-  <!-- Set defaults if explicit values have not been provided -->
-  <PropertyGroup Condition=" $(SonarQubeTempPath) != '' ">
-    <SonarQubeConfigPath Condition=" $(SonarQubeConfigPath) == '' ">$(SonarQubeTempPath)\conf</SonarQubeConfigPath>
-    <SonarQubeOutputPath Condition=" $(SonarQubeOutputPath) == '' ">$(SonarQubeTempPath)\out</SonarQubeOutputPath>
-
-    <!-- Specify the ItemGroups to be analyzed -->
-    <SQAnalysisFileItemTypes Condition=" $(SQAnalysisFileItemTypes) == '' ">AndroidEnvironment;AndroidJavaSource;AndroidResource;ApplicationDefinition;Build;ClCompile;ClInclude;Compile;Content;DeploymentExtensionConfiguration;EmbeddedResource;EntityDeploy;None;Page;PostDeploy;PRIResource;PreDeploy;RefactorLog;Resource;Script;ScriptCode;TypeScriptCompile;$(SQAdditionalAnalysisFileItemTypes)</SQAnalysisFileItemTypes>
-  </PropertyGroup>
-
-  <!-- **************************************************************************** -->
-  <!-- Using tasks -->
-  <!-- **************************************************************************** -->
-  <PropertyGroup Condition=" $(SonarQubeTempPath) != '' AND $(SonarQubeBuildTasksAssemblyFile) == '' ">
-    <!-- Assume that the tasks assembly is in the same location as this targets file
-         or in a parent directory unless another location has already been specified. -->
-    <SonarQubeBuildTasksAssemblyFile>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), SonarScanner.MSBuild.Tasks.dll))\SonarScanner.MSBuild.Tasks.dll</SonarQubeBuildTasksAssemblyFile>
-  </PropertyGroup>
-
-  <!-- Unescape the paths to work around the issue "MSBuild 4.0 UsingTask cannot have a path with parentheses".
-       See https://connect.microsoft.com/VisualStudio/feedback/details/713690/msbuild-4-0-usingtask-cannot-have-a-path-with-parentheses -->
-  <UsingTask TaskName="WriteProjectConfigFile" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
-  <UsingTask TaskName="WriteProjectInfoFile" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
-  <UsingTask TaskName="IsTestFileByName" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
-  <UsingTask TaskName="IsTestByReference" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
-  <UsingTask TaskName="GetAnalyzerSettings" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
-  <UsingTask TaskName="MakeUniqueDir" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
-  <UsingTask TaskName="WriteZeroLengthFiles" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
-
-  <!-- **************************************************************************** -->
-  <!-- **************************************************************************** -->
-  <!-- Targets -->
-  <!-- **************************************************************************** -->
-  <!-- **************************************************************************** -->
-
-  <Target Name="SkippingSonarQubeAnalysis" BeforeTargets="Build"
-          Condition=" $(SonarQubeTempPath) == '' ">
-    <Message Importance="high" Text="Sonar: ($(MSBuildProjectFile)) Skipping dumping compile outputs because SonarQubeTempPath has not been specified" />
-  </Target>
-
-  <Target Name="FailIfLowerThanMSBuild14"
-          Condition=" $(SonarQubeTempPath) != '' AND $(MSBuildToolsVersion) != '14.0' AND $(MSBuildToolsVersion) != '15.0' AND $(MSBuildToolsVersion) != 'Current'"
-          BeforeTargets="Build">
-    <Message Importance="high" Text="Sonar: ($(MSBuildProjectFile)) Current MSBuildToolsVersion: $(MSBuildToolsVersion)" />
-    <Message Importance="high" Text="Sonar: ($(MSBuildProjectFile)) Current MSBuildAssemblyVersion: $(MSBuildAssemblyVersion)" />
-    <Error Text="SonarQube analysis is only supported with MSBuild 14 or later." />
-  </Target>
-
-  <Target Name="SonarResolveReferencesMsBuild14"
-          AfterTargets="ResolveAssemblyReferences"
-          Condition=" $(SonarQubeTempPath) != '' AND $(MSBuildToolsVersion) == '14.0'">
-    <ItemGroup>
-      <SonarResolvedReferences Include="@(%(ReferencePath.FusionName))" />
-    </ItemGroup>
-  </Target>
-
-  <Target Name="SonarResolveReferences"
-          AfterTargets="FindReferenceAssembliesForReferences"
-          Condition=" $(SonarQubeTempPath) != '' AND $(MSBuildToolsVersion) != '14.0'">
-    <ItemGroup>
-      <SonarResolvedReferences Include="@(%(ReferencePathWithRefAssemblies.FusionName))" />
-    </ItemGroup>
-  </Target>
-
-  <!-- **************************************************************************** -->
-  <!-- Categorize as a product or test project -->
-  <!-- **************************************************************************** -->
-  <!-- This target is a utility target: it won't be executed unless a target that depends on it is executed. -->
-  <Target Name="SonarCategoriseProject"
-          DependsOnTargets="SonarResolveReferencesMsBuild14;SonarResolveReferences"
-          Condition=" $(SonarQubeTempPath) != '' ">
-
-    <Message Text="Sonar: ($(MSBuildProjectFile)) Categorizing project as test or product code..." />
-    <Message Condition="$(SonarQubeTestProject) != ''" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) SonarQubeTestProject has been set explicitly to $(SonarQubeTestProject)." />
-
-    <!-- Fakes detection -->
-    <PropertyGroup>
-      <IsFakesProject Condition="$(AssemblyName.EndsWith('.fakes', System.StringComparison.OrdinalIgnoreCase))">true</IsFakesProject>
-    </PropertyGroup>
-    <!-- Before deciding to exclude or tag as test such a project, make sure it is not a legitimate project that happens to be called something.fakes
-         In this case, we require from the user to explicitely state whether the project is to be analyzed/considered a test project -->
-    <PropertyGroup Condition="$(IsFakesProject) == 'true' and $(SonarQubeExclude) == ''">
-      <SonarQubeExclude>true</SonarQubeExclude>
-    </PropertyGroup>
-    <PropertyGroup Condition="$(IsFakesProject) == 'true' and $(SonarQubeTestProject) == ''">
-      <SonarQubeTestProject>true</SonarQubeTestProject>
-    </PropertyGroup>
-    <Message Condition="$(IsFakesProject) == 'true' and $(SonarQubeExclude) == 'true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project is a temporary project generated by Microsoft Fakes and will be ignored." />
-
-    <!-- Temporary project detection -->
-    <!-- Some kinds of project have logic to trigger additional special builds based on the same project file
-         e.g. WPF projects build a temporary assembly before the main compilation takes place.
-         We only want to analyze the "normal" build of the project, so we should turn off analysis for the known cases. -->
-    <PropertyGroup>
-      <!-- Special case 1: WPF projects call the task Windows.GenerateTemporaryTargetAssembly in PresentationBuildTasks. -->
-      <IsTempProject Condition="$(MSBuildProjectFile.EndsWith('.tmp_proj', System.StringComparison.OrdinalIgnoreCase))">true</IsTempProject>
-      <IsTempProject Condition="$(MSBuildProjectFile.EndsWith('_wpftmp.csproj', System.StringComparison.OrdinalIgnoreCase))">true</IsTempProject>
-      <IsTempProject Condition="$(MSBuildProjectFile.EndsWith('_wpftmp.vbproj', System.StringComparison.OrdinalIgnoreCase))">true</IsTempProject>
-    </PropertyGroup>
-
-    <PropertyGroup Condition="$(IsTempProject) == 'true' AND $(SonarQubeExclude)==''" >
-      <SonarQubeExclude>true</SonarQubeExclude>
-    </PropertyGroup>
-    <Message Condition="$(IsTempProject) == 'true' AND $(SonarQubeExclude)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project is a temporary project and will be excluded." />
-
-    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
-      <!-- The MS Test project type guid -->
-      <SonarQubeMsTestProjectTypeGuid>3AC096D0-A1C2-E12C-1390-A8335801FDAB</SonarQubeMsTestProjectTypeGuid>
-      <tmpSonarHasMSTestProjectTypeGuid Condition=" $(ProjectTypeGuids.ToUpperInvariant().Contains('$(SonarQubeMsTestProjectTypeGuid)')) ">true</tmpSonarHasMSTestProjectTypeGuid>
-      <SonarQubeTestProject Condition=" $(tmpSonarHasMSTestProjectTypeGuid)=='true' ">true</SonarQubeTestProject>
-    </PropertyGroup>
-    <Message Condition="$(tmpSonarHasMSTestProjectTypeGuid)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project has the MSTest project type guid -> test project." />
-
-    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
-      <!-- The legacy Service tag added by the Test Explorer window -->
-      <tmpSQServiceList>@(Service)</tmpSQServiceList>
-      <tmpSonarHasServiceTag Condition="$(tmpSQServiceList.ToUpperInvariant().Contains('{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}')) ">true</tmpSonarHasServiceTag>
-      <SonarQubeTestProject Condition="$(tmpSonarHasServiceTag)=='true'">true</SonarQubeTestProject>
-    </PropertyGroup>
-    <Message Condition="$(tmpSonarHasServiceTag)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project has the legacy Test Explorer Service tag {82A7F48D-3B50-4B1E-B82E-3ADA8210C358} -> test project." />
-
-    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
-      <!-- The ProjectCapability for test projects -->
-      <tmpSQProjectCapabilities>@(ProjectCapability)</tmpSQProjectCapabilities>
-      <tmpSonarHasTestContainerCapability Condition="$(tmpSQProjectCapabilities.ToUpperInvariant().Contains('TESTCONTAINER')) ">true</tmpSonarHasTestContainerCapability>
-      <SonarQubeTestProject Condition="$(tmpSonarHasTestContainerCapability)=='true'">true</SonarQubeTestProject>
-    </PropertyGroup>
-    <Message Condition="$(tmpSonarHasTestContainerCapability)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project has the ProjectCapability 'TestContainer' -> test project." />
-
-    <IsTestByReference Condition=" $(SonarQubeTestProject) == '' "
-        References="@(SonarResolvedReferences)">
-      <Output TaskParameter="TestReference" PropertyName="tmpSonarTestReferenceResult" />
-    </IsTestByReference>
-    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
-      <SonarQubeTestProject Condition="$(tmpSonarTestReferenceResult)!=''">true</SonarQubeTestProject>
-    </PropertyGroup>
-    <Message Condition="$(tmpSonarTestReferenceResult)!=''" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project is evaluated as a test project based on the '$(tmpSonarTestReferenceResult)' reference." />
-
-    <!-- If we haven't already determined whether the project is a test project then check its path/name against the regular expression in the config file -->
-    <IsTestFileByName Condition=" $(SonarQubeTestProject) == '' "
-        AnalysisConfigDir="$(SonarQubeConfigPath)"
-        FullFilePath="$(MSBuildProjectFullPath)">
-      <Output TaskParameter="IsTest" PropertyName="tmpSonarIsTestFileByNameResult" />
-    </IsTestFileByName>
-
-    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
-      <SonarQubeTestProject>$(tmpSonarIsTestFileByNameResult)</SonarQubeTestProject>
-    </PropertyGroup>
-    <Message Condition="$(tmpSonarIsTestFileByNameResult)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project is evaluated as a test project based on the project name." />
-
-    <Message Importance="normal" Condition="$(SonarQubeTestProject)=='false'" Text="Sonar: ($(MSBuildProjectFile)) categorized as MAIN project (production code)." />
-    <Message Importance="normal" Condition="$(SonarQubeTestProject)=='true'"  Text="Sonar: ($(MSBuildProjectFile)) categorized as TEST project (test code)." />
-  </Target>
-
-  <!-- **************************************************************************** -->
-  <!-- Calculate the set of files to be analyzed -->
-  <!-- **************************************************************************** -->
-  <!-- This target is a utility target: it won't be executed unless a target that
-       depends on it is executed.
-  -->
-  <Target Name="SonarWriteFilesToAnalyze"
-        Condition=" $(SonarQubeTempPath) != '' ">
-
-    <!-- Include all of contents of the specified item groups, but exclude
-         any that have the metadata 'SonarQubeExclude' set, or that are auto-generated -->
-    <ItemGroup Condition="('$(SQAnalysisFileItemTypes)' != '')">
-      <SonarQubeAnalysisFileItems Include="$(SQAnalysisFileItemTypes)" />
-      <SonarQubeAnalysisFiles Include="@(%(SonarQubeAnalysisFileItems.Identity))" />
-      <SonarQubeAnalysisFiles Remove="@(SonarQubeAnalysisFiles)" Condition=" %(SonarQubeAnalysisFiles.SonarQubeExclude) == 'true' OR %(SonarQubeAnalysisFiles.AutoGen) == 'true' OR %(SonarQubeAnalysisFiles.FullPath) == '$(TargetFrameworkMonikerAssemblyAttributesPath)'" />
-    </ItemGroup>
-
-    <!-- Exclude items under the intermediate output folder e.g. XAML files that are auto-generated on build -->
-    <PropertyGroup>
-      <!-- Calculate the full path to the base intermediate folder -->
-      <SQFullIntermediateOutputPath>$([System.IO.Path]::Combine($(MSBuildProjectDirectory),$(BaseIntermediateOutputPath)))</SQFullIntermediateOutputPath>
-    </PropertyGroup>
-    <ItemGroup>
-      <!-- Remove based on absolute path -->
-      <SQIntermediateFiles Include="$(SQFullIntermediateOutputPath)**\*.*" />
-      <!-- Remove based on relative path -->
-      <SQIntermediateFiles Include="$(BaseIntermediateOutputPath)**\*.*" />
-      <SonarQubeAnalysisFiles Remove="@(SQIntermediateFiles)" />
-    </ItemGroup>
-
-    <PropertyGroup>
-      <!-- Set a property indicating whether there are any files to analyze -->
-      <AnalysisFilesExist Condition=" @(SonarQubeAnalysisFiles) != '' ">true</AnalysisFilesExist>
-    </PropertyGroup>
-
-    <!-- Write the list of files  -->
-    <PropertyGroup>
-      <!-- Set the file name for the list file -->
-      <AnalysisFileList>$(ProjectSpecificConfDir)\FilesToAnalyze.txt</AnalysisFileList>
-    </PropertyGroup>
-
-    <Message Condition="$(AnalysisFilesExist)!='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) No files were found to analyse" />
-    <Message Condition="$(AnalysisFilesExist)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) Number of files to analyse: @(SonarQubeAnalysisFiles->Count()). The list of files to be analyzed is in $(AnalysisFileList)." />
-
-    <!-- Write out a list of files to analyze that will be passed to the sonar-scanner -->
-    <WriteLinesToFile Condition=" $(AnalysisFilesExist) == 'true' "
-            File="$(AnalysisFileList)"
-            Lines="%(SonarQubeAnalysisFiles.FullPath)"
-            Overwrite="false"
-            Encoding="utf-8" />
-  </Target>
-
-  <Target Name="SonarCreateProjectSpecificDirs" BeforeTargets="OverrideRoslynCodeAnalysisProperties;SonarWriteProjectData;SonarWriteFilesToAnalyze"  Condition=" $(SonarQubeTempPath) != '' ">
-    <!-- **************************************************************************** -->
-    <!-- Create the project-specific directories for conf and out -->
-
-    <!-- Create folder with unique name in the .sonarqube/out/ folder -->
-    <MakeUniqueDir Path="$(SonarQubeOutputPath)">
-      <Output TaskParameter="UniquePath" PropertyName="ProjectSpecificOutDir" />
-      <Output TaskParameter="UniqueName" PropertyName="UniqueName" />
-    </MakeUniqueDir>
-    <!-- Create .sonarqube/conf/ sub-folder with the same unique name -->
-    <PropertyGroup>
-      <ProjectSpecificConfDir>$(SonarQubeConfigPath)\$(UniqueName)</ProjectSpecificConfDir>
-    </PropertyGroup>
-    <MakeDir Directories="$(ProjectSpecificConfDir)" />
-  </Target>
-
-  <!-- SonarWriteProjectData has to be invoked after the Build target, so it can pick up the results for C++ projects.  -->
-  <Target Name="InvokeSonarWriteProjectData_NonRazorProject"
-          DependsOnTargets="SonarCategoriseProject;SonarWriteFilesToAnalyze;SonarCreateProjectSpecificDirs"
-          AfterTargets="Build"
-          Condition=" $(SonarQubeTempPath) != '' AND ('@(RazorCompile)'=='' OR ('@(RazorCompile)'!='' AND '$(UseRazorSourceGenerator)'=='true'))  ">
-    <CallTarget Targets="SonarWriteProjectData" />
-  </Target>
-
-  <Target Name="InvokeSonarWriteProjectData_RazorProject"
-          DependsOnTargets="SonarCategoriseProject;SonarWriteFilesToAnalyze;SonarCreateProjectSpecificDirs"
-          BeforeTargets="SonarPrepareRazorProjectCodeAnalysis"
-          AfterTargets="CoreCompile"
-          Condition=" $(SonarQubeTempPath) != '' AND '@(RazorCompile)'!='' AND ('$(UseRazorSourceGenerator)'=='' OR '$(UseRazorSourceGenerator)'=='false') ">
-    <CallTarget Targets="SonarWriteProjectData" />
-  </Target>
-
-  <Target Name="SonarWriteProjectData" >
-    <PropertyGroup>
-      <SonarErrorLogExists Condition=" $(SonarErrorLog) != '' AND  $([System.IO.File]::Exists($(SonarErrorLog))) == 'true' ">true</SonarErrorLogExists>
-    </PropertyGroup>
-
-    <ItemGroup>
-      <SonarReportFilePath Condition= "$(SonarErrorLogExists) == 'true'" Include="$(SonarErrorLog)" />
-    </ItemGroup>
-
-    <ItemGroup>
-      <SonarQubeSetting Include="sonar.$(SQLanguage).roslyn.reportFilePaths" Condition=" @(SonarReportFilePath) != '' ">
-        <!-- Join the paths with |  -->
-        <!-- This delimiter needs to be the same as PropertiesFileGenerator.RoslynReportPathsDelimiter -->
-        <Value>@(SonarReportFilePath->'%(identity)','|')</Value>
-      </SonarQubeSetting>
-      <SonarQubeSetting Include="sonar.$(SQLanguage).analyzer.projectOutPaths" Condition= "$(SonarErrorLogExists) == 'true'">
-        <Value>$(ProjectSpecificOutDir)</Value>
-      </SonarQubeSetting>
-    </ItemGroup>
-
-    <!-- Record the list of files as an analysis result -->
-    <ItemGroup Condition=" $(AnalysisFilesExist) == 'true' ">
-      <AnalysisResults Include="$(AnalysisFileList)">
-        <Id>FilesToAnalyze</Id>
-      </AnalysisResults>
-    </ItemGroup>
-
-    <CallTarget Targets="FixUpTestProjectOutputs" />
-
-    <WriteProjectInfoFile ProjectName="$(MSBuildProjectName)"
-       FullProjectPath="$(MSBuildProjectFullPath)"
-       ProjectLanguage="$(Language)"
-       ProjectGuid="$(ProjectGuid)"
-       SolutionConfigurationContents="$(CurrentSolutionConfigurationContents)"
-       IsTest="$(SonarQubeTestProject)"
-       IsExcluded="$(SonarQubeExclude)"
-       AnalysisResults="@(AnalysisResults)"
-       AnalysisSettings="@(SonarQubeSetting)"
-       OutputFolder="$(ProjectSpecificOutDir)"
-       CodePage="$(CodePage)"
-       Configuration="$(Configuration)"
-       Platform="$(Platform)"
-       TargetFramework="$(TargetFramework)" />
-
-    <Message Importance="high" Text="Sonar: ($(MSBuildProjectFile)) Project processed successfully" />
-  </Target>
-
-  <!--
-    Set the Razor specific error log properties.
-    Move the results of the core compilation to a temporary folder to prevent RazorCoreCompilation from overriding its content.
-    The contents will be moved back in SonarFinishRazorProjectCodeAnalysis target.
-  -->
-  <Target Name="SonarPrepareRazorProjectCodeAnalysis" BeforeTargets="RazorCoreCompile" AfterTargets="CoreCompile" Condition="'@(RazorCompile)'!='' AND ('$(UseRazorSourceGenerator)'=='' OR '$(UseRazorSourceGenerator)'=='false')" >
-    <PropertyGroup Condition=" $(SonarErrorLog) != '' ">
-      <!-- https://github.com/SonarSource/sonar-scanner-msbuild/issues/1015 Respect user-provided value. When set, users should provide unique path for each build (project and target framework). -->
-      <RazorSonarErrorLogName Condition=" $(RazorCompilationErrorLog) == '' ">Issues$(RazorTargetNameSuffix).json</RazorSonarErrorLogName>
-      <RazorCompilationErrorLog Condition=" $(RazorSonarErrorLogName) != '' ">$(ProjectSpecificOutDir)\$(RazorSonarErrorLogName)</RazorCompilationErrorLog>
-      <ErrorLog>$(RazorCompilationErrorLog)</ErrorLog>
-      <!-- Keep the path so that we could set SonarQubeSetting with sonar.language.roslyn.reportFilePaths -->
-      <RazorSonarErrorLog>$(RazorCompilationErrorLog)</RazorSonarErrorLog>
-    </PropertyGroup>
-    <PropertyGroup>
-      <SonarTemporaryProjectSpecificOutDir>$(ProjectSpecificOutDir).tmp</SonarTemporaryProjectSpecificOutDir>
-    </PropertyGroup>
-    <ItemGroup>
-      <CoreCompileOutFiles Include="$(ProjectSpecificOutDir)\**\*.*"/>
-    </ItemGroup>
-    <Move
-      SourceFiles="@(CoreCompileOutFiles)"
-      DestinationFolder="$(SonarTemporaryProjectSpecificOutDir)\%(RecursiveDir)" />
-    <Message Importance="high" Text="Sonar: Preparing for Razor compilation, moved files (@(CoreCompileOutFiles)) to $(SonarTemporaryProjectSpecificOutDir)." />
-  </Target>
-
-  <!-- In case of Razor compilation the output files generated during the core compilation step are already moved into a temporary folder.
-       This target renames output directories to their final state and creates the ProjectInfo.xml for them.
-  -->
-  <Target Name="SonarFinishRazorProjectCodeAnalysis" AfterTargets="RazorCoreCompile;InvokeSonarWriteProjectData_RazorProject" Condition=" $(SonarTemporaryProjectSpecificOutDir) != '' AND '@(RazorCompile)'!='' AND ('$(UseRazorSourceGenerator)'=='' OR '$(UseRazorSourceGenerator)'=='false') ">
-    <PropertyGroup>
-      <RazorSonarProjectSpecificOutDir>$(ProjectSpecificOutDir).Razor</RazorSonarProjectSpecificOutDir>
-      <RazorSonarProjectInfo>$(RazorSonarProjectSpecificOutDir)\ProjectInfo.xml</RazorSonarProjectInfo>
-    </PropertyGroup>
-    <ItemGroup>
-      <RazorCompilationOutFiles Include="$(ProjectSpecificOutDir)\**\*.*"/>
-      <SonarTempFiles Include="$(SonarTemporaryProjectSpecificOutDir)\**\*.*"/>
-    </ItemGroup>
-
-    <!-- Move main and Razor results to their final location. -->
-    <Move
-      SourceFiles="@(RazorCompilationOutFiles)"
-      DestinationFolder="$(RazorSonarProjectSpecificOutDir)\%(RecursiveDir)" />
-    <Message Importance="high" Text="Sonar: After Razor compilation, moved files (@(RazorCompilationOutFiles)) to $(RazorSonarProjectSpecificOutDir)." />
-
-    <Move
-      SourceFiles="@(SonarTempFiles)"
-      DestinationFolder="$(ProjectSpecificOutDir)\%(RecursiveDir)" />
-    <Message Importance="high" Text="Sonar: After Razor compilation, moved files (@(SonarTempFiles)) to $(ProjectSpecificOutDir) and will remove the temporary folder." />
-    <RemoveDir Directories="$(SonarTemporaryProjectSpecificOutDir)" />
-
-    <PropertyGroup>
-      <!-- This overwrites the previously set 'RazorSonarErrorLog' in 'SonarPrepareRazorProjectCodeAnalysis'
-           if 'RazorSonarErrorLogName' is set, which means 'RazorCompilationErrorLog' was null.
-           The condition is a bit difficult to follow, it would be easier to change it or also add "$(RazorSonarErrorLog) != ''" -->
-      <RazorSonarErrorLog Condition=" $(RazorSonarErrorLogName) != '' ">$(RazorSonarProjectSpecificOutDir)\$(RazorSonarErrorLogName)</RazorSonarErrorLog>
-      <RazorSonarErrorLogExists Condition=" $(RazorSonarErrorLog) != '' AND  $([System.IO.File]::Exists($(RazorSonarErrorLog))) == 'true' ">true</RazorSonarErrorLogExists>
-    </PropertyGroup>
-
-    <ItemGroup>
-      <RazorSonarReportFilePath Condition= "$(RazorSonarErrorLogExists) == 'true'" Include="$(RazorSonarErrorLog)" />
-      <RazorSonarQubeSetting Include="sonar.$(SQLanguage).roslyn.reportFilePaths" Condition=" @(RazorSonarReportFilePath) != '' ">
-        <!-- Join the paths with |  -->
-        <!-- This delimiter needs to be the same as PropertiesFileGenerator.RoslynReportPathsDelimiter -->
-        <Value>@(RazorSonarReportFilePath->'%(identity)','|')</Value>
-      </RazorSonarQubeSetting>
-      <RazorSonarQubeSetting Include="sonar.$(SQLanguage).analyzer.projectOutPaths" Condition= "$(RazorSonarErrorLogExists) == 'true'">
-        <Value>$(RazorSonarProjectSpecificOutDir)</Value>
-      </RazorSonarQubeSetting>
-    </ItemGroup>
-
-    <!-- Create the ProjectInfo.xml for the Razor part. -->
-    <WriteProjectInfoFile ProjectName="$(MSBuildProjectName)"
-                          FullProjectPath="$(MSBuildProjectFullPath)"
-                          ProjectLanguage="$(Language)"
-                          ProjectGuid="$(ProjectGuid)"
-                          SolutionConfigurationContents="$(CurrentSolutionConfigurationContents)"
-                          IsTest="$(SonarQubeTestProject)"
-                          IsExcluded="$(SonarQubeExclude)"
-                          AnalysisResults="@(AnalysisResults)"
-                          AnalysisSettings="@(RazorSonarQubeSetting)"
-                          OutputFolder="$(RazorSonarProjectSpecificOutDir)"
-                          CodePage="$(CodePage)"
-                          Configuration="$(Configuration)"
-                          Platform="$(Platform)"
-                          TargetFramework="$(TargetFramework)" />
-  </Target>
-
-  <Target Name="FixUpTestProjectOutputs" Condition="$(SonarQubeTestProject)=='true'" >
-    <Message Importance="low" Text="Sonar: ($(MSBuildProjectFile)) Fixing up test project outputs..." />
-
-    <ItemGroup>
-      <!-- Select specific metrics files that should not be uploaded for test files.
-           Assumption: these files will be in a sub-folder under the project-specific output folder. -->
-      <SQTestMetricFiles Include="$(ProjectSpecificOutDir)\*\metrics.pb" />
-      <SQTestMetricFiles Include="$(ProjectSpecificOutDir)\*\token-cpd.pb" />
-    </ItemGroup>
-
-    <Message Importance="low" Text="Sonar: ($(MSBuildProjectFile)) Selected test metric file: @(SQTestMetricFiles)" />
-    <WriteZeroLengthFiles FullFilePaths="@(SQTestMetricFiles)" />
-  </Target>
-
-  <!-- **************************************************************************** -->
-  <!-- Code analysis -->
-  <!-- **************************************************************************** -->
-  <!--  Implementation notes:
-
-        We want to override any code analysis-related properties that are set in the
-        project file. To do this, we need to execute our targets at the correct
-        point in the build.
-
-        Note that both the FxCop and Roslyn targets use a property called "CodeAnalysisRuleSet".
-        The FxCop targets use this value directly. However, the Roslyn targets use it
-        as input to the "ResolveCodeAnalysisRuleSet" target, which sets the property
-        "ResolvedCodeAnalysisRuleset".
-
-        We override the property "ResolveCodeAnalysisRuleSet" with the path to our Roslyn ruleset.
-  -->
-
-  <PropertyGroup>
-    <SQLanguage Condition="$(Language) == 'C#'">cs</SQLanguage>
-    <SQLanguage Condition="$(Language) == 'VB'">vbnet</SQLanguage>
-  </PropertyGroup>
-
-  <!-- **************************************************************************** -->
-  <!-- Roslyn analysis section -->
-  <!-- **************************************************************************** -->
-  <!-- Override VS2019 properties to make sure analysis runs in the scanner build.
-       We need to run before BeforeCompile that executes _ComputeSkipAnalyzers target.
-       We don't need to override this for excluded projects. -->
-  <Target Name="SonarOverrideRunAnalyzers"
-        Condition=" $(SonarQubeTempPath) != '' AND $(SonarQubeExclude) != 'true' "
-        BeforeTargets="BeforeCompile">
-
-    <PropertyGroup>
-      <RunAnalyzers>true</RunAnalyzers>
-      <RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
-    </PropertyGroup>
-  </Target>
-
-  <!-- Set the properties required to run Roslyn analysis as part of the build.
-       Analysis is controlled by the following properties:
-         ResolvedCodeAnalysisRuleSet - the full path to the ruleset to use
-         ErrorLog and RazorCompilationErrorLog - the file path for the error reporting file
-
-       We want to run after the core "ResolveCodeAnalysisRuleSet" target which assigns a value to "ResolvedCodeAnalysisRuleSet".
-
-       Conditions:
-       * project is excluded -> turn off Roslyn analysis
-       * project is a test project and parameter sonar.dotnet.excludeTestProjects=true -> run only metrics rules
-       * otherwise, use the analyzer settings loaded from the config file (removing any existing analyzers)
-   -->
-  <Target Name="OverrideRoslynCodeAnalysisProperties"
-        Condition=" $(SonarQubeTempPath) != '' "
-        DependsOnTargets="SonarCategoriseProject;SonarWriteFilesToAnalyze"
-        AfterTargets="ResolveCodeAnalysisRuleSet"
-        BeforeTargets="CoreCompile">
-
-    <PropertyGroup>
-      <!-- Make sure no warnings are treated as errors -->
-      <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-      <WarningsAsErrors></WarningsAsErrors>
-
-      <!-- The Roslyn analyzers output messages with different warning levels. This is tied to the diagnostic severity and currently
-      is translated as follows - error: 0, warning: 1, info: 4. To avoid issues being missed override the warning level by setting it to max tolerance.-->
-      <WarningLevel>4</WarningLevel>
-    </PropertyGroup>
-
-    <CallTarget Targets="SetRoslynCodeAnalysisProperties" Condition="$(SonarQubeExclude) != 'true'" />
-  </Target>
-
-  <Target Name="SetRoslynCodeAnalysisProperties">
-
-    <!-- Fetch the relevant settings from the config file -->
-    <GetAnalyzerSettings AnalysisConfigDir="$(SonarQubeConfigPath)"
-                         Language="$(SQLanguage)"
-                         CurrentProjectDirectoryPath="$(MSBuildProjectDirectory)"
-                         OriginalAnalyzers="@(Analyzer)"
-                         OriginalAdditionalFiles="@(AdditionalFiles)"
-                         OriginalRulesetFilePath="$(ResolvedCodeAnalysisRuleset)"
-                         ProjectSpecificConfigDirectory="$(ProjectSpecificConfDir)"
-                         IsTestProject="$(SonarQubeTestProject)">
-      <Output TaskParameter="RuleSetFilePath" PropertyName="SQRuleSetFilePath" />
-      <Output TaskParameter="AnalyzerFilePaths" ItemName="SQAnalyzerFilePaths" />
-      <Output TaskParameter="AdditionalFilePaths" ItemName="SQAdditionalFiles" />
-    </GetAnalyzerSettings>
-
-    <PropertyGroup>
-      <!-- https://github.com/SonarSource/sonar-scanner-msbuild/issues/1015 Respect user-provided value. When set, users should provide unique path for each build (project and target framework). -->
-      <!-- https://jira.sonarsource.com/browse/SONARMSBRU-211 - the full path should be unique per project and target framework. -->
-      <ErrorLog Condition=" $(ErrorLog) == '' ">$(ProjectSpecificOutDir)\Issues.json</ErrorLog>
-      <!-- Keep the path so that we could set SonarQubeSetting with sonar.language.roslyn.reportFilePaths -->
-      <SonarErrorLog>$(ErrorLog)</SonarErrorLog>
-    </PropertyGroup>
-
-    <PropertyGroup>
-      <ResolvedCodeAnalysisRuleSet>$(SQRuleSetFilePath)</ResolvedCodeAnalysisRuleSet>
-      <SonarProjectOutFolderFilePath>$(ProjectSpecificConfDir)\ProjectOutFolderPath.txt</SonarProjectOutFolderFilePath>
-    </PropertyGroup>
-
-    <!--SonarProjectOutFolderFilePath is generated only for backward compatibility with CSharp and VBNet analyzers before 8.20 -->
-    <WriteLinesToFile File="$(SonarProjectOutFolderFilePath)" Lines="$(ProjectSpecificOutDir)" Overwrite="true" />
-
-    <WriteProjectConfigFile ConfigDir="$(ProjectSpecificConfDir)"
-                            AnalysisConfigPath="$(SonarQubeConfigPath)\SonarQubeAnalysisConfig.xml"
-                            ProjectPath="$(MSBuildProjectFullPath)"
-                            FilesToAnalyzePath ="$(AnalysisFileList)"
-                            OutPath="$(ProjectSpecificOutDir)"
-                            IsTest="$(SonarQubeTestProject)"
-                            TargetFramework="$(TargetFramework)">
-      <Output TaskParameter="ProjectConfigFilePath" PropertyName="SonarProjectConfigFilePath" />
-    </WriteProjectConfigFile>
-
-    <ItemGroup>
-      <!-- Clear the original set of analyzers and additional files -->
-      <Analyzer Remove="@(Analyzer)" />
-      <AdditionalFiles Remove="@(AdditionalFiles)" />
-
-      <!-- Use the set of analyzers and additional files calculated by the GetAnalyzerSettings task -->
-      <Analyzer Include="@(SQAnalyzerFilePaths)" />
-      <AdditionalFiles Include="@(SQAdditionalFiles)" />
-      <AdditionalFiles Include="$(SonarProjectConfigFilePath)" />
-      <AdditionalFiles Include="$(SonarProjectOutFolderFilePath)" />
-    </ItemGroup>
-
-    <Message Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) Analysis configured successfully with $(SonarProjectConfigFilePath)." />
-  </Target>
-  <!-- **************************************************************************** -->
-  <!-- End of Roslyn analysis section-->
-  <!-- **************************************************************************** -->
-
-</Project>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <!--
+    This file contains targets to integrate SonarQube and MSBuild.
+
+    The targets will produce an output folder structure containing information required by the sonar-scanner.
+
+    A subdirectory will be created for each MSBuild project. Information about the project
+    will be written to a file called "ProjectInfo.xml". Additional files may also be written
+    containing information required by different analyzers. In particular, a file will be written
+    containing the list of files in the project that should be analyzed by the sonar-scanner.
+
+    The output will only be produced if the property $(SonarQubeTempPath) and is specified.
+    $(SonarQubeTempPath) is the root folder under which per-analysis output should be written.
+
+    Excluding projects and files from SonarQube analysis
+    ****************************************************
+    Individual projects can excluded from SonarQube analysis by setting the property $(SonarQubeExclude) e.g.
+
+      <SonarQubeExclude>true</SonarQubeExclude>
+
+    Individual files can be excluded from analysis by setting the <SonarQubeExclude> metadata item e.g.
+
+      <Compile Include="Logger.cs">
+        <SonarQubeExclude>true</SonarQubeExclude>
+      </Compile>
+
+    Project is also excluded if it's recognized as a Fakes or a Temp project. These projects are auto-generated.
+
+    Test projects
+    *************
+    The analysis performed by SonarQube varies depending on whether a project is a test project or not.
+
+    A project can be explicitly marked as being a test or product project by setting the property $(SonarQubeTestProject) e.g.
+
+      <SonarQubeTestProject>true</SonarQubeTestProject>
+
+    If $(SonarQubeTestProject) is not set explicitly then the project is categorized as a Test project if:
+    * Is a Fakes or a Temp project explicitly marked as SonarQubeExclude=false
+    * Has one of the expected test project GUIDs ("3AC096D0-A1C2-E12C-1390-A8335801FDAB" or legacy "82A7F48D-3B50-4B1E-B82E-3ADA8210C358").
+    * Has a TestContainer project capability.
+    * References a known unit test related assembly.
+    * Deprecated: Project name matches "sonar.msbuild.testProjectPattern" parameter. Use SonarQubeTestProject=true instead.
+
+    Otherwise it is a Product project.
+
+    Supplying analysis setting in a project file
+    ********************************************
+    Project-level analysis settings can be specified in a project file using following
+    syntax:
+
+    <ItemGroup>
+      <SonarQubeSetting Include="sonar.my.analysis.setting">
+        <Value>42</Value>
+      </SonarQubeSetting>
+    </ItemGroup>
+
+    Settings specified in the project file will override those specified on the SonarQube server.
+
+    Specifying additional types of file to be analysed
+    **************************************************
+
+    The Scanner for MSBuild will automatically collect all of the common
+    file types that can be analysed by the various Sonar language plugins
+    (e.g. C# files, TypeScript, TSQL, C++ include and source files etc).
+    The full list of item types that will be included for analysis is
+    specified in $(SQAnalysisFileItemTypes) property below.
+
+    If you have any additional item types that you want to have analyzed,
+    you can specify them setting the property $(SQAdditionalAnalysisFileItemTypes)
+    in the project being analysed e.g.
+
+    <SQAdditionalAnalysisFileItemTypes>MyCustomFileType1;MyCustomFileType</SQAdditionalAnalysisFileItemTypes>
+
+    Specific handling of Razor builds
+    **************************************************
+    During the compilation of an SDK-style MSBuild project with Razor, MSBuild executes 2 build targets:
+    CoreCompile to compile the main code and RazorCoreCompile to compile ".cshtml" view files.
+    Since it is not possible to execute one target more than once, there's a logic that prevents RazorCoreCompile
+    from overriding output files from CoreCompile step:
+      * CoreCompile produces output files in directory "X", where X represents project specific unique number.
+      * Directory "X" with CoreCompile results is renamed to "X.tmp" before RazorCoreCompile and new empty directory "X" is prepared.
+      * RazorCoreCompile produces its output to the current directory "X".
+      * Directory "X" with Razor output is renamed to "X.Razor".
+      * Directory "X.tmp" with original output is renamed back to "X".
+-->
+
+  <!-- **************************************************************************** -->
+  <!-- SonarQube MSBuild Integration implementation logic -->
+  <!-- **************************************************************************** -->
+  <!-- Note: where possible, these targets avoid taking dependencies on specific
+        managed or C++- targets e.g. they use
+           "AfterTargets='Build'" which is general rather than
+           "AfterTargets='CoreCompile'" which is specific to managed projects.
+  -->
+
+  <!-- Safeguard against importing this .targets file multiple times -->
+  <PropertyGroup>
+    <SonarQubeTargetsImported>true</SonarQubeTargetsImported>
+  </PropertyGroup>
+
+  <!-- Set defaults if explicit values have not been provided -->
+  <PropertyGroup Condition=" $(SonarQubeTempPath) != '' ">
+    <SonarQubeConfigPath Condition=" $(SonarQubeConfigPath) == '' ">$(SonarQubeTempPath)\conf</SonarQubeConfigPath>
+    <SonarQubeOutputPath Condition=" $(SonarQubeOutputPath) == '' ">$(SonarQubeTempPath)\out</SonarQubeOutputPath>
+
+    <!-- Specify the ItemGroups to be analyzed -->
+    <SQAnalysisFileItemTypes Condition=" $(SQAnalysisFileItemTypes) == '' ">AndroidEnvironment;AndroidJavaSource;AndroidResource;ApplicationDefinition;Build;ClCompile;ClInclude;Compile;Content;DeploymentExtensionConfiguration;EmbeddedResource;EntityDeploy;None;Page;PostDeploy;PRIResource;PreDeploy;RefactorLog;Resource;Script;ScriptCode;TypeScriptCompile;$(SQAdditionalAnalysisFileItemTypes)</SQAnalysisFileItemTypes>
+  </PropertyGroup>
+
+  <!-- **************************************************************************** -->
+  <!-- Using tasks -->
+  <!-- **************************************************************************** -->
+  <PropertyGroup Condition=" $(SonarQubeTempPath) != '' AND $(SonarQubeBuildTasksAssemblyFile) == '' ">
+    <!-- Assume that the tasks assembly is in the same location as this targets file
+         or in a parent directory unless another location has already been specified. -->
+    <SonarQubeBuildTasksAssemblyFile>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), SonarScanner.MSBuild.Tasks.dll))\SonarScanner.MSBuild.Tasks.dll</SonarQubeBuildTasksAssemblyFile>
+  </PropertyGroup>
+
+  <!-- Unescape the paths to work around the issue "MSBuild 4.0 UsingTask cannot have a path with parentheses".
+       See https://connect.microsoft.com/VisualStudio/feedback/details/713690/msbuild-4-0-usingtask-cannot-have-a-path-with-parentheses -->
+  <UsingTask TaskName="WriteProjectConfigFile" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
+  <UsingTask TaskName="WriteProjectInfoFile" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
+  <UsingTask TaskName="IsTestFileByName" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
+  <UsingTask TaskName="IsTestByReference" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
+  <UsingTask TaskName="GetAnalyzerSettings" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
+  <UsingTask TaskName="MakeUniqueDir" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
+  <UsingTask TaskName="WriteZeroLengthFiles" AssemblyFile="$([MSBUILD]::Unescape($(SonarQubeBuildTasksAssemblyFile)))" />
+
+  <!-- **************************************************************************** -->
+  <!-- **************************************************************************** -->
+  <!-- Targets -->
+  <!-- **************************************************************************** -->
+  <!-- **************************************************************************** -->
+
+  <Target Name="SkippingSonarQubeAnalysis" BeforeTargets="Build"
+          Condition=" $(SonarQubeTempPath) == '' ">
+    <Message Importance="high" Text="Sonar: ($(MSBuildProjectFile)) Skipping dumping compile outputs because SonarQubeTempPath has not been specified" />
+  </Target>
+
+  <Target Name="FailIfLowerThanMSBuild14"
+          Condition=" $(SonarQubeTempPath) != '' AND $(MSBuildToolsVersion) != '14.0' AND $(MSBuildToolsVersion) != '15.0' AND $(MSBuildToolsVersion) != 'Current'"
+          BeforeTargets="Build">
+    <Message Importance="high" Text="Sonar: ($(MSBuildProjectFile)) Current MSBuildToolsVersion: $(MSBuildToolsVersion)" />
+    <Message Importance="high" Text="Sonar: ($(MSBuildProjectFile)) Current MSBuildAssemblyVersion: $(MSBuildAssemblyVersion)" />
+    <Error Text="SonarQube analysis is only supported with MSBuild 14 or later." />
+  </Target>
+
+  <Target Name="SonarResolveReferencesMsBuild14"
+          AfterTargets="ResolveAssemblyReferences"
+          Condition=" $(SonarQubeTempPath) != '' AND $(MSBuildToolsVersion) == '14.0'">
+    <ItemGroup>
+      <SonarResolvedReferences Include="@(%(ReferencePath.FusionName))" />
+    </ItemGroup>
+  </Target>
+
+  <Target Name="SonarResolveReferences"
+          AfterTargets="FindReferenceAssembliesForReferences"
+          Condition=" $(SonarQubeTempPath) != '' AND $(MSBuildToolsVersion) != '14.0'">
+    <ItemGroup>
+      <SonarResolvedReferences Include="@(%(ReferencePathWithRefAssemblies.FusionName))" />
+    </ItemGroup>
+  </Target>
+
+  <!-- **************************************************************************** -->
+  <!-- Categorize as a product or test project -->
+  <!-- **************************************************************************** -->
+  <!-- This target is a utility target: it won't be executed unless a target that depends on it is executed. -->
+  <Target Name="SonarCategoriseProject"
+          DependsOnTargets="SonarResolveReferencesMsBuild14;SonarResolveReferences"
+          Condition=" $(SonarQubeTempPath) != '' ">
+
+    <Message Text="Sonar: ($(MSBuildProjectFile)) Categorizing project as test or product code..." />
+    <Message Condition="$(SonarQubeTestProject) != ''" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) SonarQubeTestProject has been set explicitly to $(SonarQubeTestProject)." />
+
+    <!-- Fakes detection -->
+    <PropertyGroup>
+      <IsFakesProject Condition="$(AssemblyName.EndsWith('.fakes', System.StringComparison.OrdinalIgnoreCase))">true</IsFakesProject>
+    </PropertyGroup>
+    <!-- Before deciding to exclude or tag as test such a project, make sure it is not a legitimate project that happens to be called something.fakes
+         In this case, we require from the user to explicitely state whether the project is to be analyzed/considered a test project -->
+    <PropertyGroup Condition="$(IsFakesProject) == 'true' and $(SonarQubeExclude) == ''">
+      <SonarQubeExclude>true</SonarQubeExclude>
+    </PropertyGroup>
+    <PropertyGroup Condition="$(IsFakesProject) == 'true' and $(SonarQubeTestProject) == ''">
+      <SonarQubeTestProject>true</SonarQubeTestProject>
+    </PropertyGroup>
+    <Message Condition="$(IsFakesProject) == 'true' and $(SonarQubeExclude) == 'true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project is a temporary project generated by Microsoft Fakes and will be ignored." />
+
+    <!-- Temporary project detection -->
+    <!-- Some kinds of project have logic to trigger additional special builds based on the same project file
+         e.g. WPF projects build a temporary assembly before the main compilation takes place.
+         We only want to analyze the "normal" build of the project, so we should turn off analysis for the known cases. -->
+    <PropertyGroup>
+      <!-- Special case 1: WPF projects call the task Windows.GenerateTemporaryTargetAssembly in PresentationBuildTasks. -->
+      <IsTempProject Condition="$(MSBuildProjectFile.EndsWith('.tmp_proj', System.StringComparison.OrdinalIgnoreCase))">true</IsTempProject>
+      <IsTempProject Condition="$(MSBuildProjectFile.EndsWith('_wpftmp.csproj', System.StringComparison.OrdinalIgnoreCase))">true</IsTempProject>
+      <IsTempProject Condition="$(MSBuildProjectFile.EndsWith('_wpftmp.vbproj', System.StringComparison.OrdinalIgnoreCase))">true</IsTempProject>
+    </PropertyGroup>
+
+    <PropertyGroup Condition="$(IsTempProject) == 'true' AND $(SonarQubeExclude)==''" >
+      <SonarQubeExclude>true</SonarQubeExclude>
+    </PropertyGroup>
+    <Message Condition="$(IsTempProject) == 'true' AND $(SonarQubeExclude)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project is a temporary project and will be excluded." />
+
+    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
+      <!-- The MS Test project type guid -->
+      <SonarQubeMsTestProjectTypeGuid>3AC096D0-A1C2-E12C-1390-A8335801FDAB</SonarQubeMsTestProjectTypeGuid>
+      <tmpSonarHasMSTestProjectTypeGuid Condition=" $(ProjectTypeGuids.ToUpperInvariant().Contains('$(SonarQubeMsTestProjectTypeGuid)')) ">true</tmpSonarHasMSTestProjectTypeGuid>
+      <SonarQubeTestProject Condition=" $(tmpSonarHasMSTestProjectTypeGuid)=='true' ">true</SonarQubeTestProject>
+    </PropertyGroup>
+    <Message Condition="$(tmpSonarHasMSTestProjectTypeGuid)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project has the MSTest project type guid -> test project." />
+
+    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
+      <!-- The legacy Service tag added by the Test Explorer window -->
+      <tmpSQServiceList>@(Service)</tmpSQServiceList>
+      <tmpSonarHasServiceTag Condition="$(tmpSQServiceList.ToUpperInvariant().Contains('{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}')) ">true</tmpSonarHasServiceTag>
+      <SonarQubeTestProject Condition="$(tmpSonarHasServiceTag)=='true'">true</SonarQubeTestProject>
+    </PropertyGroup>
+    <Message Condition="$(tmpSonarHasServiceTag)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project has the legacy Test Explorer Service tag {82A7F48D-3B50-4B1E-B82E-3ADA8210C358} -> test project." />
+
+    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
+      <!-- The ProjectCapability for test projects -->
+      <tmpSQProjectCapabilities>@(ProjectCapability)</tmpSQProjectCapabilities>
+      <tmpSonarHasTestContainerCapability Condition="$(tmpSQProjectCapabilities.ToUpperInvariant().Contains('TESTCONTAINER')) ">true</tmpSonarHasTestContainerCapability>
+      <SonarQubeTestProject Condition="$(tmpSonarHasTestContainerCapability)=='true'">true</SonarQubeTestProject>
+    </PropertyGroup>
+    <Message Condition="$(tmpSonarHasTestContainerCapability)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project has the ProjectCapability 'TestContainer' -> test project." />
+
+    <IsTestByReference Condition=" $(SonarQubeTestProject) == '' "
+        References="@(SonarResolvedReferences)">
+      <Output TaskParameter="TestReference" PropertyName="tmpSonarTestReferenceResult" />
+    </IsTestByReference>
+    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
+      <SonarQubeTestProject Condition="$(tmpSonarTestReferenceResult)!=''">true</SonarQubeTestProject>
+    </PropertyGroup>
+    <Message Condition="$(tmpSonarTestReferenceResult)!=''" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project is evaluated as a test project based on the '$(tmpSonarTestReferenceResult)' reference." />
+
+    <!-- If we haven't already determined whether the project is a test project then check its path/name against the regular expression in the config file -->
+    <IsTestFileByName Condition=" $(SonarQubeTestProject) == '' "
+        AnalysisConfigDir="$(SonarQubeConfigPath)"
+        FullFilePath="$(MSBuildProjectFullPath)">
+      <Output TaskParameter="IsTest" PropertyName="tmpSonarIsTestFileByNameResult" />
+    </IsTestFileByName>
+
+    <PropertyGroup Condition=" $(SonarQubeTestProject) == '' ">
+      <SonarQubeTestProject>$(tmpSonarIsTestFileByNameResult)</SonarQubeTestProject>
+    </PropertyGroup>
+    <Message Condition="$(tmpSonarIsTestFileByNameResult)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) project is evaluated as a test project based on the project name." />
+
+    <Message Importance="normal" Condition="$(SonarQubeTestProject)=='false'" Text="Sonar: ($(MSBuildProjectFile)) categorized as MAIN project (production code)." />
+    <Message Importance="normal" Condition="$(SonarQubeTestProject)=='true'"  Text="Sonar: ($(MSBuildProjectFile)) categorized as TEST project (test code)." />
+  </Target>
+
+  <!-- **************************************************************************** -->
+  <!-- Calculate the set of files to be analyzed -->
+  <!-- **************************************************************************** -->
+  <!-- This target is a utility target: it won't be executed unless a target that
+       depends on it is executed.
+  -->
+  <Target Name="SonarWriteFilesToAnalyze"
+        Condition=" $(SonarQubeTempPath) != '' ">
+
+    <!-- Include all of contents of the specified item groups, but exclude
+         any that have the metadata 'SonarQubeExclude' set, or that are auto-generated -->
+    <ItemGroup Condition="('$(SQAnalysisFileItemTypes)' != '')">
+      <SonarQubeAnalysisFileItems Include="$(SQAnalysisFileItemTypes)" />
+      <SonarQubeAnalysisFiles Include="@(%(SonarQubeAnalysisFileItems.Identity))" />
+      <SonarQubeAnalysisFiles Remove="@(SonarQubeAnalysisFiles)" Condition=" %(SonarQubeAnalysisFiles.SonarQubeExclude) == 'true' OR %(SonarQubeAnalysisFiles.AutoGen) == 'true' OR %(SonarQubeAnalysisFiles.FullPath) == '$(TargetFrameworkMonikerAssemblyAttributesPath)'" />
+    </ItemGroup>
+
+    <!-- Exclude items under the intermediate output folder e.g. XAML files that are auto-generated on build -->
+    <PropertyGroup>
+      <!-- Calculate the full path to the base intermediate folder -->
+      <SQFullIntermediateOutputPath>$([System.IO.Path]::Combine($(MSBuildProjectDirectory),$(BaseIntermediateOutputPath)))</SQFullIntermediateOutputPath>
+    </PropertyGroup>
+    <ItemGroup>
+      <!-- Remove based on absolute path -->
+      <SQIntermediateFiles Include="$(SQFullIntermediateOutputPath)**\*.*" />
+      <!-- Remove based on relative path -->
+      <SQIntermediateFiles Include="$(BaseIntermediateOutputPath)**\*.*" />
+      <SonarQubeAnalysisFiles Remove="@(SQIntermediateFiles)" />
+    </ItemGroup>
+
+    <PropertyGroup>
+      <!-- Set a property indicating whether there are any files to analyze -->
+      <AnalysisFilesExist Condition=" @(SonarQubeAnalysisFiles) != '' ">true</AnalysisFilesExist>
+    </PropertyGroup>
+
+    <!-- Write the list of files  -->
+    <PropertyGroup>
+      <!-- Set the file name for the list file -->
+      <AnalysisFileList>$(ProjectSpecificConfDir)\FilesToAnalyze.txt</AnalysisFileList>
+    </PropertyGroup>
+
+    <Message Condition="$(AnalysisFilesExist)!='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) No files were found to analyse" />
+    <Message Condition="$(AnalysisFilesExist)=='true'" Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) Number of files to analyse: @(SonarQubeAnalysisFiles->Count()). The list of files to be analyzed is in $(AnalysisFileList)." />
+
+    <!-- Write out a list of files to analyze that will be passed to the sonar-scanner -->
+    <WriteLinesToFile Condition=" $(AnalysisFilesExist) == 'true' "
+            File="$(AnalysisFileList)"
+            Lines="%(SonarQubeAnalysisFiles.FullPath)"
+            Overwrite="false"
+            Encoding="utf-8" />
+  </Target>
+
+  <Target Name="SonarCreateProjectSpecificDirs" BeforeTargets="OverrideRoslynCodeAnalysisProperties;SonarWriteProjectData;SonarWriteFilesToAnalyze"  Condition=" $(SonarQubeTempPath) != '' ">
+    <!-- **************************************************************************** -->
+    <!-- Create the project-specific directories for conf and out -->
+
+    <!-- Create folder with unique name in the .sonarqube/out/ folder -->
+    <MakeUniqueDir Path="$(SonarQubeOutputPath)">
+      <Output TaskParameter="UniquePath" PropertyName="ProjectSpecificOutDir" />
+      <Output TaskParameter="UniqueName" PropertyName="UniqueName" />
+    </MakeUniqueDir>
+    <!-- Create .sonarqube/conf/ sub-folder with the same unique name -->
+    <PropertyGroup>
+      <ProjectSpecificConfDir>$(SonarQubeConfigPath)\$(UniqueName)</ProjectSpecificConfDir>
+    </PropertyGroup>
+    <MakeDir Directories="$(ProjectSpecificConfDir)" />
+  </Target>
+
+  <!-- SonarWriteProjectData has to be invoked after the Build target, so it can pick up the results for C++ projects.  -->
+  <Target Name="InvokeSonarWriteProjectData_NonRazorProject"
+          DependsOnTargets="SonarCategoriseProject;SonarWriteFilesToAnalyze;SonarCreateProjectSpecificDirs"
+          AfterTargets="Build"
+          Condition=" $(SonarQubeTempPath) != '' AND ('@(RazorCompile)'=='' OR ('@(RazorCompile)'!='' AND '$(UseRazorSourceGenerator)'=='true'))  ">
+    <CallTarget Targets="SonarWriteProjectData" />
+  </Target>
+
+  <Target Name="InvokeSonarWriteProjectData_RazorProject"
+          DependsOnTargets="SonarCategoriseProject;SonarWriteFilesToAnalyze;SonarCreateProjectSpecificDirs"
+          BeforeTargets="SonarPrepareRazorProjectCodeAnalysis"
+          AfterTargets="CoreCompile"
+          Condition=" $(SonarQubeTempPath) != '' AND '@(RazorCompile)'!='' AND ('$(UseRazorSourceGenerator)'=='' OR '$(UseRazorSourceGenerator)'=='false') ">
+    <CallTarget Targets="SonarWriteProjectData" />
+  </Target>
+
+  <Target Name="SonarWriteProjectData" >
+    <PropertyGroup>
+      <SonarErrorLogExists Condition=" $(SonarErrorLog) != '' AND  $([System.IO.File]::Exists($(SonarErrorLog))) == 'true' ">true</SonarErrorLogExists>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <SonarReportFilePath Condition= "$(SonarErrorLogExists) == 'true'" Include="$(SonarErrorLog)" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <SonarQubeSetting Include="sonar.$(SQLanguage).roslyn.reportFilePaths" Condition=" @(SonarReportFilePath) != '' ">
+        <!-- Join the paths with |  -->
+        <!-- This delimiter needs to be the same as PropertiesFileGenerator.RoslynReportPathsDelimiter -->
+        <Value>@(SonarReportFilePath->'%(identity)','|')</Value>
+      </SonarQubeSetting>
+      <SonarQubeSetting Include="sonar.$(SQLanguage).analyzer.projectOutPaths" Condition= "$(SonarErrorLogExists) == 'true'">
+        <Value>$(ProjectSpecificOutDir)</Value>
+      </SonarQubeSetting>
+    </ItemGroup>
+
+    <!-- Record the list of files as an analysis result -->
+    <ItemGroup Condition=" $(AnalysisFilesExist) == 'true' ">
+      <AnalysisResults Include="$(AnalysisFileList)">
+        <Id>FilesToAnalyze</Id>
+      </AnalysisResults>
+    </ItemGroup>
+
+    <CallTarget Targets="FixUpTestProjectOutputs" />
+
+    <WriteProjectInfoFile ProjectName="$(MSBuildProjectName)"
+       FullProjectPath="$(MSBuildProjectFullPath)"
+       ProjectLanguage="$(Language)"
+       ProjectGuid="$(ProjectGuid)"
+       SolutionConfigurationContents="$(CurrentSolutionConfigurationContents)"
+       IsTest="$(SonarQubeTestProject)"
+       IsExcluded="$(SonarQubeExclude)"
+       AnalysisResults="@(AnalysisResults)"
+       AnalysisSettings="@(SonarQubeSetting)"
+       OutputFolder="$(ProjectSpecificOutDir)"
+       CodePage="$(CodePage)"
+       Configuration="$(Configuration)"
+       Platform="$(Platform)"
+       TargetFramework="$(TargetFramework)" />
+
+    <Message Importance="high" Text="Sonar: ($(MSBuildProjectFile)) Project processed successfully" />
+  </Target>
+
+  <!--
+    Set the Razor specific error log properties.
+    Move the results of the core compilation to a temporary folder to prevent RazorCoreCompilation from overriding its content.
+    The contents will be moved back in SonarFinishRazorProjectCodeAnalysis target.
+  -->
+  <Target Name="SonarPrepareRazorProjectCodeAnalysis" BeforeTargets="RazorCoreCompile" AfterTargets="CoreCompile" Condition="'@(RazorCompile)'!='' AND ('$(UseRazorSourceGenerator)'=='' OR '$(UseRazorSourceGenerator)'=='false')" >
+    <PropertyGroup Condition=" $(SonarErrorLog) != '' ">
+      <!-- https://github.com/SonarSource/sonar-scanner-msbuild/issues/1015 Respect user-provided value. When set, users should provide unique path for each build (project and target framework). -->
+      <RazorSonarErrorLogName Condition=" $(RazorCompilationErrorLog) == '' ">Issues$(RazorTargetNameSuffix).json</RazorSonarErrorLogName>
+      <RazorCompilationErrorLog Condition=" $(RazorSonarErrorLogName) != '' ">$(ProjectSpecificOutDir)\$(RazorSonarErrorLogName)</RazorCompilationErrorLog>
+      <ErrorLog>$(RazorCompilationErrorLog)</ErrorLog>
+      <!-- Keep the path so that we could set SonarQubeSetting with sonar.language.roslyn.reportFilePaths -->
+      <RazorSonarErrorLog>$(RazorCompilationErrorLog)</RazorSonarErrorLog>
+    </PropertyGroup>
+    <PropertyGroup>
+      <SonarTemporaryProjectSpecificOutDir>$(ProjectSpecificOutDir).tmp</SonarTemporaryProjectSpecificOutDir>
+    </PropertyGroup>
+    <ItemGroup>
+      <CoreCompileOutFiles Include="$(ProjectSpecificOutDir)\**\*.*"/>
+    </ItemGroup>
+    <Move
+      SourceFiles="@(CoreCompileOutFiles)"
+      DestinationFolder="$(SonarTemporaryProjectSpecificOutDir)\%(RecursiveDir)" />
+    <Message Importance="high" Text="Sonar: Preparing for Razor compilation, moved files (@(CoreCompileOutFiles)) to $(SonarTemporaryProjectSpecificOutDir)." />
+  </Target>
+
+  <!-- In case of Razor compilation the output files generated during the core compilation step are already moved into a temporary folder.
+       This target renames output directories to their final state and creates the ProjectInfo.xml for them.
+  -->
+  <Target Name="SonarFinishRazorProjectCodeAnalysis" AfterTargets="RazorCoreCompile;InvokeSonarWriteProjectData_RazorProject" Condition=" $(SonarTemporaryProjectSpecificOutDir) != '' AND '@(RazorCompile)'!='' AND ('$(UseRazorSourceGenerator)'=='' OR '$(UseRazorSourceGenerator)'=='false') ">
+    <PropertyGroup>
+      <RazorSonarProjectSpecificOutDir>$(ProjectSpecificOutDir).Razor</RazorSonarProjectSpecificOutDir>
+      <RazorSonarProjectInfo>$(RazorSonarProjectSpecificOutDir)\ProjectInfo.xml</RazorSonarProjectInfo>
+    </PropertyGroup>
+    <ItemGroup>
+      <RazorCompilationOutFiles Include="$(ProjectSpecificOutDir)\**\*.*"/>
+      <SonarTempFiles Include="$(SonarTemporaryProjectSpecificOutDir)\**\*.*"/>
+    </ItemGroup>
+
+    <!-- Move main and Razor results to their final location. -->
+    <Move
+      SourceFiles="@(RazorCompilationOutFiles)"
+      DestinationFolder="$(RazorSonarProjectSpecificOutDir)\%(RecursiveDir)" />
+    <Message Importance="high" Text="Sonar: After Razor compilation, moved files (@(RazorCompilationOutFiles)) to $(RazorSonarProjectSpecificOutDir)." />
+
+    <Move
+      SourceFiles="@(SonarTempFiles)"
+      DestinationFolder="$(ProjectSpecificOutDir)\%(RecursiveDir)" />
+    <Message Importance="high" Text="Sonar: After Razor compilation, moved files (@(SonarTempFiles)) to $(ProjectSpecificOutDir) and will remove the temporary folder." />
+    <RemoveDir Directories="$(SonarTemporaryProjectSpecificOutDir)" />
+
+    <PropertyGroup>
+      <!-- This overwrites the previously set 'RazorSonarErrorLog' in 'SonarPrepareRazorProjectCodeAnalysis'
+           if 'RazorSonarErrorLogName' is set, which means 'RazorCompilationErrorLog' was null.
+           The condition is a bit difficult to follow, it would be easier to change it or also add "$(RazorSonarErrorLog) != ''" -->
+      <RazorSonarErrorLog Condition=" $(RazorSonarErrorLogName) != '' ">$(RazorSonarProjectSpecificOutDir)\$(RazorSonarErrorLogName)</RazorSonarErrorLog>
+      <RazorSonarErrorLogExists Condition=" $(RazorSonarErrorLog) != '' AND  $([System.IO.File]::Exists($(RazorSonarErrorLog))) == 'true' ">true</RazorSonarErrorLogExists>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <RazorSonarReportFilePath Condition= "$(RazorSonarErrorLogExists) == 'true'" Include="$(RazorSonarErrorLog)" />
+      <RazorSonarQubeSetting Include="sonar.$(SQLanguage).roslyn.reportFilePaths" Condition=" @(RazorSonarReportFilePath) != '' ">
+        <!-- Join the paths with |  -->
+        <!-- This delimiter needs to be the same as PropertiesFileGenerator.RoslynReportPathsDelimiter -->
+        <Value>@(RazorSonarReportFilePath->'%(identity)','|')</Value>
+      </RazorSonarQubeSetting>
+      <RazorSonarQubeSetting Include="sonar.$(SQLanguage).analyzer.projectOutPaths" Condition= "$(RazorSonarErrorLogExists) == 'true'">
+        <Value>$(RazorSonarProjectSpecificOutDir)</Value>
+      </RazorSonarQubeSetting>
+    </ItemGroup>
+
+    <!-- Create the ProjectInfo.xml for the Razor part. -->
+    <WriteProjectInfoFile ProjectName="$(MSBuildProjectName)"
+                          FullProjectPath="$(MSBuildProjectFullPath)"
+                          ProjectLanguage="$(Language)"
+                          ProjectGuid="$(ProjectGuid)"
+                          SolutionConfigurationContents="$(CurrentSolutionConfigurationContents)"
+                          IsTest="$(SonarQubeTestProject)"
+                          IsExcluded="$(SonarQubeExclude)"
+                          AnalysisResults="@(AnalysisResults)"
+                          AnalysisSettings="@(RazorSonarQubeSetting)"
+                          OutputFolder="$(RazorSonarProjectSpecificOutDir)"
+                          CodePage="$(CodePage)"
+                          Configuration="$(Configuration)"
+                          Platform="$(Platform)"
+                          TargetFramework="$(TargetFramework)" />
+  </Target>
+
+  <Target Name="FixUpTestProjectOutputs" Condition="$(SonarQubeTestProject)=='true'" >
+    <Message Importance="low" Text="Sonar: ($(MSBuildProjectFile)) Fixing up test project outputs..." />
+
+    <ItemGroup>
+      <!-- Select specific metrics files that should not be uploaded for test files.
+           Assumption: these files will be in a sub-folder under the project-specific output folder. -->
+      <SQTestMetricFiles Include="$(ProjectSpecificOutDir)\*\metrics.pb" />
+      <SQTestMetricFiles Include="$(ProjectSpecificOutDir)\*\token-cpd.pb" />
+    </ItemGroup>
+
+    <Message Importance="low" Text="Sonar: ($(MSBuildProjectFile)) Selected test metric file: @(SQTestMetricFiles)" />
+    <WriteZeroLengthFiles FullFilePaths="@(SQTestMetricFiles)" />
+  </Target>
+
+  <!-- **************************************************************************** -->
+  <!-- Code analysis -->
+  <!-- **************************************************************************** -->
+  <!--  Implementation notes:
+
+        We want to override any code analysis-related properties that are set in the
+        project file. To do this, we need to execute our targets at the correct
+        point in the build.
+
+        Note that both the FxCop and Roslyn targets use a property called "CodeAnalysisRuleSet".
+        The FxCop targets use this value directly. However, the Roslyn targets use it
+        as input to the "ResolveCodeAnalysisRuleSet" target, which sets the property
+        "ResolvedCodeAnalysisRuleset".
+
+        We override the property "ResolveCodeAnalysisRuleSet" with the path to our Roslyn ruleset.
+  -->
+
+  <PropertyGroup>
+    <SQLanguage Condition="$(Language) == 'C#'">cs</SQLanguage>
+    <SQLanguage Condition="$(Language) == 'VB'">vbnet</SQLanguage>
+  </PropertyGroup>
+
+  <!-- **************************************************************************** -->
+  <!-- Roslyn analysis section -->
+  <!-- **************************************************************************** -->
+  <!-- Override VS2019 properties to make sure analysis runs in the scanner build.
+       We need to run before BeforeCompile that executes _ComputeSkipAnalyzers target.
+       We don't need to override this for excluded projects. -->
+  <Target Name="SonarOverrideRunAnalyzers"
+        Condition=" $(SonarQubeTempPath) != '' AND $(SonarQubeExclude) != 'true' "
+        BeforeTargets="BeforeCompile">
+
+    <PropertyGroup>
+      <RunAnalyzers>true</RunAnalyzers>
+      <RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
+    </PropertyGroup>
+  </Target>
+
+  <!-- Set the properties required to run Roslyn analysis as part of the build.
+       Analysis is controlled by the following properties:
+         ResolvedCodeAnalysisRuleSet - the full path to the ruleset to use
+         ErrorLog and RazorCompilationErrorLog - the file path for the error reporting file
+
+       We want to run after the core "ResolveCodeAnalysisRuleSet" target which assigns a value to "ResolvedCodeAnalysisRuleSet".
+
+       Conditions:
+       * project is excluded -> turn off Roslyn analysis
+       * project is a test project and parameter sonar.dotnet.excludeTestProjects=true -> run only metrics rules
+       * otherwise, use the analyzer settings loaded from the config file (removing any existing analyzers)
+   -->
+  <Target Name="OverrideRoslynCodeAnalysisProperties"
+        Condition=" $(SonarQubeTempPath) != '' "
+        DependsOnTargets="SonarCategoriseProject;SonarWriteFilesToAnalyze"
+        AfterTargets="ResolveCodeAnalysisRuleSet"
+        BeforeTargets="CoreCompile">
+
+    <PropertyGroup>
+      <!-- Make sure no warnings are treated as errors -->
+      <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+      <WarningsAsErrors></WarningsAsErrors>
+
+      <!-- The Roslyn analyzers output messages with different warning levels. This is tied to the diagnostic severity and currently
+      is translated as follows - error: 0, warning: 1, info: 4. To avoid issues being missed override the warning level by setting it to max tolerance.-->
+      <WarningLevel>4</WarningLevel>
+    </PropertyGroup>
+
+    <CallTarget Targets="SetRoslynCodeAnalysisProperties" Condition="$(SonarQubeExclude) != 'true'" />
+  </Target>
+
+  <Target Name="SetRoslynCodeAnalysisProperties">
+
+    <!-- Fetch the relevant settings from the config file -->
+    <GetAnalyzerSettings AnalysisConfigDir="$(SonarQubeConfigPath)"
+                         Language="$(SQLanguage)"
+                         CurrentProjectDirectoryPath="$(MSBuildProjectDirectory)"
+                         OriginalAnalyzers="@(Analyzer)"
+                         OriginalAdditionalFiles="@(AdditionalFiles)"
+                         OriginalRulesetFilePath="$(ResolvedCodeAnalysisRuleset)"
+                         ProjectSpecificConfigDirectory="$(ProjectSpecificConfDir)"
+                         IsTestProject="$(SonarQubeTestProject)">
+      <Output TaskParameter="RuleSetFilePath" PropertyName="SQRuleSetFilePath" />
+      <Output TaskParameter="AnalyzerFilePaths" ItemName="SQAnalyzerFilePaths" />
+      <Output TaskParameter="AdditionalFilePaths" ItemName="SQAdditionalFiles" />
+    </GetAnalyzerSettings>
+
+    <PropertyGroup>
+      <!-- https://github.com/SonarSource/sonar-scanner-msbuild/issues/1015 Respect user-provided value. When set, users should provide unique path for each build (project and target framework). -->
+      <!-- https://jira.sonarsource.com/browse/SONARMSBRU-211 - the full path should be unique per project and target framework. -->
+      <ErrorLog Condition=" $(ErrorLog) == '' ">$(ProjectSpecificOutDir)\Issues.json</ErrorLog>
+      <!-- Keep the path so that we could set SonarQubeSetting with sonar.language.roslyn.reportFilePaths -->
+      <SonarErrorLog>$(ErrorLog)</SonarErrorLog>
+    </PropertyGroup>
+
+    <PropertyGroup>
+      <ResolvedCodeAnalysisRuleSet>$(SQRuleSetFilePath)</ResolvedCodeAnalysisRuleSet>
+      <SonarProjectOutFolderFilePath>$(ProjectSpecificConfDir)\ProjectOutFolderPath.txt</SonarProjectOutFolderFilePath>
+    </PropertyGroup>
+
+    <!--SonarProjectOutFolderFilePath is generated only for backward compatibility with CSharp and VBNet analyzers before 8.20 -->
+    <WriteLinesToFile File="$(SonarProjectOutFolderFilePath)" Lines="$(ProjectSpecificOutDir)" Overwrite="true" />
+
+    <WriteProjectConfigFile ConfigDir="$(ProjectSpecificConfDir)"
+                            AnalysisConfigPath="$(SonarQubeConfigPath)\SonarQubeAnalysisConfig.xml"
+                            ProjectPath="$(MSBuildProjectFullPath)"
+                            FilesToAnalyzePath ="$(AnalysisFileList)"
+                            OutPath="$(ProjectSpecificOutDir)"
+                            IsTest="$(SonarQubeTestProject)"
+                            TargetFramework="$(TargetFramework)">
+      <Output TaskParameter="ProjectConfigFilePath" PropertyName="SonarProjectConfigFilePath" />
+    </WriteProjectConfigFile>
+
+    <ItemGroup>
+      <!-- Clear the original set of analyzers and additional files -->
+      <Analyzer Remove="@(Analyzer)" />
+      <AdditionalFiles Remove="@(AdditionalFiles)" />
+
+      <!-- Use the set of analyzers and additional files calculated by the GetAnalyzerSettings task -->
+      <Analyzer Include="@(SQAnalyzerFilePaths)" />
+      <AdditionalFiles Include="@(SQAdditionalFiles)" />
+      <AdditionalFiles Include="$(SonarProjectConfigFilePath)" />
+      <AdditionalFiles Include="$(SonarProjectOutFolderFilePath)" />
+    </ItemGroup>
+
+    <Message Importance="normal" Text="Sonar: ($(MSBuildProjectFile)) Analysis configured successfully with $(SonarProjectConfigFilePath)." />
+  </Target>
+  <!-- **************************************************************************** -->
+  <!-- End of Roslyn analysis section-->
+  <!-- **************************************************************************** -->
+
+</Project>